hadars 0.1.18 → 0.1.19

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.
@@ -1,11 +1,12 @@
1
1
  import {
2
2
  FRAGMENT_TYPE,
3
3
  Fragment,
4
+ REACT19_ELEMENT,
4
5
  SLIM_ELEMENT,
5
6
  SUSPENSE_TYPE,
6
7
  createElement,
7
8
  jsx
8
- } from "../chunk-TGSIYGY2.js";
9
+ } from "../chunk-OS3V4CPN.js";
9
10
 
10
11
  // src/slim-react/renderContext.ts
11
12
  var GLOBAL_KEY = "__slimReactRenderState";
@@ -187,7 +188,7 @@ var VOID_ELEMENTS = /* @__PURE__ */ new Set([
187
188
  "wbr"
188
189
  ]);
189
190
  function escapeHtml(str) {
190
- return str.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
191
+ return str.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/'/g, "&#x27;");
191
192
  }
192
193
  function escapeAttr(str) {
193
194
  return str.replace(/&/g, "&amp;").replace(/"/g, "&quot;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
@@ -332,7 +333,7 @@ var SVG_ATTR_MAP = {
332
333
  function renderAttributes(props, isSvg) {
333
334
  let attrs = "";
334
335
  for (const [key, value] of Object.entries(props)) {
335
- if (key === "children" || key === "key" || key === "ref" || key === "dangerouslySetInnerHTML")
336
+ if (key === "children" || key === "key" || key === "ref" || key === "dangerouslySetInnerHTML" || key === "suppressHydrationWarning" || key === "suppressContentEditableWarning")
336
337
  continue;
337
338
  if (key.startsWith("on") && key.length > 2 && key[2] === key[2].toUpperCase())
338
339
  continue;
@@ -340,12 +341,16 @@ function renderAttributes(props, isSvg) {
340
341
  if (isSvg && key in SVG_ATTR_MAP) {
341
342
  attrName = SVG_ATTR_MAP[key];
342
343
  } else {
343
- attrName = key === "className" ? "class" : key === "htmlFor" ? "for" : key === "tabIndex" ? "tabindex" : key;
344
+ attrName = key === "className" ? "class" : key === "htmlFor" ? "for" : key === "tabIndex" ? "tabindex" : key === "defaultValue" ? "value" : key === "defaultChecked" ? "checked" : key;
344
345
  }
345
- if (value === false || value == null)
346
+ if (value === false || value == null) {
347
+ if (value === false && (attrName.startsWith("aria-") || attrName.startsWith("data-"))) {
348
+ attrs += ` ${attrName}="false"`;
349
+ }
346
350
  continue;
351
+ }
347
352
  if (value === true) {
348
- attrs += ` ${attrName}`;
353
+ attrs += ` ${attrName}=""`;
349
354
  continue;
350
355
  }
351
356
  if (key === "style" && typeof value === "object") {
@@ -358,23 +363,30 @@ function renderAttributes(props, isSvg) {
358
363
  }
359
364
  var BufferWriter = class {
360
365
  chunks = [];
366
+ lastWasText = false;
361
367
  write(chunk) {
362
368
  this.chunks.push(chunk);
369
+ this.lastWasText = false;
370
+ }
371
+ text(s2) {
372
+ this.chunks.push(s2);
373
+ this.lastWasText = true;
363
374
  }
364
375
  flush(target) {
365
376
  for (const c of this.chunks)
366
377
  target.write(c);
378
+ target.lastWasText = this.lastWasText;
367
379
  }
368
380
  };
369
381
  function renderNode(node, writer, isSvg = false) {
370
382
  if (node == null || typeof node === "boolean")
371
383
  return;
372
384
  if (typeof node === "string") {
373
- writer.write(escapeHtml(node));
385
+ writer.text(escapeHtml(node));
374
386
  return;
375
387
  }
376
388
  if (typeof node === "number") {
377
- writer.write(String(node));
389
+ writer.text(String(node));
378
390
  return;
379
391
  }
380
392
  if (Array.isArray(node)) {
@@ -387,7 +399,10 @@ function renderNode(node, writer, isSvg = false) {
387
399
  isSvg
388
400
  );
389
401
  }
390
- if (typeof node === "object" && node !== null && "$$typeof" in node && node.$$typeof === SLIM_ELEMENT) {
402
+ if (typeof node === "object" && node !== null && "$$typeof" in node) {
403
+ const elType = node["$$typeof"];
404
+ if (elType !== SLIM_ELEMENT && elType !== REACT19_ELEMENT)
405
+ return;
391
406
  const element = node;
392
407
  const { type, props } = element;
393
408
  if (type === FRAGMENT_TYPE) {
@@ -399,16 +414,79 @@ function renderNode(node, writer, isSvg = false) {
399
414
  if (typeof type === "function") {
400
415
  return renderComponent(type, props, writer, isSvg);
401
416
  }
417
+ if (typeof type === "object" && type !== null) {
418
+ return renderComponent(type, props, writer, isSvg);
419
+ }
402
420
  if (typeof type === "string") {
403
421
  return renderHostElement(type, props, writer, isSvg);
404
422
  }
405
423
  }
406
424
  }
425
+ function markSelectedOptionsMulti(children, selectedValues) {
426
+ if (children == null || typeof children === "boolean")
427
+ return children;
428
+ if (typeof children === "string" || typeof children === "number")
429
+ return children;
430
+ if (Array.isArray(children)) {
431
+ return children.map((c) => markSelectedOptionsMulti(c, selectedValues));
432
+ }
433
+ if (typeof children === "object" && "$$typeof" in children) {
434
+ const elType = children["$$typeof"];
435
+ if (elType !== SLIM_ELEMENT && elType !== REACT19_ELEMENT)
436
+ return children;
437
+ const el = children;
438
+ if (el.type === "option") {
439
+ const optValue = el.props.value !== void 0 ? el.props.value : el.props.children;
440
+ const isSelected = selectedValues.has(String(optValue));
441
+ return { ...el, props: { ...el.props, selected: isSelected || void 0 } };
442
+ }
443
+ if (el.type === "optgroup" || el.type === FRAGMENT_TYPE) {
444
+ const newChildren = markSelectedOptionsMulti(el.props.children, selectedValues);
445
+ return { ...el, props: { ...el.props, children: newChildren } };
446
+ }
447
+ }
448
+ return children;
449
+ }
407
450
  function renderHostElement(tag, props, writer, isSvg) {
408
451
  const enteringSvg = tag === "svg";
409
452
  const childSvg = isSvg || enteringSvg;
410
- const effectiveProps = enteringSvg && !props.xmlns ? { xmlns: "http://www.w3.org/2000/svg", ...props } : props;
411
- writer.write(`<${tag}${renderAttributes(effectiveProps, childSvg)}>`);
453
+ if (tag === "textarea") {
454
+ const textContent = props.value ?? props.defaultValue ?? props.children ?? "";
455
+ const filteredProps = {};
456
+ for (const k of Object.keys(props)) {
457
+ if (k !== "value" && k !== "defaultValue" && k !== "children")
458
+ filteredProps[k] = props[k];
459
+ }
460
+ writer.write(`<textarea${renderAttributes(filteredProps, false)}>`);
461
+ writer.text(escapeHtml(String(textContent)));
462
+ writer.write("</textarea>");
463
+ return;
464
+ }
465
+ if (tag === "select") {
466
+ const selectedValue = props.value ?? props.defaultValue;
467
+ const filteredProps = {};
468
+ for (const k of Object.keys(props)) {
469
+ if (k !== "value" && k !== "defaultValue")
470
+ filteredProps[k] = props[k];
471
+ }
472
+ writer.write(`<select${renderAttributes(filteredProps, false)}>`);
473
+ const selectedSet = selectedValue == null ? null : Array.isArray(selectedValue) ? new Set(selectedValue.map(String)) : /* @__PURE__ */ new Set([String(selectedValue)]);
474
+ const patchedChildren = selectedSet != null ? markSelectedOptionsMulti(props.children, selectedSet) : props.children;
475
+ const inner2 = renderChildren(patchedChildren, writer, false);
476
+ if (inner2 && typeof inner2.then === "function") {
477
+ return inner2.then(() => {
478
+ writer.write("</select>");
479
+ });
480
+ }
481
+ writer.write("</select>");
482
+ return;
483
+ }
484
+ writer.write(`<${tag}${renderAttributes(props, childSvg)}`);
485
+ if (VOID_ELEMENTS.has(tag)) {
486
+ writer.write("/>");
487
+ return;
488
+ }
489
+ writer.write(">");
412
490
  const childContext = tag === "foreignObject" ? false : childSvg;
413
491
  let inner = void 0;
414
492
  if (props.dangerouslySetInnerHTML) {
@@ -418,17 +496,17 @@ function renderHostElement(tag, props, writer, isSvg) {
418
496
  }
419
497
  if (inner && typeof inner.then === "function") {
420
498
  return inner.then(() => {
421
- if (!VOID_ELEMENTS.has(tag))
422
- writer.write(`</${tag}>`);
499
+ writer.write(`</${tag}>`);
423
500
  });
424
501
  }
425
- if (!VOID_ELEMENTS.has(tag))
426
- writer.write(`</${tag}>`);
502
+ writer.write(`</${tag}>`);
427
503
  }
428
504
  var REACT_MEMO = Symbol.for("react.memo");
429
505
  var REACT_FORWARD_REF = Symbol.for("react.forward_ref");
430
506
  var REACT_PROVIDER = Symbol.for("react.provider");
431
507
  var REACT_CONTEXT = Symbol.for("react.context");
508
+ var REACT_CONSUMER = Symbol.for("react.consumer");
509
+ var REACT_LAZY = Symbol.for("react.lazy");
432
510
  function renderComponent(type, props, writer, isSvg) {
433
511
  const typeOf = type?.$$typeof;
434
512
  if (typeOf === REACT_MEMO) {
@@ -441,6 +519,24 @@ function renderComponent(type, props, writer, isSvg) {
441
519
  if (typeOf === REACT_FORWARD_REF) {
442
520
  return renderComponent(type.render, props, writer, isSvg);
443
521
  }
522
+ if (typeOf === REACT_LAZY) {
523
+ const resolved = type._init(type._payload);
524
+ const LazyComp = resolved?.default ?? resolved;
525
+ return renderComponent(LazyComp, props, writer, isSvg);
526
+ }
527
+ if (typeOf === REACT_CONSUMER) {
528
+ const ctx2 = type._context;
529
+ const value = ctx2?._currentValue;
530
+ const result2 = typeof props.children === "function" ? props.children(value) : null;
531
+ const savedScope2 = pushComponentScope();
532
+ const finish2 = () => popComponentScope(savedScope2);
533
+ const r2 = renderNode(result2, writer, isSvg);
534
+ if (r2 && typeof r2.then === "function") {
535
+ return r2.then(finish2);
536
+ }
537
+ finish2();
538
+ return;
539
+ }
444
540
  const isProvider = "_context" in type || typeOf === REACT_PROVIDER || typeOf === REACT_CONTEXT && "value" in props;
445
541
  let prevCtxValue;
446
542
  let ctx;
@@ -450,10 +546,27 @@ function renderComponent(type, props, writer, isSvg) {
450
546
  ctx._currentValue = props.value;
451
547
  }
452
548
  const savedScope = pushComponentScope();
549
+ if (isProvider && typeof type !== "function") {
550
+ const finish2 = () => {
551
+ popComponentScope(savedScope);
552
+ ctx._currentValue = prevCtxValue;
553
+ };
554
+ const r2 = renderChildren(props.children, writer, isSvg);
555
+ if (r2 && typeof r2.then === "function") {
556
+ return r2.then(finish2);
557
+ }
558
+ finish2();
559
+ return;
560
+ }
453
561
  let result;
454
562
  try {
455
563
  if (type.prototype && typeof type.prototype.render === "function") {
456
564
  const instance = new type(props);
565
+ if (typeof type.getDerivedStateFromProps === "function") {
566
+ const derived = type.getDerivedStateFromProps(props, instance.state ?? {});
567
+ if (derived != null)
568
+ instance.state = { ...instance.state ?? {}, ...derived };
569
+ }
457
570
  result = instance.render();
458
571
  } else {
459
572
  result = type(props);
@@ -490,7 +603,7 @@ function isTextLike(node) {
490
603
  function renderChildArray(children, writer, isSvg) {
491
604
  const totalChildren = children.length;
492
605
  for (let i = 0; i < totalChildren; i++) {
493
- if (i > 0 && isTextLike(children[i]) && isTextLike(children[i - 1])) {
606
+ if (isTextLike(children[i]) && writer.lastWasText) {
494
607
  writer.write("<!-- -->");
495
608
  }
496
609
  const savedTree = pushTreeContext(totalChildren, i);
@@ -507,7 +620,7 @@ function renderChildArray(children, writer, isSvg) {
507
620
  function renderChildArrayFrom(children, startIndex, writer, isSvg) {
508
621
  const totalChildren = children.length;
509
622
  for (let i = startIndex; i < totalChildren; i++) {
510
- if (i > 0 && isTextLike(children[i]) && isTextLike(children[i - 1])) {
623
+ if (isTextLike(children[i]) && writer.lastWasText) {
511
624
  writer.write("<!-- -->");
512
625
  }
513
626
  const savedTree = pushTreeContext(totalChildren, i);
@@ -570,8 +683,14 @@ function renderToStream(element) {
570
683
  async start(controller) {
571
684
  resetRenderState();
572
685
  const writer = {
686
+ lastWasText: false,
573
687
  write(chunk) {
574
688
  controller.enqueue(encoder.encode(chunk));
689
+ this.lastWasText = false;
690
+ },
691
+ text(s2) {
692
+ controller.enqueue(encoder.encode(s2));
693
+ this.lastWasText = true;
575
694
  }
576
695
  };
577
696
  try {
@@ -589,9 +708,17 @@ async function renderToString(element) {
589
708
  for (let attempt = 0; attempt < MAX_SUSPENSE_RETRIES; attempt++) {
590
709
  resetRenderState();
591
710
  const chunks = [];
592
- const writer = { write(c) {
593
- chunks.push(c);
594
- } };
711
+ const writer = {
712
+ lastWasText: false,
713
+ write(c) {
714
+ chunks.push(c);
715
+ this.lastWasText = false;
716
+ },
717
+ text(s2) {
718
+ chunks.push(s2);
719
+ this.lastWasText = true;
720
+ }
721
+ };
595
722
  try {
596
723
  const r = renderNode(element, writer);
597
724
  if (r && typeof r.then === "function")
@@ -29,6 +29,7 @@ module.exports = __toCommonJS(jsx_runtime_exports);
29
29
 
30
30
  // src/slim-react/types.ts
31
31
  var SLIM_ELEMENT = Symbol.for("react.element");
32
+ var REACT19_ELEMENT = Symbol.for("react.transitional.element");
32
33
  var FRAGMENT_TYPE = Symbol.for("react.fragment");
33
34
  var SUSPENSE_TYPE = Symbol.for("react.suspense");
34
35
 
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  Fragment,
3
3
  jsx
4
- } from "../chunk-TGSIYGY2.js";
4
+ } from "../chunk-OS3V4CPN.js";
5
5
  export {
6
6
  Fragment,
7
7
  jsx,
@@ -43,6 +43,7 @@ function processSegmentCache(html) {
43
43
 
44
44
  // src/slim-react/types.ts
45
45
  var SLIM_ELEMENT = Symbol.for("react.element");
46
+ var REACT19_ELEMENT = Symbol.for("react.transitional.element");
46
47
  var FRAGMENT_TYPE = Symbol.for("react.fragment");
47
48
  var SUSPENSE_TYPE = Symbol.for("react.suspense");
48
49
 
@@ -140,7 +141,7 @@ var VOID_ELEMENTS = /* @__PURE__ */ new Set([
140
141
  "wbr"
141
142
  ]);
142
143
  function escapeHtml(str) {
143
- return str.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
144
+ return str.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/'/g, "&#x27;");
144
145
  }
145
146
  function escapeAttr(str) {
146
147
  return str.replace(/&/g, "&amp;").replace(/"/g, "&quot;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
@@ -285,7 +286,7 @@ var SVG_ATTR_MAP = {
285
286
  function renderAttributes(props, isSvg) {
286
287
  let attrs = "";
287
288
  for (const [key, value] of Object.entries(props)) {
288
- if (key === "children" || key === "key" || key === "ref" || key === "dangerouslySetInnerHTML")
289
+ if (key === "children" || key === "key" || key === "ref" || key === "dangerouslySetInnerHTML" || key === "suppressHydrationWarning" || key === "suppressContentEditableWarning")
289
290
  continue;
290
291
  if (key.startsWith("on") && key.length > 2 && key[2] === key[2].toUpperCase())
291
292
  continue;
@@ -293,12 +294,16 @@ function renderAttributes(props, isSvg) {
293
294
  if (isSvg && key in SVG_ATTR_MAP) {
294
295
  attrName = SVG_ATTR_MAP[key];
295
296
  } else {
296
- attrName = key === "className" ? "class" : key === "htmlFor" ? "for" : key === "tabIndex" ? "tabindex" : key;
297
+ attrName = key === "className" ? "class" : key === "htmlFor" ? "for" : key === "tabIndex" ? "tabindex" : key === "defaultValue" ? "value" : key === "defaultChecked" ? "checked" : key;
297
298
  }
298
- if (value === false || value == null)
299
+ if (value === false || value == null) {
300
+ if (value === false && (attrName.startsWith("aria-") || attrName.startsWith("data-"))) {
301
+ attrs += ` ${attrName}="false"`;
302
+ }
299
303
  continue;
304
+ }
300
305
  if (value === true) {
301
- attrs += ` ${attrName}`;
306
+ attrs += ` ${attrName}=""`;
302
307
  continue;
303
308
  }
304
309
  if (key === "style" && typeof value === "object") {
@@ -311,23 +316,30 @@ function renderAttributes(props, isSvg) {
311
316
  }
312
317
  var BufferWriter = class {
313
318
  chunks = [];
319
+ lastWasText = false;
314
320
  write(chunk) {
315
321
  this.chunks.push(chunk);
322
+ this.lastWasText = false;
323
+ }
324
+ text(s2) {
325
+ this.chunks.push(s2);
326
+ this.lastWasText = true;
316
327
  }
317
328
  flush(target) {
318
329
  for (const c of this.chunks)
319
330
  target.write(c);
331
+ target.lastWasText = this.lastWasText;
320
332
  }
321
333
  };
322
334
  function renderNode(node, writer, isSvg = false) {
323
335
  if (node == null || typeof node === "boolean")
324
336
  return;
325
337
  if (typeof node === "string") {
326
- writer.write(escapeHtml(node));
338
+ writer.text(escapeHtml(node));
327
339
  return;
328
340
  }
329
341
  if (typeof node === "number") {
330
- writer.write(String(node));
342
+ writer.text(String(node));
331
343
  return;
332
344
  }
333
345
  if (Array.isArray(node)) {
@@ -340,7 +352,10 @@ function renderNode(node, writer, isSvg = false) {
340
352
  isSvg
341
353
  );
342
354
  }
343
- if (typeof node === "object" && node !== null && "$$typeof" in node && node.$$typeof === SLIM_ELEMENT) {
355
+ if (typeof node === "object" && node !== null && "$$typeof" in node) {
356
+ const elType = node["$$typeof"];
357
+ if (elType !== SLIM_ELEMENT && elType !== REACT19_ELEMENT)
358
+ return;
344
359
  const element = node;
345
360
  const { type, props } = element;
346
361
  if (type === FRAGMENT_TYPE) {
@@ -352,16 +367,79 @@ function renderNode(node, writer, isSvg = false) {
352
367
  if (typeof type === "function") {
353
368
  return renderComponent(type, props, writer, isSvg);
354
369
  }
370
+ if (typeof type === "object" && type !== null) {
371
+ return renderComponent(type, props, writer, isSvg);
372
+ }
355
373
  if (typeof type === "string") {
356
374
  return renderHostElement(type, props, writer, isSvg);
357
375
  }
358
376
  }
359
377
  }
378
+ function markSelectedOptionsMulti(children, selectedValues) {
379
+ if (children == null || typeof children === "boolean")
380
+ return children;
381
+ if (typeof children === "string" || typeof children === "number")
382
+ return children;
383
+ if (Array.isArray(children)) {
384
+ return children.map((c) => markSelectedOptionsMulti(c, selectedValues));
385
+ }
386
+ if (typeof children === "object" && "$$typeof" in children) {
387
+ const elType = children["$$typeof"];
388
+ if (elType !== SLIM_ELEMENT && elType !== REACT19_ELEMENT)
389
+ return children;
390
+ const el = children;
391
+ if (el.type === "option") {
392
+ const optValue = el.props.value !== void 0 ? el.props.value : el.props.children;
393
+ const isSelected = selectedValues.has(String(optValue));
394
+ return { ...el, props: { ...el.props, selected: isSelected || void 0 } };
395
+ }
396
+ if (el.type === "optgroup" || el.type === FRAGMENT_TYPE) {
397
+ const newChildren = markSelectedOptionsMulti(el.props.children, selectedValues);
398
+ return { ...el, props: { ...el.props, children: newChildren } };
399
+ }
400
+ }
401
+ return children;
402
+ }
360
403
  function renderHostElement(tag, props, writer, isSvg) {
361
404
  const enteringSvg = tag === "svg";
362
405
  const childSvg = isSvg || enteringSvg;
363
- const effectiveProps = enteringSvg && !props.xmlns ? { xmlns: "http://www.w3.org/2000/svg", ...props } : props;
364
- writer.write(`<${tag}${renderAttributes(effectiveProps, childSvg)}>`);
406
+ if (tag === "textarea") {
407
+ const textContent = props.value ?? props.defaultValue ?? props.children ?? "";
408
+ const filteredProps = {};
409
+ for (const k of Object.keys(props)) {
410
+ if (k !== "value" && k !== "defaultValue" && k !== "children")
411
+ filteredProps[k] = props[k];
412
+ }
413
+ writer.write(`<textarea${renderAttributes(filteredProps, false)}>`);
414
+ writer.text(escapeHtml(String(textContent)));
415
+ writer.write("</textarea>");
416
+ return;
417
+ }
418
+ if (tag === "select") {
419
+ const selectedValue = props.value ?? props.defaultValue;
420
+ const filteredProps = {};
421
+ for (const k of Object.keys(props)) {
422
+ if (k !== "value" && k !== "defaultValue")
423
+ filteredProps[k] = props[k];
424
+ }
425
+ writer.write(`<select${renderAttributes(filteredProps, false)}>`);
426
+ const selectedSet = selectedValue == null ? null : Array.isArray(selectedValue) ? new Set(selectedValue.map(String)) : /* @__PURE__ */ new Set([String(selectedValue)]);
427
+ const patchedChildren = selectedSet != null ? markSelectedOptionsMulti(props.children, selectedSet) : props.children;
428
+ const inner2 = renderChildren(patchedChildren, writer, false);
429
+ if (inner2 && typeof inner2.then === "function") {
430
+ return inner2.then(() => {
431
+ writer.write("</select>");
432
+ });
433
+ }
434
+ writer.write("</select>");
435
+ return;
436
+ }
437
+ writer.write(`<${tag}${renderAttributes(props, childSvg)}`);
438
+ if (VOID_ELEMENTS.has(tag)) {
439
+ writer.write("/>");
440
+ return;
441
+ }
442
+ writer.write(">");
365
443
  const childContext = tag === "foreignObject" ? false : childSvg;
366
444
  let inner = void 0;
367
445
  if (props.dangerouslySetInnerHTML) {
@@ -371,17 +449,17 @@ function renderHostElement(tag, props, writer, isSvg) {
371
449
  }
372
450
  if (inner && typeof inner.then === "function") {
373
451
  return inner.then(() => {
374
- if (!VOID_ELEMENTS.has(tag))
375
- writer.write(`</${tag}>`);
452
+ writer.write(`</${tag}>`);
376
453
  });
377
454
  }
378
- if (!VOID_ELEMENTS.has(tag))
379
- writer.write(`</${tag}>`);
455
+ writer.write(`</${tag}>`);
380
456
  }
381
457
  var REACT_MEMO = Symbol.for("react.memo");
382
458
  var REACT_FORWARD_REF = Symbol.for("react.forward_ref");
383
459
  var REACT_PROVIDER = Symbol.for("react.provider");
384
460
  var REACT_CONTEXT = Symbol.for("react.context");
461
+ var REACT_CONSUMER = Symbol.for("react.consumer");
462
+ var REACT_LAZY = Symbol.for("react.lazy");
385
463
  function renderComponent(type, props, writer, isSvg) {
386
464
  const typeOf = type?.$$typeof;
387
465
  if (typeOf === REACT_MEMO) {
@@ -394,6 +472,24 @@ function renderComponent(type, props, writer, isSvg) {
394
472
  if (typeOf === REACT_FORWARD_REF) {
395
473
  return renderComponent(type.render, props, writer, isSvg);
396
474
  }
475
+ if (typeOf === REACT_LAZY) {
476
+ const resolved = type._init(type._payload);
477
+ const LazyComp = resolved?.default ?? resolved;
478
+ return renderComponent(LazyComp, props, writer, isSvg);
479
+ }
480
+ if (typeOf === REACT_CONSUMER) {
481
+ const ctx2 = type._context;
482
+ const value = ctx2?._currentValue;
483
+ const result2 = typeof props.children === "function" ? props.children(value) : null;
484
+ const savedScope2 = pushComponentScope();
485
+ const finish2 = () => popComponentScope(savedScope2);
486
+ const r2 = renderNode(result2, writer, isSvg);
487
+ if (r2 && typeof r2.then === "function") {
488
+ return r2.then(finish2);
489
+ }
490
+ finish2();
491
+ return;
492
+ }
397
493
  const isProvider = "_context" in type || typeOf === REACT_PROVIDER || typeOf === REACT_CONTEXT && "value" in props;
398
494
  let prevCtxValue;
399
495
  let ctx;
@@ -403,10 +499,27 @@ function renderComponent(type, props, writer, isSvg) {
403
499
  ctx._currentValue = props.value;
404
500
  }
405
501
  const savedScope = pushComponentScope();
502
+ if (isProvider && typeof type !== "function") {
503
+ const finish2 = () => {
504
+ popComponentScope(savedScope);
505
+ ctx._currentValue = prevCtxValue;
506
+ };
507
+ const r2 = renderChildren(props.children, writer, isSvg);
508
+ if (r2 && typeof r2.then === "function") {
509
+ return r2.then(finish2);
510
+ }
511
+ finish2();
512
+ return;
513
+ }
406
514
  let result;
407
515
  try {
408
516
  if (type.prototype && typeof type.prototype.render === "function") {
409
517
  const instance = new type(props);
518
+ if (typeof type.getDerivedStateFromProps === "function") {
519
+ const derived = type.getDerivedStateFromProps(props, instance.state ?? {});
520
+ if (derived != null)
521
+ instance.state = { ...instance.state ?? {}, ...derived };
522
+ }
410
523
  result = instance.render();
411
524
  } else {
412
525
  result = type(props);
@@ -443,7 +556,7 @@ function isTextLike(node) {
443
556
  function renderChildArray(children, writer, isSvg) {
444
557
  const totalChildren = children.length;
445
558
  for (let i = 0; i < totalChildren; i++) {
446
- if (i > 0 && isTextLike(children[i]) && isTextLike(children[i - 1])) {
559
+ if (isTextLike(children[i]) && writer.lastWasText) {
447
560
  writer.write("<!-- -->");
448
561
  }
449
562
  const savedTree = pushTreeContext(totalChildren, i);
@@ -460,7 +573,7 @@ function renderChildArray(children, writer, isSvg) {
460
573
  function renderChildArrayFrom(children, startIndex, writer, isSvg) {
461
574
  const totalChildren = children.length;
462
575
  for (let i = startIndex; i < totalChildren; i++) {
463
- if (i > 0 && isTextLike(children[i]) && isTextLike(children[i - 1])) {
576
+ if (isTextLike(children[i]) && writer.lastWasText) {
464
577
  writer.write("<!-- -->");
465
578
  }
466
579
  const savedTree = pushTreeContext(totalChildren, i);
@@ -521,9 +634,17 @@ async function renderToString(element) {
521
634
  for (let attempt = 0; attempt < MAX_SUSPENSE_RETRIES; attempt++) {
522
635
  resetRenderState();
523
636
  const chunks = [];
524
- const writer = { write(c) {
525
- chunks.push(c);
526
- } };
637
+ const writer = {
638
+ lastWasText: false,
639
+ write(c) {
640
+ chunks.push(c);
641
+ this.lastWasText = false;
642
+ },
643
+ text(s2) {
644
+ chunks.push(s2);
645
+ this.lastWasText = true;
646
+ }
647
+ };
527
648
  try {
528
649
  const r = renderNode(element, writer);
529
650
  if (r && typeof r.then === "function")
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hadars",
3
- "version": "0.1.18",
3
+ "version": "0.1.19",
4
4
  "description": "Minimal SSR framework for React — rspack, HMR, TypeScript, Bun/Node/Deno",
5
5
  "module": "./dist/index.js",
6
6
  "type": "module",
@@ -32,7 +32,7 @@
32
32
  "build:lib": "tsup src/index.tsx src/slim-react/index.ts src/slim-react/jsx-runtime.ts --format esm,cjs --dts --out-dir dist --clean --external '@rspack/*' --external '@rspack/binding'",
33
33
  "build:cli": "node build-scripts/build-cli.mjs",
34
34
  "build:all": "npm run build:lib && npm run build:cli",
35
- "test": "bun test test/ssr.test.ts",
35
+ "test": "bun test test/render-compare.test.tsx && bun test test/ssr.test.ts",
36
36
  "prepare": "npm run build:all",
37
37
  "prepublishOnly": "npm run build:all"
38
38
  },