react-server-dom-webpack 19.0.0-canary-48ec17b86-20240402 → 19.0.0-canary-7a2609eed-20240403

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 (24) hide show
  1. package/cjs/react-server-dom-webpack-client.browser.development.js +13 -5
  2. package/cjs/react-server-dom-webpack-client.edge.development.js +13 -5
  3. package/cjs/react-server-dom-webpack-client.node.development.js +13 -5
  4. package/cjs/react-server-dom-webpack-client.node.unbundled.development.js +13 -5
  5. package/cjs/react-server-dom-webpack-server.browser.development.js +74 -25
  6. package/cjs/react-server-dom-webpack-server.browser.production.js +73 -26
  7. package/cjs/react-server-dom-webpack-server.browser.production.min.js +46 -45
  8. package/cjs/react-server-dom-webpack-server.browser.production.min.js.map +1 -1
  9. package/cjs/react-server-dom-webpack-server.edge.development.js +74 -25
  10. package/cjs/react-server-dom-webpack-server.edge.production.js +73 -26
  11. package/cjs/react-server-dom-webpack-server.edge.production.min.js +32 -31
  12. package/cjs/react-server-dom-webpack-server.edge.production.min.js.map +1 -1
  13. package/cjs/react-server-dom-webpack-server.node.development.js +74 -25
  14. package/cjs/react-server-dom-webpack-server.node.production.js +73 -26
  15. package/cjs/react-server-dom-webpack-server.node.production.min.js +33 -31
  16. package/cjs/react-server-dom-webpack-server.node.production.min.js.map +1 -1
  17. package/cjs/react-server-dom-webpack-server.node.unbundled.development.js +74 -25
  18. package/cjs/react-server-dom-webpack-server.node.unbundled.production.js +73 -26
  19. package/cjs/react-server-dom-webpack-server.node.unbundled.production.min.js +33 -31
  20. package/cjs/react-server-dom-webpack-server.node.unbundled.production.min.js.map +1 -1
  21. package/package.json +3 -3
  22. package/umd/react-server-dom-webpack-client.browser.development.js +13 -5
  23. package/umd/react-server-dom-webpack-server.browser.development.js +74 -25
  24. package/umd/react-server-dom-webpack-server.browser.production.min.js +50 -50
@@ -411,7 +411,7 @@ function printWarning(level, format, args) {
411
411
  // Please consider also adding to 'react-devtools-shared/src/backend/ReactSymbols'
412
412
  // The Symbol used to tag the ReactElement-like types.
413
413
  var REACT_ELEMENT_TYPE = Symbol.for('react.element');
414
- var REACT_PROVIDER_TYPE = Symbol.for('react.provider'); // TODO: Delete with enableRenderableContext
414
+ var REACT_CONTEXT_TYPE = Symbol.for('react.context');
415
415
  var REACT_FORWARD_REF_TYPE = Symbol.for('react.forward_ref');
416
416
  var REACT_SUSPENSE_TYPE = Symbol.for('react.suspense');
417
417
  var REACT_SUSPENSE_LIST_TYPE = Symbol.for('react.suspense_list');
@@ -1077,7 +1077,7 @@ function processReply(root, formFieldPrefix, temporaryReferences, resolve, rejec
1077
1077
  }
1078
1078
 
1079
1079
  {
1080
- if (value.$$typeof === (REACT_PROVIDER_TYPE)) {
1080
+ if (value.$$typeof === (REACT_CONTEXT_TYPE )) {
1081
1081
  error('React Context Providers cannot be passed to Server Functions from the Client.%s', describeObjectForErrorMessage(parent, key));
1082
1082
  } else if (objectName(value) !== 'Object') {
1083
1083
  error('Only plain objects can be passed to Server Functions from the Client. ' + '%s objects are not supported.%s', objectName(value), describeObjectForErrorMessage(parent, key));
@@ -1497,20 +1497,28 @@ function reportGlobalError(response, error) {
1497
1497
  });
1498
1498
  }
1499
1499
 
1500
+ function nullRefGetter() {
1501
+ {
1502
+ return null;
1503
+ }
1504
+ }
1505
+
1500
1506
  function createElement(type, key, props) {
1501
1507
  var element;
1502
1508
 
1503
1509
  {
1510
+ // `ref` is non-enumerable in dev
1504
1511
  element = {
1505
- // This tag allows us to uniquely identify this as a React Element
1506
1512
  $$typeof: REACT_ELEMENT_TYPE,
1507
1513
  type: type,
1508
1514
  key: key,
1509
- ref: null,
1510
1515
  props: props,
1511
- // Record the component responsible for creating this element.
1512
1516
  _owner: null
1513
1517
  };
1518
+ Object.defineProperty(element, 'ref', {
1519
+ enumerable: false,
1520
+ get: nullRefGetter
1521
+ });
1514
1522
  }
1515
1523
 
1516
1524
  {
@@ -430,7 +430,7 @@ function printWarning(level, format, args) {
430
430
  // Please consider also adding to 'react-devtools-shared/src/backend/ReactSymbols'
431
431
  // The Symbol used to tag the ReactElement-like types.
432
432
  var REACT_ELEMENT_TYPE = Symbol.for('react.element');
433
- var REACT_PROVIDER_TYPE = Symbol.for('react.provider'); // TODO: Delete with enableRenderableContext
433
+ var REACT_CONTEXT_TYPE = Symbol.for('react.context');
434
434
  var REACT_FORWARD_REF_TYPE = Symbol.for('react.forward_ref');
435
435
  var REACT_SUSPENSE_TYPE = Symbol.for('react.suspense');
436
436
  var REACT_SUSPENSE_LIST_TYPE = Symbol.for('react.suspense_list');
@@ -1096,7 +1096,7 @@ function processReply(root, formFieldPrefix, temporaryReferences, resolve, rejec
1096
1096
  }
1097
1097
 
1098
1098
  {
1099
- if (value.$$typeof === (REACT_PROVIDER_TYPE)) {
1099
+ if (value.$$typeof === (REACT_CONTEXT_TYPE )) {
1100
1100
  error('React Context Providers cannot be passed to Server Functions from the Client.%s', describeObjectForErrorMessage(parent, key));
1101
1101
  } else if (objectName(value) !== 'Object') {
1102
1102
  error('Only plain objects can be passed to Server Functions from the Client. ' + '%s objects are not supported.%s', objectName(value), describeObjectForErrorMessage(parent, key));
@@ -1750,20 +1750,28 @@ function reportGlobalError(response, error) {
1750
1750
  });
1751
1751
  }
1752
1752
 
1753
+ function nullRefGetter() {
1754
+ {
1755
+ return null;
1756
+ }
1757
+ }
1758
+
1753
1759
  function createElement(type, key, props) {
1754
1760
  var element;
1755
1761
 
1756
1762
  {
1763
+ // `ref` is non-enumerable in dev
1757
1764
  element = {
1758
- // This tag allows us to uniquely identify this as a React Element
1759
1765
  $$typeof: REACT_ELEMENT_TYPE,
1760
1766
  type: type,
1761
1767
  key: key,
1762
- ref: null,
1763
1768
  props: props,
1764
- // Record the component responsible for creating this element.
1765
1769
  _owner: null
1766
1770
  };
1771
+ Object.defineProperty(element, 'ref', {
1772
+ enumerable: false,
1773
+ get: nullRefGetter
1774
+ });
1767
1775
  }
1768
1776
 
1769
1777
  {
@@ -431,7 +431,7 @@ function printWarning(level, format, args) {
431
431
  // Please consider also adding to 'react-devtools-shared/src/backend/ReactSymbols'
432
432
  // The Symbol used to tag the ReactElement-like types.
433
433
  var REACT_ELEMENT_TYPE = Symbol.for('react.element');
434
- var REACT_PROVIDER_TYPE = Symbol.for('react.provider'); // TODO: Delete with enableRenderableContext
434
+ var REACT_CONTEXT_TYPE = Symbol.for('react.context');
435
435
  var REACT_FORWARD_REF_TYPE = Symbol.for('react.forward_ref');
436
436
  var REACT_SUSPENSE_TYPE = Symbol.for('react.suspense');
437
437
  var REACT_SUSPENSE_LIST_TYPE = Symbol.for('react.suspense_list');
@@ -1094,7 +1094,7 @@ function processReply(root, formFieldPrefix, temporaryReferences, resolve, rejec
1094
1094
  }
1095
1095
 
1096
1096
  {
1097
- if (value.$$typeof === (REACT_PROVIDER_TYPE)) {
1097
+ if (value.$$typeof === (REACT_CONTEXT_TYPE )) {
1098
1098
  error('React Context Providers cannot be passed to Server Functions from the Client.%s', describeObjectForErrorMessage(parent, key));
1099
1099
  } else if (objectName(value) !== 'Object') {
1100
1100
  error('Only plain objects can be passed to Server Functions from the Client. ' + '%s objects are not supported.%s', objectName(value), describeObjectForErrorMessage(parent, key));
@@ -1748,20 +1748,28 @@ function reportGlobalError(response, error) {
1748
1748
  });
1749
1749
  }
1750
1750
 
1751
+ function nullRefGetter() {
1752
+ {
1753
+ return null;
1754
+ }
1755
+ }
1756
+
1751
1757
  function createElement(type, key, props) {
1752
1758
  var element;
1753
1759
 
1754
1760
  {
1761
+ // `ref` is non-enumerable in dev
1755
1762
  element = {
1756
- // This tag allows us to uniquely identify this as a React Element
1757
1763
  $$typeof: REACT_ELEMENT_TYPE,
1758
1764
  type: type,
1759
1765
  key: key,
1760
- ref: null,
1761
1766
  props: props,
1762
- // Record the component responsible for creating this element.
1763
1767
  _owner: null
1764
1768
  };
1769
+ Object.defineProperty(element, 'ref', {
1770
+ enumerable: false,
1771
+ get: nullRefGetter
1772
+ });
1765
1773
  }
1766
1774
 
1767
1775
  {
@@ -384,7 +384,7 @@ function printWarning(level, format, args) {
384
384
  // Please consider also adding to 'react-devtools-shared/src/backend/ReactSymbols'
385
385
  // The Symbol used to tag the ReactElement-like types.
386
386
  var REACT_ELEMENT_TYPE = Symbol.for('react.element');
387
- var REACT_PROVIDER_TYPE = Symbol.for('react.provider'); // TODO: Delete with enableRenderableContext
387
+ var REACT_CONTEXT_TYPE = Symbol.for('react.context');
388
388
  var REACT_FORWARD_REF_TYPE = Symbol.for('react.forward_ref');
389
389
  var REACT_SUSPENSE_TYPE = Symbol.for('react.suspense');
390
390
  var REACT_SUSPENSE_LIST_TYPE = Symbol.for('react.suspense_list');
@@ -1047,7 +1047,7 @@ function processReply(root, formFieldPrefix, temporaryReferences, resolve, rejec
1047
1047
  }
1048
1048
 
1049
1049
  {
1050
- if (value.$$typeof === (REACT_PROVIDER_TYPE)) {
1050
+ if (value.$$typeof === (REACT_CONTEXT_TYPE )) {
1051
1051
  error('React Context Providers cannot be passed to Server Functions from the Client.%s', describeObjectForErrorMessage(parent, key));
1052
1052
  } else if (objectName(value) !== 'Object') {
1053
1053
  error('Only plain objects can be passed to Server Functions from the Client. ' + '%s objects are not supported.%s', objectName(value), describeObjectForErrorMessage(parent, key));
@@ -1701,20 +1701,28 @@ function reportGlobalError(response, error) {
1701
1701
  });
1702
1702
  }
1703
1703
 
1704
+ function nullRefGetter() {
1705
+ {
1706
+ return null;
1707
+ }
1708
+ }
1709
+
1704
1710
  function createElement(type, key, props) {
1705
1711
  var element;
1706
1712
 
1707
1713
  {
1714
+ // `ref` is non-enumerable in dev
1708
1715
  element = {
1709
- // This tag allows us to uniquely identify this as a React Element
1710
1716
  $$typeof: REACT_ELEMENT_TYPE,
1711
1717
  type: type,
1712
1718
  key: key,
1713
- ref: null,
1714
1719
  props: props,
1715
- // Record the component responsible for creating this element.
1716
1720
  _owner: null
1717
1721
  };
1722
+ Object.defineProperty(element, 'ref', {
1723
+ enumerable: false,
1724
+ get: nullRefGetter
1725
+ });
1718
1726
  }
1719
1727
 
1720
1728
  {
@@ -1034,10 +1034,6 @@ function use(usable) {
1034
1034
  }
1035
1035
  }
1036
1036
 
1037
- function createSignal() {
1038
- return new AbortController().signal;
1039
- }
1040
-
1041
1037
  function resolveCache() {
1042
1038
  var request = resolveRequest();
1043
1039
 
@@ -1049,17 +1045,6 @@ function resolveCache() {
1049
1045
  }
1050
1046
 
1051
1047
  var DefaultCacheDispatcher = {
1052
- getCacheSignal: function () {
1053
- var cache = resolveCache();
1054
- var entry = cache.get(createSignal);
1055
-
1056
- if (entry === undefined) {
1057
- entry = createSignal();
1058
- cache.set(createSignal, entry);
1059
- }
1060
-
1061
- return entry;
1062
- },
1063
1048
  getCacheForType: function (resourceType) {
1064
1049
  var cache = resolveCache();
1065
1050
  var entry = cache.get(resourceType);
@@ -1736,15 +1721,68 @@ function renderFragment(request, task, children) {
1736
1721
  }
1737
1722
  }
1738
1723
 
1739
- {
1740
- return children;
1741
- }
1724
+ if (task.keyPath !== null) {
1725
+ // We have a Server Component that specifies a key but we're now splitting
1726
+ // the tree using a fragment.
1727
+ var fragment = [REACT_ELEMENT_TYPE, REACT_FRAGMENT_TYPE, task.keyPath, {
1728
+ children: children
1729
+ }];
1730
+
1731
+ if (!task.implicitSlot) {
1732
+ // If this was keyed inside a set. I.e. the outer Server Component was keyed
1733
+ // then we need to handle reorders of the whole set. To do this we need to wrap
1734
+ // this array in a keyed Fragment.
1735
+ return fragment;
1736
+ } // If the outer Server Component was implicit but then an inner one had a key
1737
+ // we don't actually need to be able to move the whole set around. It'll always be
1738
+ // in an implicit slot. The key only exists to be able to reset the state of the
1739
+ // children. We could achieve the same effect by passing on the keyPath to the next
1740
+ // set of components inside the fragment. This would also allow a keyless fragment
1741
+ // reconcile against a single child.
1742
+ // Unfortunately because of JSON.stringify, we can't call the recursive loop for
1743
+ // each child within this context because we can't return a set with already resolved
1744
+ // values. E.g. a string would get double encoded. Returning would pop the context.
1745
+ // So instead, we wrap it with an unkeyed fragment and inner keyed fragment.
1746
+
1747
+
1748
+ return [fragment];
1749
+ } // Since we're yielding here, that implicitly resets the keyPath context on the
1750
+ // way up. Which is what we want since we've consumed it. If this changes to
1751
+ // be recursive serialization, we need to reset the keyPath and implicitSlot,
1752
+ // before recursing here.
1753
+
1754
+
1755
+ return children;
1742
1756
  }
1743
1757
 
1744
1758
  function renderClientElement(task, type, key, props) {
1745
- {
1746
- return [REACT_ELEMENT_TYPE, type, key, props];
1747
- } // We prepend the terminal client element that actually gets serialized with
1759
+ // the keys of any Server Components which are not serialized.
1760
+
1761
+
1762
+ var keyPath = task.keyPath;
1763
+
1764
+ if (key === null) {
1765
+ key = keyPath;
1766
+ } else if (keyPath !== null) {
1767
+ key = keyPath + ',' + key;
1768
+ }
1769
+
1770
+ var element = [REACT_ELEMENT_TYPE, type, key, props];
1771
+
1772
+ if (task.implicitSlot && key !== null) {
1773
+ // The root Server Component had no key so it was in an implicit slot.
1774
+ // If we had a key lower, it would end up in that slot with an explicit key.
1775
+ // We wrap the element in a fragment to give it an implicit key slot with
1776
+ // an inner explicit key.
1777
+ return [element];
1778
+ } // Since we're yielding here, that implicitly resets the keyPath context on the
1779
+ // way up. Which is what we want since we've consumed it. If this changes to
1780
+ // be recursive serialization, we need to reset the keyPath and implicitSlot,
1781
+ // before recursing here. We also need to reset it once we render into an array
1782
+ // or anything else too which we also get implicitly.
1783
+
1784
+
1785
+ return element;
1748
1786
  } // The chunk ID we're currently rendering that we can assign debug data to.
1749
1787
 
1750
1788
 
@@ -1863,7 +1901,7 @@ function createTask(request, model, keyPath, implicitSlot, abortSet) {
1863
1901
  if (typeof model === 'object' && model !== null) {
1864
1902
  // If we're about to write this into a new task we can assign it an ID early so that
1865
1903
  // any other references can refer to the value we're about to write.
1866
- {
1904
+ if ((keyPath !== null || implicitSlot)) ; else {
1867
1905
  request.writtenObjects.set(model, id);
1868
1906
  }
1869
1907
  }
@@ -2194,7 +2232,7 @@ function renderModelDestructive(request, task, parent, parentPropertyName, value
2194
2232
  var _existingId = _writtenObjects.get(value);
2195
2233
 
2196
2234
  if (_existingId !== undefined) {
2197
- if (modelRoot === value) {
2235
+ if ((task.keyPath !== null || task.implicitSlot)) ; else if (modelRoot === value) {
2198
2236
  // This is the ID we're currently emitting so we need to write it
2199
2237
  // once but if we discover it again, we refer to it by id.
2200
2238
  modelRoot = null;
@@ -2246,7 +2284,11 @@ function renderModelDestructive(request, task, parent, parentPropertyName, value
2246
2284
  var ref;
2247
2285
 
2248
2286
  {
2249
- ref = element.ref;
2287
+ // TODO: This is a temporary, intermediate step. Once the feature
2288
+ // flag is removed, we should get the ref off the props object right
2289
+ // before using it.
2290
+ var refProp = props.ref;
2291
+ ref = refProp !== undefined ? refProp : null;
2250
2292
  } // Attempt to render the Server Component.
2251
2293
 
2252
2294
 
@@ -2295,7 +2337,14 @@ function renderModelDestructive(request, task, parent, parentPropertyName, value
2295
2337
 
2296
2338
  if (typeof value.then === 'function') {
2297
2339
  if (existingId !== undefined) {
2298
- if (modelRoot === value) {
2340
+ if ((task.keyPath !== null || task.implicitSlot)) {
2341
+ // If we're in some kind of context we can't reuse the result of this render or
2342
+ // previous renders of this element. We only reuse Promises if they're not wrapped
2343
+ // by another Server Component.
2344
+ var _promiseId = serializeThenable(request, task, value);
2345
+
2346
+ return serializePromiseID(_promiseId);
2347
+ } else if (modelRoot === value) {
2299
2348
  // This is the ID we're currently emitting so we need to write it
2300
2349
  // once but if we discover it again, we refer to it by id.
2301
2350
  modelRoot = null;
@@ -992,10 +992,6 @@ function use(usable) {
992
992
  }
993
993
  }
994
994
 
995
- function createSignal() {
996
- return new AbortController().signal;
997
- }
998
-
999
995
  function resolveCache() {
1000
996
  const request = resolveRequest();
1001
997
 
@@ -1007,18 +1003,6 @@ function resolveCache() {
1007
1003
  }
1008
1004
 
1009
1005
  const DefaultCacheDispatcher = {
1010
- getCacheSignal() {
1011
- const cache = resolveCache();
1012
- let entry = cache.get(createSignal);
1013
-
1014
- if (entry === undefined) {
1015
- entry = createSignal();
1016
- cache.set(createSignal, entry);
1017
- }
1018
-
1019
- return entry;
1020
- },
1021
-
1022
1006
  getCacheForType(resourceType) {
1023
1007
  const cache = resolveCache();
1024
1008
  let entry = cache.get(resourceType);
@@ -1512,15 +1496,68 @@ function renderFunctionComponent(request, task, key, Component, props) {
1512
1496
 
1513
1497
  function renderFragment(request, task, children) {
1514
1498
 
1515
- {
1516
- return children;
1517
- }
1499
+ if (task.keyPath !== null) {
1500
+ // We have a Server Component that specifies a key but we're now splitting
1501
+ // the tree using a fragment.
1502
+ const fragment = [REACT_ELEMENT_TYPE, REACT_FRAGMENT_TYPE, task.keyPath, {
1503
+ children
1504
+ }];
1505
+
1506
+ if (!task.implicitSlot) {
1507
+ // If this was keyed inside a set. I.e. the outer Server Component was keyed
1508
+ // then we need to handle reorders of the whole set. To do this we need to wrap
1509
+ // this array in a keyed Fragment.
1510
+ return fragment;
1511
+ } // If the outer Server Component was implicit but then an inner one had a key
1512
+ // we don't actually need to be able to move the whole set around. It'll always be
1513
+ // in an implicit slot. The key only exists to be able to reset the state of the
1514
+ // children. We could achieve the same effect by passing on the keyPath to the next
1515
+ // set of components inside the fragment. This would also allow a keyless fragment
1516
+ // reconcile against a single child.
1517
+ // Unfortunately because of JSON.stringify, we can't call the recursive loop for
1518
+ // each child within this context because we can't return a set with already resolved
1519
+ // values. E.g. a string would get double encoded. Returning would pop the context.
1520
+ // So instead, we wrap it with an unkeyed fragment and inner keyed fragment.
1521
+
1522
+
1523
+ return [fragment];
1524
+ } // Since we're yielding here, that implicitly resets the keyPath context on the
1525
+ // way up. Which is what we want since we've consumed it. If this changes to
1526
+ // be recursive serialization, we need to reset the keyPath and implicitSlot,
1527
+ // before recursing here.
1528
+
1529
+
1530
+ return children;
1518
1531
  }
1519
1532
 
1520
1533
  function renderClientElement(task, type, key, props) {
1521
- {
1522
- return [REACT_ELEMENT_TYPE, type, key, props];
1523
- } // We prepend the terminal client element that actually gets serialized with
1534
+ // the keys of any Server Components which are not serialized.
1535
+
1536
+
1537
+ const keyPath = task.keyPath;
1538
+
1539
+ if (key === null) {
1540
+ key = keyPath;
1541
+ } else if (keyPath !== null) {
1542
+ key = keyPath + ',' + key;
1543
+ }
1544
+
1545
+ const element = [REACT_ELEMENT_TYPE, type, key, props];
1546
+
1547
+ if (task.implicitSlot && key !== null) {
1548
+ // The root Server Component had no key so it was in an implicit slot.
1549
+ // If we had a key lower, it would end up in that slot with an explicit key.
1550
+ // We wrap the element in a fragment to give it an implicit key slot with
1551
+ // an inner explicit key.
1552
+ return [element];
1553
+ } // Since we're yielding here, that implicitly resets the keyPath context on the
1554
+ // way up. Which is what we want since we've consumed it. If this changes to
1555
+ // be recursive serialization, we need to reset the keyPath and implicitSlot,
1556
+ // before recursing here. We also need to reset it once we render into an array
1557
+ // or anything else too which we also get implicitly.
1558
+
1559
+
1560
+ return element;
1524
1561
  } // The chunk ID we're currently rendering that we can assign debug data to.
1525
1562
 
1526
1563
 
@@ -1612,7 +1649,7 @@ function createTask(request, model, keyPath, implicitSlot, abortSet) {
1612
1649
  if (typeof model === 'object' && model !== null) {
1613
1650
  // If we're about to write this into a new task we can assign it an ID early so that
1614
1651
  // any other references can refer to the value we're about to write.
1615
- {
1652
+ if ((keyPath !== null || implicitSlot)) ; else {
1616
1653
  request.writtenObjects.set(model, id);
1617
1654
  }
1618
1655
  }
@@ -1921,7 +1958,7 @@ function renderModelDestructive(request, task, parent, parentPropertyName, value
1921
1958
  const existingId = writtenObjects.get(value);
1922
1959
 
1923
1960
  if (existingId !== undefined) {
1924
- if (modelRoot === value) {
1961
+ if ((task.keyPath !== null || task.implicitSlot)) ; else if (modelRoot === value) {
1925
1962
  // This is the ID we're currently emitting so we need to write it
1926
1963
  // once but if we discover it again, we refer to it by id.
1927
1964
  modelRoot = null;
@@ -1956,7 +1993,11 @@ function renderModelDestructive(request, task, parent, parentPropertyName, value
1956
1993
  let ref;
1957
1994
 
1958
1995
  {
1959
- ref = element.ref;
1996
+ // TODO: This is a temporary, intermediate step. Once the feature
1997
+ // flag is removed, we should get the ref off the props object right
1998
+ // before using it.
1999
+ const refProp = props.ref;
2000
+ ref = refProp !== undefined ? refProp : null;
1960
2001
  } // Attempt to render the Server Component.
1961
2002
 
1962
2003
 
@@ -1987,7 +2028,13 @@ function renderModelDestructive(request, task, parent, parentPropertyName, value
1987
2028
 
1988
2029
  if (typeof value.then === 'function') {
1989
2030
  if (existingId !== undefined) {
1990
- if (modelRoot === value) {
2031
+ if ((task.keyPath !== null || task.implicitSlot)) {
2032
+ // If we're in some kind of context we can't reuse the result of this render or
2033
+ // previous renders of this element. We only reuse Promises if they're not wrapped
2034
+ // by another Server Component.
2035
+ const promiseId = serializeThenable(request, task, value);
2036
+ return serializePromiseID(promiseId);
2037
+ } else if (modelRoot === value) {
1991
2038
  // This is the ID we're currently emitting so we need to write it
1992
2039
  // once but if we discover it again, we refer to it by id.
1993
2040
  modelRoot = null;