react-server-dom-webpack 19.0.0-canary-cf5ab8b8b2-20240425 → 19.0.0-rc-915b914b3a-20240515

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.
@@ -151,9 +151,22 @@ var textEncoder = new TextEncoder();
151
151
  function stringToChunk(content) {
152
152
  return textEncoder.encode(content);
153
153
  }
154
+ function typedArrayToBinaryChunk(content) {
155
+ // Convert any non-Uint8Array array to Uint8Array. We could avoid this for Uint8Arrays.
156
+ // If we passed through this straight to enqueue we wouldn't have to convert it but since
157
+ // we need to copy the buffer in that case, we need to convert it to copy it.
158
+ // When we copy it into another array using set() it needs to be a Uint8Array.
159
+ var buffer = new Uint8Array(content.buffer, content.byteOffset, content.byteLength); // We clone large chunks so that we can transfer them when we write them.
160
+ // Others get copied into the target buffer.
161
+
162
+ return content.byteLength > VIEW_SIZE ? buffer.slice() : buffer;
163
+ }
154
164
  function byteLengthOfChunk(chunk) {
155
165
  return chunk.byteLength;
156
166
  }
167
+ function byteLengthOfBinaryChunk(chunk) {
168
+ return chunk.byteLength;
169
+ }
157
170
  function closeWithError(destination, error) {
158
171
  // $FlowFixMe[method-unbinding]
159
172
  if (typeof destination.error === 'function') {
@@ -765,14 +778,19 @@ function createHints() {
765
778
 
766
779
  var supportsRequestStorage = false;
767
780
  var requestStorage = null;
781
+ var supportsComponentStorage = false;
782
+ var componentStorage = null;
768
783
 
769
784
  var TEMPORARY_REFERENCE_TAG = Symbol.for('react.temporary.reference'); // eslint-disable-next-line no-unused-vars
770
785
 
771
- function isTemporaryReference(reference) {
786
+ function createTemporaryReferenceSet() {
787
+ return new WeakMap();
788
+ }
789
+ function isOpaqueTemporaryReference(reference) {
772
790
  return reference.$$typeof === TEMPORARY_REFERENCE_TAG;
773
791
  }
774
- function resolveTemporaryReferenceID(temporaryReference) {
775
- return temporaryReference.$$id;
792
+ function resolveTemporaryReference(temporaryReferences, temporaryReference) {
793
+ return temporaryReferences.get(temporaryReference);
776
794
  }
777
795
  var proxyHandlers = {
778
796
  get: function (target, name, receiver) {
@@ -783,12 +801,6 @@ var proxyHandlers = {
783
801
  // have the Flight runtime extract the inner target instead.
784
802
  return target.$$typeof;
785
803
 
786
- case '$$id':
787
- return target.$$id;
788
-
789
- case '$$async':
790
- return target.$$async;
791
-
792
804
  case 'name':
793
805
  return undefined;
794
806
 
@@ -823,21 +835,28 @@ var proxyHandlers = {
823
835
  throw new Error('Cannot assign to a temporary client reference from a server module.');
824
836
  }
825
837
  };
826
- function createTemporaryReference(id) {
838
+ function createTemporaryReference(temporaryReferences, id) {
827
839
  var reference = Object.defineProperties(function () {
828
840
  throw new Error( // eslint-disable-next-line react-internal/safe-string-coercion
829
841
  "Attempted to call a temporary Client Reference from the server but it is on the client. " + "It's not possible to invoke a client function from the server, it can " + "only be rendered as a Component or passed to props of a Client Component.");
830
842
  }, {
831
843
  $$typeof: {
832
844
  value: TEMPORARY_REFERENCE_TAG
833
- },
834
- $$id: {
835
- value: id
836
845
  }
837
846
  });
838
- return new Proxy(reference, proxyHandlers);
847
+ var wrapper = new Proxy(reference, proxyHandlers);
848
+ registerTemporaryReference(temporaryReferences, wrapper, id);
849
+ return wrapper;
839
850
  }
851
+ function registerTemporaryReference(temporaryReferences, object, id) {
852
+ temporaryReferences.set(object, id);
853
+ }
854
+
855
+ // When adding new symbols to this file,
856
+ // Please consider also adding to 'react-devtools-shared/src/backend/ReactSymbols'
857
+ // The Symbol used to tag the ReactElement-like types.
840
858
 
859
+ var REACT_LEGACY_ELEMENT_TYPE = Symbol.for('react.element');
841
860
  var REACT_ELEMENT_TYPE = Symbol.for('react.transitional.element') ;
842
861
  var REACT_FRAGMENT_TYPE = Symbol.for('react.fragment');
843
862
  var REACT_CONTEXT_TYPE = Symbol.for('react.context');
@@ -863,6 +882,7 @@ function getIteratorFn(maybeIterable) {
863
882
 
864
883
  return null;
865
884
  }
885
+ var ASYNC_ITERATOR = Symbol.asyncIterator;
866
886
 
867
887
  // Corresponds to ReactFiberWakeable and ReactFizzWakeable modules. Generally,
868
888
  // changes to one module should be reflected in the others.
@@ -1111,6 +1131,16 @@ function use(usable) {
1111
1131
  }
1112
1132
  }
1113
1133
 
1134
+ var currentOwner = null;
1135
+ function setCurrentOwner(componentInfo) {
1136
+ currentOwner = componentInfo;
1137
+ }
1138
+ function resolveOwner() {
1139
+ if (currentOwner) return currentOwner;
1140
+
1141
+ return null;
1142
+ }
1143
+
1114
1144
  function resolveCache() {
1115
1145
  var request = resolveRequest();
1116
1146
 
@@ -1121,7 +1151,7 @@ function resolveCache() {
1121
1151
  return new Map();
1122
1152
  }
1123
1153
 
1124
- var DefaultCacheDispatcher = {
1154
+ var DefaultAsyncDispatcher = {
1125
1155
  getCacheForType: function (resourceType) {
1126
1156
  var cache = resolveCache();
1127
1157
  var entry = cache.get(resourceType);
@@ -1136,6 +1166,10 @@ var DefaultCacheDispatcher = {
1136
1166
  }
1137
1167
  };
1138
1168
 
1169
+ {
1170
+ DefaultAsyncDispatcher.getOwner = resolveOwner;
1171
+ }
1172
+
1139
1173
  var isArrayImpl = Array.isArray; // eslint-disable-next-line no-redeclare
1140
1174
 
1141
1175
  function isArray(a) {
@@ -1484,10 +1518,7 @@ var stringify = JSON.stringify; // Serializable values
1484
1518
  var PENDING$1 = 0;
1485
1519
  var COMPLETED = 1;
1486
1520
  var ABORTED = 3;
1487
- var ERRORED$1 = 4; // object reference status
1488
-
1489
- var SEEN_BUT_NOT_YET_OUTLINED = -1;
1490
- var NEVER_OUTLINED = -2;
1521
+ var ERRORED$1 = 4;
1491
1522
 
1492
1523
  function defaultErrorHandler(error) {
1493
1524
  console['error'](error); // Don't transform to our wrapper
@@ -1499,12 +1530,12 @@ function defaultPostponeHandler(reason) {// Noop
1499
1530
  var OPEN = 0;
1500
1531
  var CLOSING = 1;
1501
1532
  var CLOSED = 2;
1502
- function createRequest(model, bundlerConfig, onError, identifierPrefix, onPostpone, environmentName) {
1503
- if (ReactSharedInternals.C !== null && ReactSharedInternals.C !== DefaultCacheDispatcher) {
1533
+ function createRequest(model, bundlerConfig, onError, identifierPrefix, onPostpone, environmentName, temporaryReferences) {
1534
+ if (ReactSharedInternals.A !== null && ReactSharedInternals.A !== DefaultAsyncDispatcher) {
1504
1535
  throw new Error('Currently React only supports one RSC renderer at a time.');
1505
1536
  }
1506
1537
 
1507
- ReactSharedInternals.C = DefaultCacheDispatcher;
1538
+ ReactSharedInternals.A = DefaultAsyncDispatcher;
1508
1539
  var abortSet = new Set();
1509
1540
  var pingedTasks = [];
1510
1541
  var cleanupQueue = [];
@@ -1531,6 +1562,7 @@ function createRequest(model, bundlerConfig, onError, identifierPrefix, onPostpo
1531
1562
  writtenClientReferences: new Map(),
1532
1563
  writtenServerReferences: new Map(),
1533
1564
  writtenObjects: new WeakMap(),
1565
+ temporaryReferences: temporaryReferences,
1534
1566
  identifierPrefix: identifierPrefix || '',
1535
1567
  identifierCount: 1,
1536
1568
  taintCleanupQueue: cleanupQueue,
@@ -1633,6 +1665,192 @@ function serializeThenable(request, task, thenable) {
1633
1665
  return newTask.id;
1634
1666
  }
1635
1667
 
1668
+ function serializeReadableStream(request, task, stream) {
1669
+ // Detect if this is a BYOB stream. BYOB streams should be able to be read as bytes on the
1670
+ // receiving side. It also implies that different chunks can be split up or merged as opposed
1671
+ // to a readable stream that happens to have Uint8Array as the type which might expect it to be
1672
+ // received in the same slices.
1673
+ // $FlowFixMe: This is a Node.js extension.
1674
+ var supportsBYOB = stream.supportsBYOB;
1675
+
1676
+ if (supportsBYOB === undefined) {
1677
+ try {
1678
+ // $FlowFixMe[extra-arg]: This argument is accepted.
1679
+ stream.getReader({
1680
+ mode: 'byob'
1681
+ }).releaseLock();
1682
+ supportsBYOB = true;
1683
+ } catch (x) {
1684
+ supportsBYOB = false;
1685
+ }
1686
+ }
1687
+
1688
+ var reader = stream.getReader(); // This task won't actually be retried. We just use it to attempt synchronous renders.
1689
+
1690
+ var streamTask = createTask(request, task.model, task.keyPath, task.implicitSlot, request.abortableTasks);
1691
+ request.abortableTasks.delete(streamTask);
1692
+ request.pendingChunks++; // The task represents the Start row. This adds a Stop row.
1693
+
1694
+ var startStreamRow = streamTask.id.toString(16) + ':' + (supportsBYOB ? 'r' : 'R') + '\n';
1695
+ request.completedRegularChunks.push(stringToChunk(startStreamRow)); // There's a race condition between when the stream is aborted and when the promise
1696
+ // resolves so we track whether we already aborted it to avoid writing twice.
1697
+
1698
+ var aborted = false;
1699
+
1700
+ function progress(entry) {
1701
+ if (aborted) {
1702
+ return;
1703
+ }
1704
+
1705
+ if (entry.done) {
1706
+ request.abortListeners.delete(error);
1707
+ var endStreamRow = streamTask.id.toString(16) + ':C\n';
1708
+ request.completedRegularChunks.push(stringToChunk(endStreamRow));
1709
+ enqueueFlush(request);
1710
+ aborted = true;
1711
+ } else {
1712
+ try {
1713
+ streamTask.model = entry.value;
1714
+ request.pendingChunks++;
1715
+ tryStreamTask(request, streamTask);
1716
+ enqueueFlush(request);
1717
+ reader.read().then(progress, error);
1718
+ } catch (x) {
1719
+ error(x);
1720
+ }
1721
+ }
1722
+ }
1723
+
1724
+ function error(reason) {
1725
+ if (aborted) {
1726
+ return;
1727
+ }
1728
+
1729
+ aborted = true;
1730
+ request.abortListeners.delete(error);
1731
+
1732
+ {
1733
+ var digest = logRecoverableError(request, reason);
1734
+ emitErrorChunk(request, streamTask.id, digest, reason);
1735
+ }
1736
+
1737
+ enqueueFlush(request); // $FlowFixMe should be able to pass mixed
1738
+
1739
+ reader.cancel(reason).then(error, error);
1740
+ }
1741
+
1742
+ request.abortListeners.add(error);
1743
+ reader.read().then(progress, error);
1744
+ return serializeByValueID(streamTask.id);
1745
+ } // This indirect exists so we can exclude its stack frame in DEV (and anything below it).
1746
+
1747
+ /** @noinline */
1748
+
1749
+
1750
+ function callIteratorInDEV(iterator, progress, error) {
1751
+ iterator.next().then(progress, error);
1752
+ }
1753
+
1754
+ function serializeAsyncIterable(request, task, iterable, iterator) {
1755
+ // Generators/Iterators are Iterables but they're also their own iterator
1756
+ // functions. If that's the case, we treat them as single-shot. Otherwise,
1757
+ // we assume that this iterable might be a multi-shot and allow it to be
1758
+ // iterated more than once on the client.
1759
+ var isIterator = iterable === iterator; // This task won't actually be retried. We just use it to attempt synchronous renders.
1760
+
1761
+ var streamTask = createTask(request, task.model, task.keyPath, task.implicitSlot, request.abortableTasks);
1762
+ request.abortableTasks.delete(streamTask);
1763
+ request.pendingChunks++; // The task represents the Start row. This adds a Stop row.
1764
+
1765
+ var startStreamRow = streamTask.id.toString(16) + ':' + (isIterator ? 'x' : 'X') + '\n';
1766
+ request.completedRegularChunks.push(stringToChunk(startStreamRow));
1767
+
1768
+ {
1769
+ var debugInfo = iterable._debugInfo;
1770
+
1771
+ if (debugInfo) {
1772
+ forwardDebugInfo(request, streamTask.id, debugInfo);
1773
+ }
1774
+ } // There's a race condition between when the stream is aborted and when the promise
1775
+ // resolves so we track whether we already aborted it to avoid writing twice.
1776
+
1777
+
1778
+ var aborted = false;
1779
+
1780
+ function progress(entry) {
1781
+ if (aborted) {
1782
+ return;
1783
+ }
1784
+
1785
+ if (entry.done) {
1786
+ request.abortListeners.delete(error);
1787
+ var endStreamRow;
1788
+
1789
+ if (entry.value === undefined) {
1790
+ endStreamRow = streamTask.id.toString(16) + ':C\n';
1791
+ } else {
1792
+ // Unlike streams, the last value may not be undefined. If it's not
1793
+ // we outline it and encode a reference to it in the closing instruction.
1794
+ try {
1795
+ var chunkId = outlineModel(request, entry.value);
1796
+ endStreamRow = streamTask.id.toString(16) + ':C' + stringify(serializeByValueID(chunkId)) + '\n';
1797
+ } catch (x) {
1798
+ error(x);
1799
+ return;
1800
+ }
1801
+ }
1802
+
1803
+ request.completedRegularChunks.push(stringToChunk(endStreamRow));
1804
+ enqueueFlush(request);
1805
+ aborted = true;
1806
+ } else {
1807
+ try {
1808
+ streamTask.model = entry.value;
1809
+ request.pendingChunks++;
1810
+ tryStreamTask(request, streamTask);
1811
+ enqueueFlush(request);
1812
+
1813
+ if (true) {
1814
+ callIteratorInDEV(iterator, progress, error);
1815
+ }
1816
+ } catch (x) {
1817
+ error(x);
1818
+ return;
1819
+ }
1820
+ }
1821
+ }
1822
+
1823
+ function error(reason) {
1824
+ if (aborted) {
1825
+ return;
1826
+ }
1827
+
1828
+ aborted = true;
1829
+ request.abortListeners.delete(error);
1830
+
1831
+ {
1832
+ var digest = logRecoverableError(request, reason);
1833
+ emitErrorChunk(request, streamTask.id, digest, reason);
1834
+ }
1835
+
1836
+ enqueueFlush(request);
1837
+
1838
+ if (typeof iterator.throw === 'function') {
1839
+ // The iterator protocol doesn't necessarily include this but a generator do.
1840
+ // $FlowFixMe should be able to pass mixed
1841
+ iterator.throw(reason).then(error, error);
1842
+ }
1843
+ }
1844
+
1845
+ request.abortListeners.add(error);
1846
+
1847
+ {
1848
+ callIteratorInDEV(iterator, progress, error);
1849
+ }
1850
+
1851
+ return serializeByValueID(streamTask.id);
1852
+ }
1853
+
1636
1854
  function emitHint(request, code, model) {
1637
1855
  emitHintChunk(request, code, model);
1638
1856
  enqueueFlush(request);
@@ -1704,15 +1922,44 @@ function createLazyWrapperAroundWakeable(wakeable) {
1704
1922
  }
1705
1923
 
1706
1924
  return lazyType;
1925
+ } // This indirect exists so we can exclude its stack frame in DEV (and anything below it).
1926
+
1927
+ /** @noinline */
1928
+
1929
+
1930
+ function callComponentInDEV(Component, props, componentDebugInfo) {
1931
+ // The secondArg is always undefined in Server Components since refs error early.
1932
+ var secondArg = undefined;
1933
+ setCurrentOwner(componentDebugInfo);
1934
+
1935
+ try {
1936
+ if (supportsComponentStorage) ; else {
1937
+ return Component(props, secondArg);
1938
+ }
1939
+ } finally {
1940
+ setCurrentOwner(null);
1941
+ }
1942
+ } // This indirect exists so we can exclude its stack frame in DEV (and anything below it).
1943
+
1944
+ /** @noinline */
1945
+
1946
+
1947
+ function callLazyInitInDEV(lazy) {
1948
+ var payload = lazy._payload;
1949
+ var init = lazy._init;
1950
+ return init(payload);
1707
1951
  }
1708
1952
 
1709
- function renderFunctionComponent(request, task, key, Component, props, owner) {
1953
+ function renderFunctionComponent(request, task, key, Component, props, owner, // DEV-only
1954
+ stack) // DEV-only
1955
+ {
1710
1956
  // Reset the task's thenable state before continuing, so that if a later
1711
1957
  // component suspends we can reuse the same task object. If the same
1712
1958
  // component suspends again, the thenable state will be restored.
1713
1959
  var prevThenableState = task.thenableState;
1714
1960
  task.thenableState = null;
1715
- var componentDebugInfo = null;
1961
+ var result;
1962
+ var componentDebugInfo;
1716
1963
 
1717
1964
  {
1718
1965
  if (debugID === null) {
@@ -1733,28 +1980,17 @@ function renderFunctionComponent(request, task, key, Component, props, owner) {
1733
1980
  name: componentName,
1734
1981
  env: request.environmentName,
1735
1982
  owner: owner
1736
- }; // We outline this model eagerly so that we can refer to by reference as an owner.
1983
+ };
1737
1984
  // If we had a smarter way to dedupe we might not have to do this if there ends up
1738
1985
  // being no references to this as an owner.
1739
1986
 
1987
+
1740
1988
  outlineModel(request, componentDebugInfo);
1741
1989
  emitDebugChunk(request, componentDebugID, componentDebugInfo);
1742
1990
  }
1743
- }
1744
-
1745
- prepareToUseHooksForComponent(prevThenableState, componentDebugInfo); // The secondArg is always undefined in Server Components since refs error early.
1746
-
1747
- var secondArg = undefined;
1748
- var result;
1749
-
1750
- {
1751
- ReactSharedInternals.owner = componentDebugInfo;
1752
1991
 
1753
- try {
1754
- result = Component(props, secondArg);
1755
- } finally {
1756
- ReactSharedInternals.owner = null;
1757
- }
1992
+ prepareToUseHooksForComponent(prevThenableState, componentDebugInfo);
1993
+ result = callComponentInDEV(Component, props, componentDebugInfo);
1758
1994
  }
1759
1995
 
1760
1996
  if (typeof result === 'object' && result !== null) {
@@ -1806,6 +2042,33 @@ function renderFunctionComponent(request, task, key, Component, props, owner) {
1806
2042
  {
1807
2043
  result._debugInfo = iterableChild._debugInfo;
1808
2044
  }
2045
+ } else if (typeof result[ASYNC_ITERATOR] === 'function' && (typeof ReadableStream !== 'function' || !(result instanceof ReadableStream))) {
2046
+ var _iterableChild = result;
2047
+ result = _defineProperty({}, ASYNC_ITERATOR, function () {
2048
+ var iterator = _iterableChild[ASYNC_ITERATOR]();
2049
+
2050
+ {
2051
+ // If this was an AsyncIterator but not an AsyncGeneratorFunction we warn because
2052
+ // it might have been a mistake. Technically you can make this mistake with
2053
+ // AsyncGeneratorFunctions and even single-shot AsyncIterables too but it's extra
2054
+ // tempting to try to return the value from a generator.
2055
+ if (iterator === _iterableChild) {
2056
+ var isGeneratorComponent = // $FlowIgnore[method-unbinding]
2057
+ Object.prototype.toString.call(Component) === '[object AsyncGeneratorFunction]' && // $FlowIgnore[method-unbinding]
2058
+ Object.prototype.toString.call(_iterableChild) === '[object AsyncGenerator]';
2059
+
2060
+ if (!isGeneratorComponent) {
2061
+ error('Returning an AsyncIterator from a Server Component is not supported ' + 'since it cannot be looped over more than once. ');
2062
+ }
2063
+ }
2064
+ }
2065
+
2066
+ return iterator;
2067
+ });
2068
+
2069
+ {
2070
+ result._debugInfo = _iterableChild._debugInfo;
2071
+ }
1809
2072
  }
1810
2073
  } // Track this element's key on the Server Component on the keyPath context..
1811
2074
 
@@ -1888,11 +2151,47 @@ function renderFragment(request, task, children) {
1888
2151
  return children;
1889
2152
  }
1890
2153
 
1891
- function renderClientElement(task, type, key, props, owner) // DEV-only
1892
- {
1893
- // the keys of any Server Components which are not serialized.
2154
+ function renderAsyncFragment(request, task, children, getAsyncIterator) {
2155
+ if (task.keyPath !== null) {
2156
+ // We have a Server Component that specifies a key but we're now splitting
2157
+ // the tree using a fragment.
2158
+ var fragment = [REACT_ELEMENT_TYPE, REACT_FRAGMENT_TYPE, task.keyPath, {
2159
+ children: children
2160
+ }];
2161
+
2162
+ if (!task.implicitSlot) {
2163
+ // If this was keyed inside a set. I.e. the outer Server Component was keyed
2164
+ // then we need to handle reorders of the whole set. To do this we need to wrap
2165
+ // this array in a keyed Fragment.
2166
+ return fragment;
2167
+ } // If the outer Server Component was implicit but then an inner one had a key
2168
+ // we don't actually need to be able to move the whole set around. It'll always be
2169
+ // in an implicit slot. The key only exists to be able to reset the state of the
2170
+ // children. We could achieve the same effect by passing on the keyPath to the next
2171
+ // set of components inside the fragment. This would also allow a keyless fragment
2172
+ // reconcile against a single child.
2173
+ // Unfortunately because of JSON.stringify, we can't call the recursive loop for
2174
+ // each child within this context because we can't return a set with already resolved
2175
+ // values. E.g. a string would get double encoded. Returning would pop the context.
2176
+ // So instead, we wrap it with an unkeyed fragment and inner keyed fragment.
2177
+
2178
+
2179
+ return [fragment];
2180
+ } // Since we're yielding here, that implicitly resets the keyPath context on the
2181
+ // way up. Which is what we want since we've consumed it. If this changes to
2182
+ // be recursive serialization, we need to reset the keyPath and implicitSlot,
2183
+ // before recursing here.
2184
+
1894
2185
 
2186
+ var asyncIterator = getAsyncIterator.call(children);
2187
+ return serializeAsyncIterable(request, task, children, asyncIterator);
2188
+ }
1895
2189
 
2190
+ function renderClientElement(task, type, key, props, owner, // DEV-only
2191
+ stack) // DEV-only
2192
+ {
2193
+ // We prepend the terminal client element that actually gets serialized with
2194
+ // the keys of any Server Components which are not serialized.
1896
2195
  var keyPath = task.keyPath;
1897
2196
 
1898
2197
  if (key === null) {
@@ -1939,7 +2238,8 @@ function outlineTask(request, task) {
1939
2238
  return serializeLazyID(newTask.id);
1940
2239
  }
1941
2240
 
1942
- function renderElement(request, task, type, key, ref, props, owner) // DEV only
2241
+ function renderElement(request, task, type, key, ref, props, owner, // DEV only
2242
+ stack) // DEV only
1943
2243
  {
1944
2244
  if (ref !== null && ref !== undefined) {
1945
2245
  // When the ref moves to the regular props object this will implicitly
@@ -1959,7 +2259,7 @@ function renderElement(request, task, type, key, ref, props, owner) // DEV only
1959
2259
  }
1960
2260
 
1961
2261
  if (typeof type === 'function') {
1962
- if (isClientReference(type) || isTemporaryReference(type)) {
2262
+ if (isClientReference(type) || isOpaqueTemporaryReference(type)) {
1963
2263
  // This is a reference to a Client Component.
1964
2264
  return renderClientElement(task, type, key, props, owner);
1965
2265
  } // This is a Server Component.
@@ -1996,9 +2296,12 @@ function renderElement(request, task, type, key, ref, props, owner) // DEV only
1996
2296
  switch (type.$$typeof) {
1997
2297
  case REACT_LAZY_TYPE:
1998
2298
  {
1999
- var payload = type._payload;
2000
- var init = type._init;
2001
- var wrappedType = init(payload);
2299
+ var wrappedType;
2300
+
2301
+ {
2302
+ wrappedType = callLazyInitInDEV(type);
2303
+ }
2304
+
2002
2305
  return renderElement(request, task, wrappedType, key, ref, props, owner);
2003
2306
  }
2004
2307
 
@@ -2036,8 +2339,8 @@ function createTask(request, model, keyPath, implicitSlot, abortSet) {
2036
2339
  if (typeof model === 'object' && model !== null) {
2037
2340
  // If we're about to write this into a new task we can assign it an ID early so that
2038
2341
  // any other references can refer to the value we're about to write.
2039
- if ((keyPath !== null || implicitSlot)) ; else {
2040
- request.writtenObjects.set(model, id);
2342
+ if (keyPath !== null || implicitSlot) ; else {
2343
+ request.writtenObjects.set(model, serializeByValueID(id));
2041
2344
  }
2042
2345
  }
2043
2346
 
@@ -2100,10 +2403,6 @@ function serializeServerReferenceID(id) {
2100
2403
  return '$F' + id.toString(16);
2101
2404
  }
2102
2405
 
2103
- function serializeTemporaryReferenceID(id) {
2104
- return '$T' + id;
2105
- }
2106
-
2107
2406
  function serializeSymbolReference(name) {
2108
2407
  return '$S' + name;
2109
2408
  }
@@ -2220,9 +2519,8 @@ function serializeServerReference(request, serverReference) {
2220
2519
  return serializeServerReferenceID(metadataId);
2221
2520
  }
2222
2521
 
2223
- function serializeTemporaryReference(request, temporaryReference) {
2224
- var id = resolveTemporaryReferenceID(temporaryReference);
2225
- return serializeTemporaryReferenceID(id);
2522
+ function serializeTemporaryReference(request, reference) {
2523
+ return '$T' + reference;
2226
2524
  }
2227
2525
 
2228
2526
  function serializeLargeTextString(request, text) {
@@ -2234,20 +2532,6 @@ function serializeLargeTextString(request, text) {
2234
2532
 
2235
2533
  function serializeMap(request, map) {
2236
2534
  var entries = Array.from(map);
2237
-
2238
- for (var i = 0; i < entries.length; i++) {
2239
- var key = entries[i][0];
2240
-
2241
- if (typeof key === 'object' && key !== null) {
2242
- var writtenObjects = request.writtenObjects;
2243
- var existingId = writtenObjects.get(key);
2244
-
2245
- if (existingId === undefined) {
2246
- writtenObjects.set(key, SEEN_BUT_NOT_YET_OUTLINED);
2247
- }
2248
- }
2249
- }
2250
-
2251
2535
  var id = outlineModel(request, entries);
2252
2536
  return '$Q' + id.toString(16);
2253
2537
  }
@@ -2260,20 +2544,6 @@ function serializeFormData(request, formData) {
2260
2544
 
2261
2545
  function serializeSet(request, set) {
2262
2546
  var entries = Array.from(set);
2263
-
2264
- for (var i = 0; i < entries.length; i++) {
2265
- var key = entries[i];
2266
-
2267
- if (typeof key === 'object' && key !== null) {
2268
- var writtenObjects = request.writtenObjects;
2269
- var existingId = writtenObjects.get(key);
2270
-
2271
- if (existingId === undefined) {
2272
- writtenObjects.set(key, SEEN_BUT_NOT_YET_OUTLINED);
2273
- }
2274
- }
2275
- }
2276
-
2277
2547
  var id = outlineModel(request, entries);
2278
2548
  return '$W' + id.toString(16);
2279
2549
  }
@@ -2283,6 +2553,58 @@ function serializeIterator(request, iterator) {
2283
2553
  return '$i' + id.toString(16);
2284
2554
  }
2285
2555
 
2556
+ function serializeTypedArray(request, tag, typedArray) {
2557
+ request.pendingChunks++;
2558
+ var bufferId = request.nextChunkId++;
2559
+ emitTypedArrayChunk(request, bufferId, tag, typedArray);
2560
+ return serializeByValueID(bufferId);
2561
+ }
2562
+
2563
+ function serializeBlob(request, blob) {
2564
+ var model = [blob.type];
2565
+ var newTask = createTask(request, model, null, false, request.abortableTasks);
2566
+ var reader = blob.stream().getReader();
2567
+ var aborted = false;
2568
+
2569
+ function progress(entry) {
2570
+ if (aborted) {
2571
+ return;
2572
+ }
2573
+
2574
+ if (entry.done) {
2575
+ request.abortListeners.delete(error);
2576
+ aborted = true;
2577
+ pingTask(request, newTask);
2578
+ return;
2579
+ } // TODO: Emit the chunk early and refer to it later by dedupe.
2580
+
2581
+
2582
+ model.push(entry.value); // $FlowFixMe[incompatible-call]
2583
+
2584
+ return reader.read().then(progress).catch(error);
2585
+ }
2586
+
2587
+ function error(reason) {
2588
+ if (aborted) {
2589
+ return;
2590
+ }
2591
+
2592
+ aborted = true;
2593
+ request.abortListeners.delete(error);
2594
+ var digest = logRecoverableError(request, reason);
2595
+ emitErrorChunk(request, newTask.id, digest, reason);
2596
+ request.abortableTasks.delete(newTask);
2597
+ enqueueFlush(request); // $FlowFixMe should be able to pass mixed
2598
+
2599
+ reader.cancel(reason).then(error, error);
2600
+ }
2601
+
2602
+ request.abortListeners.add(error); // $FlowFixMe[incompatible-call]
2603
+
2604
+ reader.read().then(progress).catch(error);
2605
+ return '$B' + newTask.id.toString(16);
2606
+ }
2607
+
2286
2608
  function escapeStringValue(value) {
2287
2609
  if (value[0] === '$') {
2288
2610
  // We need to escape $ prefixed strings since we use those to encode
@@ -2375,37 +2697,34 @@ function renderModelDestructive(request, task, parent, parentPropertyName, value
2375
2697
  {
2376
2698
  var _writtenObjects = request.writtenObjects;
2377
2699
 
2378
- var _existingId = _writtenObjects.get(value);
2379
-
2380
- if (_existingId !== undefined) {
2381
- if ((task.keyPath !== null || task.implicitSlot)) ; else if (modelRoot === value) {
2382
- // This is the ID we're currently emitting so we need to write it
2383
- // once but if we discover it again, we refer to it by id.
2384
- modelRoot = null;
2385
- } else if (_existingId === SEEN_BUT_NOT_YET_OUTLINED) {
2386
- // TODO: If we throw here we can treat this as suspending which causes an outline
2387
- // but that is able to reuse the same task if we're already in one but then that
2388
- // will be a lazy future value rather than guaranteed to exist but maybe that's good.
2389
- var newId = outlineModel(request, value);
2390
- return serializeByValueID(newId);
2391
- } else {
2392
- // We've already emitted this as an outlined object, so we can refer to that by its
2393
- // existing ID. TODO: We should use a lazy reference since, unlike plain objects,
2394
- // elements might suspend so it might not have emitted yet even if we have the ID for
2395
- // it. However, this creates an extra wrapper when it's not needed. We should really
2396
- // detect whether this already was emitted and synchronously available. In that
2397
- // case we can refer to it synchronously and only make it lazy otherwise.
2398
- // We currently don't have a data structure that lets us see that though.
2399
- return serializeByValueID(_existingId);
2400
- }
2401
- } else {
2402
- // This is the first time we've seen this object. We may never see it again
2403
- // so we'll inline it. Mark it as seen. If we see it again, we'll outline.
2404
- _writtenObjects.set(value, SEEN_BUT_NOT_YET_OUTLINED); // The element's props are marked as "never outlined" so that they are inlined into
2405
- // the same row as the element itself.
2406
-
2700
+ if (task.keyPath !== null || task.implicitSlot) ; else {
2701
+ var _existingReference = _writtenObjects.get(value);
2407
2702
 
2408
- _writtenObjects.set(value.props, NEVER_OUTLINED);
2703
+ if (_existingReference !== undefined) {
2704
+ if (modelRoot === value) {
2705
+ // This is the ID we're currently emitting so we need to write it
2706
+ // once but if we discover it again, we refer to it by id.
2707
+ modelRoot = null;
2708
+ } else {
2709
+ // We've already emitted this as an outlined object, so we can refer to that by its
2710
+ // existing ID. TODO: We should use a lazy reference since, unlike plain objects,
2711
+ // elements might suspend so it might not have emitted yet even if we have the ID for
2712
+ // it. However, this creates an extra wrapper when it's not needed. We should really
2713
+ // detect whether this already was emitted and synchronously available. In that
2714
+ // case we can refer to it synchronously and only make it lazy otherwise.
2715
+ // We currently don't have a data structure that lets us see that though.
2716
+ return _existingReference;
2717
+ }
2718
+ } else if (parentPropertyName.indexOf(':') === -1) {
2719
+ // TODO: If the property name contains a colon, we don't dedupe. Escape instead.
2720
+ var parentReference = _writtenObjects.get(parent);
2721
+
2722
+ if (parentReference !== undefined) {
2723
+ // If the parent has a reference, we can refer to this object indirectly
2724
+ // through the property name inside that parent.
2725
+ _writtenObjects.set(value, parentReference + ':' + parentPropertyName);
2726
+ }
2727
+ }
2409
2728
  }
2410
2729
 
2411
2730
  var element = value;
@@ -2448,9 +2767,11 @@ function renderModelDestructive(request, task, parent, parentPropertyName, value
2448
2767
  // from suspending the lazy before.
2449
2768
  task.thenableState = null;
2450
2769
  var lazy = value;
2451
- var payload = lazy._payload;
2452
- var init = lazy._init;
2453
- var resolvedModel = init(payload);
2770
+ var resolvedModel;
2771
+
2772
+ {
2773
+ resolvedModel = callLazyInitInDEV(lazy);
2774
+ }
2454
2775
 
2455
2776
  {
2456
2777
  var _debugInfo = lazy._debugInfo;
@@ -2472,18 +2793,31 @@ function renderModelDestructive(request, task, parent, parentPropertyName, value
2472
2793
 
2473
2794
  return renderModelDestructive(request, task, emptyRoot, '', resolvedModel);
2474
2795
  }
2796
+
2797
+ case REACT_LEGACY_ELEMENT_TYPE:
2798
+ {
2799
+ throw new Error('A React Element from an older version of React was rendered. ' + 'This is not supported. It can happen if:\n' + '- Multiple copies of the "react" package is used.\n' + '- A library pre-bundled an old copy of "react" or "react/jsx-runtime".\n' + '- A compiler tries to "inline" JSX instead of using the runtime.');
2800
+ }
2475
2801
  }
2476
2802
 
2477
2803
  if (isClientReference(value)) {
2478
2804
  return serializeClientReference(request, parent, parentPropertyName, value);
2479
2805
  }
2480
2806
 
2807
+ if (request.temporaryReferences !== undefined) {
2808
+ var tempRef = resolveTemporaryReference(request.temporaryReferences, value);
2809
+
2810
+ if (tempRef !== undefined) {
2811
+ return serializeTemporaryReference(request, tempRef);
2812
+ }
2813
+ }
2814
+
2481
2815
  var writtenObjects = request.writtenObjects;
2482
- var existingId = writtenObjects.get(value); // $FlowFixMe[method-unbinding]
2816
+ var existingReference = writtenObjects.get(value); // $FlowFixMe[method-unbinding]
2483
2817
 
2484
2818
  if (typeof value.then === 'function') {
2485
- if (existingId !== undefined) {
2486
- if ((task.keyPath !== null || task.implicitSlot)) {
2819
+ if (existingReference !== undefined) {
2820
+ if (task.keyPath !== null || task.implicitSlot) {
2487
2821
  // If we're in some kind of context we can't reuse the result of this render or
2488
2822
  // previous renders of this element. We only reuse Promises if they're not wrapped
2489
2823
  // by another Server Component.
@@ -2496,35 +2830,58 @@ function renderModelDestructive(request, task, parent, parentPropertyName, value
2496
2830
  modelRoot = null;
2497
2831
  } else {
2498
2832
  // We've seen this promise before, so we can just refer to the same result.
2499
- return serializePromiseID(existingId);
2833
+ return existingReference;
2500
2834
  }
2501
2835
  } // We assume that any object with a .then property is a "Thenable" type,
2502
2836
  // or a Promise type. Either of which can be represented by a Promise.
2503
2837
 
2504
2838
 
2505
2839
  var promiseId = serializeThenable(request, task, value);
2506
- writtenObjects.set(value, promiseId);
2507
- return serializePromiseID(promiseId);
2840
+ var promiseReference = serializePromiseID(promiseId);
2841
+ writtenObjects.set(value, promiseReference);
2842
+ return promiseReference;
2508
2843
  }
2509
2844
 
2510
- if (existingId !== undefined) {
2845
+ if (existingReference !== undefined) {
2511
2846
  if (modelRoot === value) {
2512
2847
  // This is the ID we're currently emitting so we need to write it
2513
2848
  // once but if we discover it again, we refer to it by id.
2514
2849
  modelRoot = null;
2515
- } else if (existingId === SEEN_BUT_NOT_YET_OUTLINED) {
2516
- var _newId = outlineModel(request, value);
2517
-
2518
- return serializeByValueID(_newId);
2519
- } else if (existingId !== NEVER_OUTLINED) {
2850
+ } else {
2520
2851
  // We've already emitted this as an outlined object, so we can
2521
2852
  // just refer to that by its existing ID.
2522
- return serializeByValueID(existingId);
2853
+ return existingReference;
2854
+ }
2855
+ } else if (parentPropertyName.indexOf(':') === -1) {
2856
+ // TODO: If the property name contains a colon, we don't dedupe. Escape instead.
2857
+ var _parentReference = writtenObjects.get(parent);
2858
+
2859
+ if (_parentReference !== undefined) {
2860
+ // If the parent has a reference, we can refer to this object indirectly
2861
+ // through the property name inside that parent.
2862
+ var propertyName = parentPropertyName;
2863
+
2864
+ if (isArray(parent) && parent[0] === REACT_ELEMENT_TYPE) {
2865
+ // For elements, we've converted it to an array but we'll have converted
2866
+ // it back to an element before we read the references so the property
2867
+ // needs to be aliased.
2868
+ switch (parentPropertyName) {
2869
+ case '1':
2870
+ propertyName = 'type';
2871
+ break;
2872
+
2873
+ case '2':
2874
+ propertyName = 'key';
2875
+ break;
2876
+
2877
+ case '3':
2878
+ propertyName = 'props';
2879
+ break;
2880
+ }
2881
+ }
2882
+
2883
+ writtenObjects.set(value, _parentReference + ':' + propertyName);
2523
2884
  }
2524
- } else {
2525
- // This is the first time we've seen this object. We may never see it again
2526
- // so we'll inline it. Mark it as seen. If we see it again, we'll outline.
2527
- writtenObjects.set(value, SEEN_BUT_NOT_YET_OUTLINED);
2528
2885
  }
2529
2886
 
2530
2887
  if (isArray(value)) {
@@ -2544,20 +2901,105 @@ function renderModelDestructive(request, task, parent, parentPropertyName, value
2544
2901
  return serializeFormData(request, value);
2545
2902
  }
2546
2903
 
2547
- var iteratorFn = getIteratorFn(value);
2904
+ {
2905
+ if (value instanceof ArrayBuffer) {
2906
+ return serializeTypedArray(request, 'A', new Uint8Array(value));
2907
+ }
2548
2908
 
2549
- if (iteratorFn) {
2550
- // TODO: Should we serialize the return value as well like we do for AsyncIterables?
2551
- var iterator = iteratorFn.call(value);
2909
+ if (value instanceof Int8Array) {
2910
+ // char
2911
+ return serializeTypedArray(request, 'O', value);
2912
+ }
2552
2913
 
2553
- if (iterator === value) {
2554
- // Iterator, not Iterable
2555
- return serializeIterator(request, iterator);
2914
+ if (value instanceof Uint8Array) {
2915
+ // unsigned char
2916
+ return serializeTypedArray(request, 'o', value);
2917
+ }
2918
+
2919
+ if (value instanceof Uint8ClampedArray) {
2920
+ // unsigned clamped char
2921
+ return serializeTypedArray(request, 'U', value);
2922
+ }
2923
+
2924
+ if (value instanceof Int16Array) {
2925
+ // sort
2926
+ return serializeTypedArray(request, 'S', value);
2927
+ }
2928
+
2929
+ if (value instanceof Uint16Array) {
2930
+ // unsigned short
2931
+ return serializeTypedArray(request, 's', value);
2932
+ }
2933
+
2934
+ if (value instanceof Int32Array) {
2935
+ // long
2936
+ return serializeTypedArray(request, 'L', value);
2937
+ }
2938
+
2939
+ if (value instanceof Uint32Array) {
2940
+ // unsigned long
2941
+ return serializeTypedArray(request, 'l', value);
2942
+ }
2943
+
2944
+ if (value instanceof Float32Array) {
2945
+ // float
2946
+ return serializeTypedArray(request, 'G', value);
2947
+ }
2948
+
2949
+ if (value instanceof Float64Array) {
2950
+ // double
2951
+ return serializeTypedArray(request, 'g', value);
2952
+ }
2953
+
2954
+ if (value instanceof BigInt64Array) {
2955
+ // number
2956
+ return serializeTypedArray(request, 'M', value);
2957
+ }
2958
+
2959
+ if (value instanceof BigUint64Array) {
2960
+ // unsigned number
2961
+ // We use "m" instead of "n" since JSON can start with "null"
2962
+ return serializeTypedArray(request, 'm', value);
2963
+ }
2964
+
2965
+ if (value instanceof DataView) {
2966
+ return serializeTypedArray(request, 'V', value);
2967
+ } // TODO: Blob is not available in old Node. Remove the typeof check later.
2968
+
2969
+
2970
+ if (typeof Blob === 'function' && value instanceof Blob) {
2971
+ return serializeBlob(request, value);
2972
+ }
2973
+ }
2974
+
2975
+ var iteratorFn = getIteratorFn(value);
2976
+
2977
+ if (iteratorFn) {
2978
+ // TODO: Should we serialize the return value as well like we do for AsyncIterables?
2979
+ var iterator = iteratorFn.call(value);
2980
+
2981
+ if (iterator === value) {
2982
+ // Iterator, not Iterable
2983
+ return serializeIterator(request, iterator);
2556
2984
  }
2557
2985
 
2558
2986
  return renderFragment(request, task, Array.from(iterator));
2559
2987
  }
2560
2988
 
2989
+ {
2990
+ // TODO: Blob is not available in old Node. Remove the typeof check later.
2991
+ if (typeof ReadableStream === 'function' && value instanceof ReadableStream) {
2992
+ return serializeReadableStream(request, task, value);
2993
+ }
2994
+
2995
+ var getAsyncIterator = value[ASYNC_ITERATOR];
2996
+
2997
+ if (typeof getAsyncIterator === 'function') {
2998
+ // We treat AsyncIterables as a Fragment and as such we might need to key them.
2999
+ return renderAsyncFragment(request, task, value, getAsyncIterator);
3000
+ }
3001
+ } // Verify that this is a simple plain object.
3002
+
2561
3003
 
2562
3004
  var proto = getPrototypeOf(value);
2563
3005
 
@@ -2627,11 +3069,17 @@ function renderModelDestructive(request, task, parent, parentPropertyName, value
2627
3069
  return serializeServerReference(request, value);
2628
3070
  }
2629
3071
 
2630
- if (isTemporaryReference(value)) {
2631
- return serializeTemporaryReference(request, value);
3072
+ if (request.temporaryReferences !== undefined) {
3073
+ var _tempRef = resolveTemporaryReference(request.temporaryReferences, value);
3074
+
3075
+ if (_tempRef !== undefined) {
3076
+ return serializeTemporaryReference(request, _tempRef);
3077
+ }
2632
3078
  }
2633
3079
 
2634
- if (/^on[A-Z]/.test(parentPropertyName)) {
3080
+ if (isOpaqueTemporaryReference(value)) {
3081
+ throw new Error('Could not reference an opaque temporary reference. ' + 'This is likely due to misconfiguring the temporaryReferences options ' + 'on the server.');
3082
+ } else if (/^on[A-Z]/.test(parentPropertyName)) {
2635
3083
  throw new Error('Event handlers cannot be passed to Client Component props.' + describeObjectForErrorMessage(parent, parentPropertyName) + '\nIf you need interactivity, consider converting part of this to a Client Component.');
2636
3084
  } else if ((jsxChildrenParents.has(parent) || jsxPropsParents.has(parent) && parentPropertyName === 'children')) {
2637
3085
  var componentName = value.displayName || value.name || 'Component';
@@ -2643,11 +3091,10 @@ function renderModelDestructive(request, task, parent, parentPropertyName, value
2643
3091
 
2644
3092
  if (typeof value === 'symbol') {
2645
3093
  var writtenSymbols = request.writtenSymbols;
3094
+ var existingId = writtenSymbols.get(value);
2646
3095
 
2647
- var _existingId2 = writtenSymbols.get(value);
2648
-
2649
- if (_existingId2 !== undefined) {
2650
- return serializeByValueID(_existingId2);
3096
+ if (existingId !== undefined) {
3097
+ return serializeByValueID(existingId);
2651
3098
  } // $FlowFixMe[incompatible-type] `description` might be undefined
2652
3099
 
2653
3100
 
@@ -2829,6 +3276,18 @@ function emitDebugChunk(request, id, debugInfo) {
2829
3276
  request.completedRegularChunks.push(processedChunk);
2830
3277
  }
2831
3278
 
3279
+ function emitTypedArrayChunk(request, id, tag, typedArray) {
3280
+
3281
+ request.pendingChunks++; // Extra chunk for the header.
3282
+ // TODO: Convert to little endian if that's not the server default.
3283
+
3284
+ var binaryChunk = typedArrayToBinaryChunk(typedArray);
3285
+ var binaryLength = byteLengthOfBinaryChunk(binaryChunk);
3286
+ var row = id.toString(16) + ':' + tag + binaryLength.toString(16) + ',';
3287
+ var headerChunk = stringToChunk(row);
3288
+ request.completedRegularChunks.push(headerChunk, binaryChunk);
3289
+ }
3290
+
2832
3291
  function emitTextChunk(request, id, text) {
2833
3292
  request.pendingChunks++; // Extra chunk for the header.
2834
3293
 
@@ -2864,6 +3323,14 @@ function renderConsoleValue(request, counter, parent, parentPropertyName, value)
2864
3323
  return serializeClientReference(request, parent, parentPropertyName, value);
2865
3324
  }
2866
3325
 
3326
+ if (request.temporaryReferences !== undefined) {
3327
+ var tempRef = resolveTemporaryReference(request.temporaryReferences, value);
3328
+
3329
+ if (tempRef !== undefined) {
3330
+ return serializeTemporaryReference(request, tempRef);
3331
+ }
3332
+ }
3333
+
2867
3334
  if (counter.objectCount > 20) {
2868
3335
  // We've reached our max number of objects to serialize across the wire so we serialize this
2869
3336
  // object but no properties inside of it, as a place holder.
@@ -2872,12 +3339,12 @@ function renderConsoleValue(request, counter, parent, parentPropertyName, value)
2872
3339
 
2873
3340
  counter.objectCount++;
2874
3341
  var writtenObjects = request.writtenObjects;
2875
- var existingId = writtenObjects.get(value); // $FlowFixMe[method-unbinding]
3342
+ var existingReference = writtenObjects.get(value); // $FlowFixMe[method-unbinding]
2876
3343
 
2877
3344
  if (typeof value.then === 'function') {
2878
- if (existingId !== undefined) {
3345
+ if (existingReference !== undefined) {
2879
3346
  // We've seen this promise before, so we can just refer to the same result.
2880
- return serializePromiseID(existingId);
3347
+ return existingReference;
2881
3348
  }
2882
3349
 
2883
3350
  var thenable = value;
@@ -2909,10 +3376,10 @@ function renderConsoleValue(request, counter, parent, parentPropertyName, value)
2909
3376
  return serializeInfinitePromise();
2910
3377
  }
2911
3378
 
2912
- if (existingId !== undefined && existingId >= 0) {
3379
+ if (existingReference !== undefined) {
2913
3380
  // We've already emitted this as a real object, so we can
2914
- // just refer to that by its existing ID.
2915
- return serializeByValueID(existingId);
3381
+ // just refer to that by its existing reference.
3382
+ return existingReference;
2916
3383
  }
2917
3384
 
2918
3385
  if (isArray(value)) {
@@ -2932,6 +3399,77 @@ function renderConsoleValue(request, counter, parent, parentPropertyName, value)
2932
3399
  return serializeFormData(request, value);
2933
3400
  }
2934
3401
 
3402
+ {
3403
+ if (value instanceof ArrayBuffer) {
3404
+ return serializeTypedArray(request, 'A', new Uint8Array(value));
3405
+ }
3406
+
3407
+ if (value instanceof Int8Array) {
3408
+ // char
3409
+ return serializeTypedArray(request, 'O', value);
3410
+ }
3411
+
3412
+ if (value instanceof Uint8Array) {
3413
+ // unsigned char
3414
+ return serializeTypedArray(request, 'o', value);
3415
+ }
3416
+
3417
+ if (value instanceof Uint8ClampedArray) {
3418
+ // unsigned clamped char
3419
+ return serializeTypedArray(request, 'U', value);
3420
+ }
3421
+
3422
+ if (value instanceof Int16Array) {
3423
+ // sort
3424
+ return serializeTypedArray(request, 'S', value);
3425
+ }
3426
+
3427
+ if (value instanceof Uint16Array) {
3428
+ // unsigned short
3429
+ return serializeTypedArray(request, 's', value);
3430
+ }
3431
+
3432
+ if (value instanceof Int32Array) {
3433
+ // long
3434
+ return serializeTypedArray(request, 'L', value);
3435
+ }
3436
+
3437
+ if (value instanceof Uint32Array) {
3438
+ // unsigned long
3439
+ return serializeTypedArray(request, 'l', value);
3440
+ }
3441
+
3442
+ if (value instanceof Float32Array) {
3443
+ // float
3444
+ return serializeTypedArray(request, 'G', value);
3445
+ }
3446
+
3447
+ if (value instanceof Float64Array) {
3448
+ // double
3449
+ return serializeTypedArray(request, 'g', value);
3450
+ }
3451
+
3452
+ if (value instanceof BigInt64Array) {
3453
+ // number
3454
+ return serializeTypedArray(request, 'M', value);
3455
+ }
3456
+
3457
+ if (value instanceof BigUint64Array) {
3458
+ // unsigned number
3459
+ // We use "m" instead of "n" since JSON can start with "null"
3460
+ return serializeTypedArray(request, 'm', value);
3461
+ }
3462
+
3463
+ if (value instanceof DataView) {
3464
+ return serializeTypedArray(request, 'V', value);
3465
+ } // TODO: Blob is not available in old Node. Remove the typeof check later.
3466
+
3467
+
3468
+ if (typeof Blob === 'function' && value instanceof Blob) {
3469
+ return serializeBlob(request, value);
3470
+ }
3471
+ }
3472
+
2935
3473
  var iteratorFn = getIteratorFn(value);
2936
3474
 
2937
3475
  if (iteratorFn) {
@@ -2977,8 +3515,12 @@ function renderConsoleValue(request, counter, parent, parentPropertyName, value)
2977
3515
  return serializeClientReference(request, parent, parentPropertyName, value);
2978
3516
  }
2979
3517
 
2980
- if (isTemporaryReference(value)) {
2981
- return serializeTemporaryReference(request, value);
3518
+ if (request.temporaryReferences !== undefined) {
3519
+ var _tempRef2 = resolveTemporaryReference(request.temporaryReferences, value);
3520
+
3521
+ if (_tempRef2 !== undefined) {
3522
+ return serializeTemporaryReference(request, _tempRef2);
3523
+ }
2982
3524
  } // Serialize the body of the function as an eval so it can be printed.
2983
3525
  // $FlowFixMe[method-unbinding]
2984
3526
 
@@ -2988,11 +3530,10 @@ function renderConsoleValue(request, counter, parent, parentPropertyName, value)
2988
3530
 
2989
3531
  if (typeof value === 'symbol') {
2990
3532
  var writtenSymbols = request.writtenSymbols;
3533
+ var existingId = writtenSymbols.get(value);
2991
3534
 
2992
- var _existingId3 = writtenSymbols.get(value);
2993
-
2994
- if (_existingId3 !== undefined) {
2995
- return serializeByValueID(_existingId3);
3535
+ if (existingId !== undefined) {
3536
+ return serializeByValueID(existingId);
2996
3537
  } // $FlowFixMe[incompatible-type] `description` might be undefined
2997
3538
 
2998
3539
 
@@ -3047,6 +3588,85 @@ function emitChunk(request, task, value) {
3047
3588
  emitTextChunk(request, id, value);
3048
3589
  return;
3049
3590
  }
3591
+
3592
+ {
3593
+ if (value instanceof ArrayBuffer) {
3594
+ emitTypedArrayChunk(request, id, 'A', new Uint8Array(value));
3595
+ return;
3596
+ }
3597
+
3598
+ if (value instanceof Int8Array) {
3599
+ // char
3600
+ emitTypedArrayChunk(request, id, 'O', value);
3601
+ return;
3602
+ }
3603
+
3604
+ if (value instanceof Uint8Array) {
3605
+ // unsigned char
3606
+ emitTypedArrayChunk(request, id, 'o', value);
3607
+ return;
3608
+ }
3609
+
3610
+ if (value instanceof Uint8ClampedArray) {
3611
+ // unsigned clamped char
3612
+ emitTypedArrayChunk(request, id, 'U', value);
3613
+ return;
3614
+ }
3615
+
3616
+ if (value instanceof Int16Array) {
3617
+ // sort
3618
+ emitTypedArrayChunk(request, id, 'S', value);
3619
+ return;
3620
+ }
3621
+
3622
+ if (value instanceof Uint16Array) {
3623
+ // unsigned short
3624
+ emitTypedArrayChunk(request, id, 's', value);
3625
+ return;
3626
+ }
3627
+
3628
+ if (value instanceof Int32Array) {
3629
+ // long
3630
+ emitTypedArrayChunk(request, id, 'L', value);
3631
+ return;
3632
+ }
3633
+
3634
+ if (value instanceof Uint32Array) {
3635
+ // unsigned long
3636
+ emitTypedArrayChunk(request, id, 'l', value);
3637
+ return;
3638
+ }
3639
+
3640
+ if (value instanceof Float32Array) {
3641
+ // float
3642
+ emitTypedArrayChunk(request, id, 'G', value);
3643
+ return;
3644
+ }
3645
+
3646
+ if (value instanceof Float64Array) {
3647
+ // double
3648
+ emitTypedArrayChunk(request, id, 'g', value);
3649
+ return;
3650
+ }
3651
+
3652
+ if (value instanceof BigInt64Array) {
3653
+ // number
3654
+ emitTypedArrayChunk(request, id, 'M', value);
3655
+ return;
3656
+ }
3657
+
3658
+ if (value instanceof BigUint64Array) {
3659
+ // unsigned number
3660
+ // We use "m" instead of "n" since JSON can start with "null"
3661
+ emitTypedArrayChunk(request, id, 'm', value);
3662
+ return;
3663
+ }
3664
+
3665
+ if (value instanceof DataView) {
3666
+ emitTypedArrayChunk(request, id, 'V', value);
3667
+ return;
3668
+ }
3669
+ } // For anything else we need to try to serialize it using JSON.
3050
3670
  // $FlowFixMe[incompatible-type] stringify can return null for undefined but we never do
3051
3671
 
3052
3672
 
@@ -3092,8 +3712,11 @@ function retryTask(request, task) {
3092
3712
  task.implicitSlot = false;
3093
3713
 
3094
3714
  if (typeof resolvedModel === 'object' && resolvedModel !== null) {
3095
- // Object might contain unresolved values like additional elements.
3715
+ // We're not in a contextual place here so we can refer to this object by this ID for
3716
+ // any future references.
3717
+ request.writtenObjects.set(resolvedModel, serializeByValueID(task.id)); // Object might contain unresolved values like additional elements.
3096
3718
  // This is simulating what the JSON loop would do if this was part of it.
3719
+
3097
3720
  emitChunk(request, task, resolvedModel);
3098
3721
  } else {
3099
3722
  // If the value is a string, it means it's a terminal value and we already escaped it
@@ -3135,6 +3758,26 @@ function retryTask(request, task) {
3135
3758
  }
3136
3759
  }
3137
3760
 
3761
+ function tryStreamTask(request, task) {
3762
+ // This is used to try to emit something synchronously but if it suspends,
3763
+ // we emit a reference to a new outlined task immediately instead.
3764
+ var prevDebugID = debugID;
3765
+
3766
+ {
3767
+ // We don't use the id of the stream task for debugID. Instead we leave it null
3768
+ // so that we instead outline the row to get a new debugID if needed.
3769
+ debugID = null;
3770
+ }
3771
+
3772
+ try {
3773
+ emitChunk(request, task, task.model);
3774
+ } finally {
3775
+ {
3776
+ debugID = prevDebugID;
3777
+ }
3778
+ }
3779
+ }
3780
+
3138
3781
  function performWork(request) {
3139
3782
  var prevDispatcher = ReactSharedInternals.H;
3140
3783
  ReactSharedInternals.H = HooksDispatcher;
@@ -3524,9 +4167,12 @@ function loadChunk(chunkId, filename) {
3524
4167
  return __webpack_chunk_load__(chunkId);
3525
4168
  }
3526
4169
 
3527
- // The server acts as a Client of itself when resolving Server References.
4170
+ // $FlowFixMe[method-unbinding]
4171
+ var hasOwnProperty = Object.prototype.hasOwnProperty;
4172
+
3528
4173
  var PENDING = 'pending';
3529
4174
  var BLOCKED = 'blocked';
4175
+ var CYCLIC = 'cyclic';
3530
4176
  var RESOLVED_MODEL = 'resolved_model';
3531
4177
  var INITIALIZED = 'fulfilled';
3532
4178
  var ERRORED = 'rejected'; // $FlowFixMe[missing-this-annot]
@@ -3559,6 +4205,7 @@ Chunk.prototype.then = function (resolve, reject) {
3559
4205
 
3560
4206
  case PENDING:
3561
4207
  case BLOCKED:
4208
+ case CYCLIC:
3562
4209
  if (resolve) {
3563
4210
  if (chunk.value === null) {
3564
4211
  chunk.value = [];
@@ -3600,9 +4247,39 @@ function wakeChunk(listeners, value) {
3600
4247
  }
3601
4248
  }
3602
4249
 
4250
+ function wakeChunkIfInitialized(chunk, resolveListeners, rejectListeners) {
4251
+ switch (chunk.status) {
4252
+ case INITIALIZED:
4253
+ wakeChunk(resolveListeners, chunk.value);
4254
+ break;
4255
+
4256
+ case PENDING:
4257
+ case BLOCKED:
4258
+ case CYCLIC:
4259
+ chunk.value = resolveListeners;
4260
+ chunk.reason = rejectListeners;
4261
+ break;
4262
+
4263
+ case ERRORED:
4264
+ if (rejectListeners) {
4265
+ wakeChunk(rejectListeners, chunk.reason);
4266
+ }
4267
+
4268
+ break;
4269
+ }
4270
+ }
4271
+
3603
4272
  function triggerErrorOnChunk(chunk, error) {
3604
4273
  if (chunk.status !== PENDING && chunk.status !== BLOCKED) {
3605
- // We already resolved. We didn't expect to see this.
4274
+ {
4275
+ // If we get more data to an already resolved ID, we assume that it's
4276
+ // a stream chunk since any other row shouldn't have more than one entry.
4277
+ var streamChunk = chunk;
4278
+ var controller = streamChunk.reason; // $FlowFixMe[incompatible-call]: The error method should accept mixed.
4279
+
4280
+ controller.error(error);
4281
+ }
4282
+
3606
4283
  return;
3607
4284
  }
3608
4285
 
@@ -3616,9 +4293,64 @@ function triggerErrorOnChunk(chunk, error) {
3616
4293
  }
3617
4294
  }
3618
4295
 
3619
- function createResolvedModelChunk(response, value) {
4296
+ function createResolvedModelChunk(response, value, id) {
3620
4297
  // $FlowFixMe[invalid-constructor] Flow doesn't support functions as constructors
3621
- return new Chunk(RESOLVED_MODEL, value, null, response);
4298
+ return new Chunk(RESOLVED_MODEL, value, id, response);
4299
+ }
4300
+
4301
+ function resolveModelChunk(chunk, value, id) {
4302
+ if (chunk.status !== PENDING) {
4303
+ {
4304
+ // If we get more data to an already resolved ID, we assume that it's
4305
+ // a stream chunk since any other row shouldn't have more than one entry.
4306
+ var streamChunk = chunk;
4307
+ var controller = streamChunk.reason;
4308
+
4309
+ if (value[0] === 'C') {
4310
+ controller.close(value === 'C' ? '"$undefined"' : value.slice(1));
4311
+ } else {
4312
+ controller.enqueueModel(value);
4313
+ }
4314
+ }
4315
+
4316
+ return;
4317
+ }
4318
+
4319
+ var resolveListeners = chunk.value;
4320
+ var rejectListeners = chunk.reason;
4321
+ var resolvedChunk = chunk;
4322
+ resolvedChunk.status = RESOLVED_MODEL;
4323
+ resolvedChunk.value = value;
4324
+ resolvedChunk.reason = id;
4325
+
4326
+ if (resolveListeners !== null) {
4327
+ // This is unfortunate that we're reading this eagerly if
4328
+ // we already have listeners attached since they might no
4329
+ // longer be rendered or might not be the highest pri.
4330
+ initializeModelChunk(resolvedChunk); // The status might have changed after initialization.
4331
+
4332
+ wakeChunkIfInitialized(chunk, resolveListeners, rejectListeners);
4333
+ }
4334
+ }
4335
+
4336
+ function createInitializedStreamChunk(response, value, controller) {
4337
+ // We use the reason field to stash the controller since we already have that
4338
+ // field. It's a bit of a hack but efficient.
4339
+ // $FlowFixMe[invalid-constructor] Flow doesn't support functions as constructors
4340
+ return new Chunk(INITIALIZED, value, controller, response);
4341
+ }
4342
+
4343
+ function createResolvedIteratorResultChunk(response, value, done) {
4344
+ // To reuse code as much code as possible we add the wrapper element as part of the JSON.
4345
+ var iteratorResultJSON = (done ? '{"done":true,"value":' : '{"done":false,"value":') + value + '}'; // $FlowFixMe[invalid-constructor] Flow doesn't support functions as constructors
4346
+
4347
+ return new Chunk(RESOLVED_MODEL, iteratorResultJSON, -1, response);
4348
+ }
4349
+
4350
+ function resolveIteratorResultChunk(chunk, value, done) {
4351
+ // To reuse code as much code as possible we add the wrapper element as part of the JSON.
4352
+ var iteratorResultJSON = (done ? '{"done":true,"value":' : '{"done":false,"value":') + value + '}';
4353
+ resolveModelChunk(chunk, iteratorResultJSON, -1);
3622
4354
  }
3623
4355
 
3624
4356
  function bindArgs$1(fn, args) {
@@ -3649,11 +4381,51 @@ function loadServerReference$1(response, id, bound, parentChunk, parentObject, k
3649
4381
  }
3650
4382
  }
3651
4383
 
3652
- promise.then(createModelResolver(parentChunk, parentObject, key), createModelReject(parentChunk)); // We need a placeholder value that will be replaced later.
4384
+ promise.then(createModelResolver(parentChunk, parentObject, key, false, response, createModel, []), createModelReject(parentChunk)); // We need a placeholder value that will be replaced later.
3653
4385
 
3654
4386
  return null;
3655
4387
  }
3656
4388
 
4389
+ function reviveModel(response, parentObj, parentKey, value, reference) {
4390
+ if (typeof value === 'string') {
4391
+ // We can't use .bind here because we need the "this" value.
4392
+ return parseModelString(response, parentObj, parentKey, value, reference);
4393
+ }
4394
+
4395
+ if (typeof value === 'object' && value !== null) {
4396
+ if (reference !== undefined && response._temporaryReferences !== undefined) {
4397
+ // Store this object's reference in case it's returned later.
4398
+ registerTemporaryReference(response._temporaryReferences, value, reference);
4399
+ }
4400
+
4401
+ if (Array.isArray(value)) {
4402
+ for (var i = 0; i < value.length; i++) {
4403
+ var childRef = reference !== undefined ? reference + ':' + i : undefined; // $FlowFixMe[cannot-write]
4404
+
4405
+ value[i] = reviveModel(response, value, '' + i, value[i], childRef);
4406
+ }
4407
+ } else {
4408
+ for (var key in value) {
4409
+ if (hasOwnProperty.call(value, key)) {
4410
+ var _childRef = reference !== undefined && key.indexOf(':') === -1 ? reference + ':' + key : undefined;
4411
+
4412
+ var newValue = reviveModel(response, value, key, value[key], _childRef);
4413
+
4414
+ if (newValue !== undefined) {
4415
+ // $FlowFixMe[cannot-write]
4416
+ value[key] = newValue;
4417
+ } else {
4418
+ // $FlowFixMe[cannot-write]
4419
+ delete value[key];
4420
+ }
4421
+ }
4422
+ }
4423
+ }
4424
+ }
4425
+
4426
+ return value;
4427
+ }
4428
+
3657
4429
  var initializingChunk = null;
3658
4430
  var initializingChunkBlockedModel = null;
3659
4431
 
@@ -3662,9 +4434,21 @@ function initializeModelChunk(chunk) {
3662
4434
  var prevBlocked = initializingChunkBlockedModel;
3663
4435
  initializingChunk = chunk;
3664
4436
  initializingChunkBlockedModel = null;
4437
+ var rootReference = chunk.reason === -1 ? undefined : chunk.reason.toString(16);
4438
+ var resolvedModel = chunk.value; // We go to the CYCLIC state until we've fully resolved this.
4439
+ // We do this before parsing in case we try to initialize the same chunk
4440
+ // while parsing the model. Such as in a cyclic reference.
4441
+
4442
+ var cyclicChunk = chunk;
4443
+ cyclicChunk.status = CYCLIC;
4444
+ cyclicChunk.value = null;
4445
+ cyclicChunk.reason = null;
3665
4446
 
3666
4447
  try {
3667
- var value = JSON.parse(chunk.value, chunk._response._fromJSON);
4448
+ var rawModel = JSON.parse(resolvedModel);
4449
+ var value = reviveModel(chunk._response, {
4450
+ '': rawModel
4451
+ }, '', rawModel, rootReference);
3668
4452
 
3669
4453
  if (initializingChunkBlockedModel !== null && initializingChunkBlockedModel.deps > 0) {
3670
4454
  initializingChunkBlockedModel.value = value; // We discovered new dependencies on modules that are not yet resolved.
@@ -3675,9 +4459,14 @@ function initializeModelChunk(chunk) {
3675
4459
  blockedChunk.value = null;
3676
4460
  blockedChunk.reason = null;
3677
4461
  } else {
4462
+ var resolveListeners = cyclicChunk.value;
3678
4463
  var initializedChunk = chunk;
3679
4464
  initializedChunk.status = INITIALIZED;
3680
4465
  initializedChunk.value = value;
4466
+
4467
+ if (resolveListeners !== null) {
4468
+ wakeChunk(resolveListeners, value);
4469
+ }
3681
4470
  }
3682
4471
  } catch (error) {
3683
4472
  var erroredChunk = chunk;
@@ -3714,7 +4503,7 @@ function getChunk(response, id) {
3714
4503
 
3715
4504
  if (backingEntry != null) {
3716
4505
  // We assume that this is a string entry for now.
3717
- chunk = createResolvedModelChunk(response, backingEntry);
4506
+ chunk = createResolvedModelChunk(response, backingEntry, id);
3718
4507
  } else {
3719
4508
  // We're still waiting on this entry to stream in.
3720
4509
  chunk = createPendingChunk(response);
@@ -3726,21 +4515,34 @@ function getChunk(response, id) {
3726
4515
  return chunk;
3727
4516
  }
3728
4517
 
3729
- function createModelResolver(chunk, parentObject, key) {
4518
+ function createModelResolver(chunk, parentObject, key, cyclic, response, map, path) {
3730
4519
  var blocked;
3731
4520
 
3732
4521
  if (initializingChunkBlockedModel) {
3733
4522
  blocked = initializingChunkBlockedModel;
3734
- blocked.deps++;
4523
+
4524
+ if (!cyclic) {
4525
+ blocked.deps++;
4526
+ }
3735
4527
  } else {
3736
4528
  blocked = initializingChunkBlockedModel = {
3737
- deps: 1,
4529
+ deps: cyclic ? 0 : 1,
3738
4530
  value: null
3739
4531
  };
3740
4532
  }
3741
4533
 
3742
4534
  return function (value) {
3743
- parentObject[key] = value;
4535
+ for (var i = 1; i < path.length; i++) {
4536
+ value = value[path[i]];
4537
+ }
4538
+
4539
+ parentObject[key] = map(response, value); // If this is the root object for a model reference, where `blocked.value`
4540
+ // is a stale `null`, the resolved value can be used directly.
4541
+
4542
+ if (key === '' && blocked.value === null) {
4543
+ blocked.value = parentObject[key];
4544
+ }
4545
+
3744
4546
  blocked.deps--;
3745
4547
 
3746
4548
  if (blocked.deps === 0) {
@@ -3766,22 +4568,271 @@ function createModelReject(chunk) {
3766
4568
  };
3767
4569
  }
3768
4570
 
3769
- function getOutlinedModel(response, id) {
4571
+ function getOutlinedModel(response, reference, parentObject, key, map) {
4572
+ var path = reference.split(':');
4573
+ var id = parseInt(path[0], 16);
3770
4574
  var chunk = getChunk(response, id);
3771
4575
 
3772
- if (chunk.status === RESOLVED_MODEL) {
3773
- initializeModelChunk(chunk);
4576
+ switch (chunk.status) {
4577
+ case RESOLVED_MODEL:
4578
+ initializeModelChunk(chunk);
4579
+ break;
4580
+ } // The status might have changed after initialization.
4581
+
4582
+
4583
+ switch (chunk.status) {
4584
+ case INITIALIZED:
4585
+ var value = chunk.value;
4586
+
4587
+ for (var i = 1; i < path.length; i++) {
4588
+ value = value[path[i]];
4589
+ }
4590
+
4591
+ return map(response, value);
4592
+
4593
+ case PENDING:
4594
+ case BLOCKED:
4595
+ case CYCLIC:
4596
+ var parentChunk = initializingChunk;
4597
+ chunk.then(createModelResolver(parentChunk, parentObject, key, chunk.status === CYCLIC, response, map, path), createModelReject(parentChunk));
4598
+ return null;
4599
+
4600
+ default:
4601
+ throw chunk.reason;
3774
4602
  }
4603
+ }
4604
+
4605
+ function createMap(response, model) {
4606
+ return new Map(model);
4607
+ }
4608
+
4609
+ function createSet(response, model) {
4610
+ return new Set(model);
4611
+ }
4612
+
4613
+ function extractIterator(response, model) {
4614
+ // $FlowFixMe[incompatible-use]: This uses raw Symbols because we're extracting from a native array.
4615
+ return model[Symbol.iterator]();
4616
+ }
4617
+
4618
+ function createModel(response, model) {
4619
+ return model;
4620
+ }
4621
+
4622
+ function parseTypedArray(response, reference, constructor, bytesPerElement, parentObject, parentKey) {
4623
+ var id = parseInt(reference.slice(2), 16);
4624
+ var prefix = response._prefix;
4625
+ var key = prefix + id; // We should have this backingEntry in the store already because we emitted
4626
+ // it before referencing it. It should be a Blob.
4627
+
4628
+ var backingEntry = response._formData.get(key);
4629
+
4630
+ var promise = constructor === ArrayBuffer ? backingEntry.arrayBuffer() : backingEntry.arrayBuffer().then(function (buffer) {
4631
+ return new constructor(buffer);
4632
+ }); // Since loading the buffer is an async operation we'll be blocking the parent
4633
+ // chunk.
4634
+
4635
+ var parentChunk = initializingChunk;
4636
+ promise.then(createModelResolver(parentChunk, parentObject, parentKey, false, response, createModel, []), createModelReject(parentChunk));
4637
+ return null;
4638
+ }
4639
+
4640
+ function resolveStream(response, id, stream, controller) {
4641
+ var chunks = response._chunks;
4642
+ var chunk = createInitializedStreamChunk(response, stream, controller);
4643
+ chunks.set(id, chunk);
4644
+ var prefix = response._prefix;
4645
+ var key = prefix + id;
4646
+
4647
+ var existingEntries = response._formData.getAll(key);
3775
4648
 
3776
- if (chunk.status !== INITIALIZED) {
3777
- // We know that this is emitted earlier so otherwise it's an error.
3778
- throw chunk.reason;
4649
+ for (var i = 0; i < existingEntries.length; i++) {
4650
+ // We assume that this is a string entry for now.
4651
+ var value = existingEntries[i];
4652
+
4653
+ if (value[0] === 'C') {
4654
+ controller.close(value === 'C' ? '"$undefined"' : value.slice(1));
4655
+ } else {
4656
+ controller.enqueueModel(value);
4657
+ }
3779
4658
  }
4659
+ }
4660
+
4661
+ function parseReadableStream(response, reference, type, parentObject, parentKey) {
4662
+ var id = parseInt(reference.slice(2), 16);
4663
+ var controller = null;
4664
+ var stream = new ReadableStream({
4665
+ type: type,
4666
+ start: function (c) {
4667
+ controller = c;
4668
+ }
4669
+ });
4670
+ var previousBlockedChunk = null;
4671
+ var flightController = {
4672
+ enqueueModel: function (json) {
4673
+ if (previousBlockedChunk === null) {
4674
+ // If we're not blocked on any other chunks, we can try to eagerly initialize
4675
+ // this as a fast-path to avoid awaiting them.
4676
+ var chunk = createResolvedModelChunk(response, json, -1);
4677
+ initializeModelChunk(chunk);
4678
+ var initializedChunk = chunk;
3780
4679
 
3781
- return chunk.value;
4680
+ if (initializedChunk.status === INITIALIZED) {
4681
+ controller.enqueue(initializedChunk.value);
4682
+ } else {
4683
+ chunk.then(function (v) {
4684
+ return controller.enqueue(v);
4685
+ }, function (e) {
4686
+ return controller.error(e);
4687
+ });
4688
+ previousBlockedChunk = chunk;
4689
+ }
4690
+ } else {
4691
+ // We're still waiting on a previous chunk so we can't enqueue quite yet.
4692
+ var blockedChunk = previousBlockedChunk;
4693
+
4694
+ var _chunk = createPendingChunk(response);
4695
+
4696
+ _chunk.then(function (v) {
4697
+ return controller.enqueue(v);
4698
+ }, function (e) {
4699
+ return controller.error(e);
4700
+ });
4701
+
4702
+ previousBlockedChunk = _chunk;
4703
+ blockedChunk.then(function () {
4704
+ if (previousBlockedChunk === _chunk) {
4705
+ // We were still the last chunk so we can now clear the queue and return
4706
+ // to synchronous emitting.
4707
+ previousBlockedChunk = null;
4708
+ }
4709
+
4710
+ resolveModelChunk(_chunk, json, -1);
4711
+ });
4712
+ }
4713
+ },
4714
+ close: function (json) {
4715
+ if (previousBlockedChunk === null) {
4716
+ controller.close();
4717
+ } else {
4718
+ var blockedChunk = previousBlockedChunk; // We shouldn't get any more enqueues after this so we can set it back to null.
4719
+
4720
+ previousBlockedChunk = null;
4721
+ blockedChunk.then(function () {
4722
+ return controller.close();
4723
+ });
4724
+ }
4725
+ },
4726
+ error: function (error) {
4727
+ if (previousBlockedChunk === null) {
4728
+ // $FlowFixMe[incompatible-call]
4729
+ controller.error(error);
4730
+ } else {
4731
+ var blockedChunk = previousBlockedChunk; // We shouldn't get any more enqueues after this so we can set it back to null.
4732
+
4733
+ previousBlockedChunk = null;
4734
+ blockedChunk.then(function () {
4735
+ return controller.error(error);
4736
+ });
4737
+ }
4738
+ }
4739
+ };
4740
+ resolveStream(response, id, stream, flightController);
4741
+ return stream;
3782
4742
  }
3783
4743
 
3784
- function parseModelString(response, obj, key, value) {
4744
+ function asyncIterator() {
4745
+ // Self referencing iterator.
4746
+ return this;
4747
+ }
4748
+
4749
+ function createIterator(next) {
4750
+ var iterator = {
4751
+ next: next // TODO: Add return/throw as options for aborting.
4752
+
4753
+ }; // TODO: The iterator could inherit the AsyncIterator prototype which is not exposed as
4754
+ // a global but exists as a prototype of an AsyncGenerator. However, it's not needed
4755
+ // to satisfy the iterable protocol.
4756
+
4757
+ iterator[ASYNC_ITERATOR] = asyncIterator;
4758
+ return iterator;
4759
+ }
4760
+
4761
+ function parseAsyncIterable(response, reference, iterator, parentObject, parentKey) {
4762
+ var id = parseInt(reference.slice(2), 16);
4763
+ var buffer = [];
4764
+ var closed = false;
4765
+ var nextWriteIndex = 0;
4766
+ var flightController = {
4767
+ enqueueModel: function (value) {
4768
+ if (nextWriteIndex === buffer.length) {
4769
+ buffer[nextWriteIndex] = createResolvedIteratorResultChunk(response, value, false);
4770
+ } else {
4771
+ resolveIteratorResultChunk(buffer[nextWriteIndex], value, false);
4772
+ }
4773
+
4774
+ nextWriteIndex++;
4775
+ },
4776
+ close: function (value) {
4777
+ closed = true;
4778
+
4779
+ if (nextWriteIndex === buffer.length) {
4780
+ buffer[nextWriteIndex] = createResolvedIteratorResultChunk(response, value, true);
4781
+ } else {
4782
+ resolveIteratorResultChunk(buffer[nextWriteIndex], value, true);
4783
+ }
4784
+
4785
+ nextWriteIndex++;
4786
+
4787
+ while (nextWriteIndex < buffer.length) {
4788
+ // In generators, any extra reads from the iterator have the value undefined.
4789
+ resolveIteratorResultChunk(buffer[nextWriteIndex++], '"$undefined"', true);
4790
+ }
4791
+ },
4792
+ error: function (error) {
4793
+ closed = true;
4794
+
4795
+ if (nextWriteIndex === buffer.length) {
4796
+ buffer[nextWriteIndex] = createPendingChunk(response);
4797
+ }
4798
+
4799
+ while (nextWriteIndex < buffer.length) {
4800
+ triggerErrorOnChunk(buffer[nextWriteIndex++], error);
4801
+ }
4802
+ }
4803
+ };
4804
+
4805
+ var iterable = _defineProperty({}, ASYNC_ITERATOR, function () {
4806
+ var nextReadIndex = 0;
4807
+ return createIterator(function (arg) {
4808
+ if (arg !== undefined) {
4809
+ throw new Error('Values cannot be passed to next() of AsyncIterables passed to Client Components.');
4810
+ }
4811
+
4812
+ if (nextReadIndex === buffer.length) {
4813
+ if (closed) {
4814
+ // $FlowFixMe[invalid-constructor] Flow doesn't support functions as constructors
4815
+ return new Chunk(INITIALIZED, {
4816
+ done: true,
4817
+ value: undefined
4818
+ }, null, response);
4819
+ }
4820
+
4821
+ buffer[nextReadIndex] = createPendingChunk(response);
4822
+ }
4823
+
4824
+ return buffer[nextReadIndex++];
4825
+ });
4826
+ }); // TODO: If it's a single shot iterator we can optimize memory by cleaning up the buffer after
4827
+ // reading through the end, but currently we favor code size over this optimization.
4828
+
4829
+
4830
+ var stream = iterator ? iterable[ASYNC_ITERATOR]() : iterable;
4831
+ resolveStream(response, id, stream, flightController);
4832
+ return stream;
4833
+ }
4834
+
4835
+ function parseModelString(response, obj, key, value, reference) {
3785
4836
  if (value[0] === '$') {
3786
4837
  switch (value[1]) {
3787
4838
  case '$':
@@ -3793,46 +4844,45 @@ function parseModelString(response, obj, key, value) {
3793
4844
  case '@':
3794
4845
  {
3795
4846
  // Promise
3796
- var _id = parseInt(value.slice(2), 16);
3797
-
3798
- var _chunk = getChunk(response, _id);
3799
-
3800
- return _chunk;
4847
+ var id = parseInt(value.slice(2), 16);
4848
+ var chunk = getChunk(response, id);
4849
+ return chunk;
3801
4850
  }
3802
4851
 
3803
4852
  case 'F':
3804
4853
  {
3805
4854
  // Server Reference
3806
- var _id2 = parseInt(value.slice(2), 16); // TODO: Just encode this in the reference inline instead of as a model.
4855
+ var _ref2 = value.slice(2); // TODO: Just encode this in the reference inline instead of as a model.
3807
4856
 
3808
4857
 
3809
- var metaData = getOutlinedModel(response, _id2);
4858
+ var metaData = getOutlinedModel(response, _ref2, obj, key, createModel);
3810
4859
  return loadServerReference$1(response, metaData.id, metaData.bound, initializingChunk, obj, key);
3811
4860
  }
3812
4861
 
3813
4862
  case 'T':
3814
4863
  {
3815
4864
  // Temporary Reference
3816
- return createTemporaryReference(value.slice(2));
4865
+ if (reference === undefined || response._temporaryReferences === undefined) {
4866
+ throw new Error('Could not reference an opaque temporary reference. ' + 'This is likely due to misconfiguring the temporaryReferences options ' + 'on the server.');
4867
+ }
4868
+
4869
+ return createTemporaryReference(response._temporaryReferences, reference);
3817
4870
  }
3818
4871
 
3819
4872
  case 'Q':
3820
4873
  {
3821
4874
  // Map
3822
- var _id3 = parseInt(value.slice(2), 16);
4875
+ var _ref3 = value.slice(2);
3823
4876
 
3824
- var data = getOutlinedModel(response, _id3);
3825
- return new Map(data);
4877
+ return getOutlinedModel(response, _ref3, obj, key, createMap);
3826
4878
  }
3827
4879
 
3828
4880
  case 'W':
3829
4881
  {
3830
4882
  // Set
3831
- var _id4 = parseInt(value.slice(2), 16);
3832
-
3833
- var _data = getOutlinedModel(response, _id4);
4883
+ var _ref4 = value.slice(2);
3834
4884
 
3835
- return new Set(_data);
4885
+ return getOutlinedModel(response, _ref4, obj, key, createSet);
3836
4886
  }
3837
4887
 
3838
4888
  case 'K':
@@ -3840,9 +4890,7 @@ function parseModelString(response, obj, key, value) {
3840
4890
  // FormData
3841
4891
  var stringId = value.slice(2);
3842
4892
  var formPrefix = response._prefix + stringId + '_';
3843
-
3844
- var _data2 = new FormData();
3845
-
4893
+ var data = new FormData();
3846
4894
  var backingFormData = response._formData; // We assume that the reference to FormData always comes after each
3847
4895
  // entry that it references so we can assume they all exist in the
3848
4896
  // backing store already.
@@ -3850,20 +4898,18 @@ function parseModelString(response, obj, key, value) {
3850
4898
 
3851
4899
  backingFormData.forEach(function (entry, entryKey) {
3852
4900
  if (entryKey.startsWith(formPrefix)) {
3853
- _data2.append(entryKey.slice(formPrefix.length), entry);
4901
+ data.append(entryKey.slice(formPrefix.length), entry);
3854
4902
  }
3855
4903
  });
3856
- return _data2;
4904
+ return data;
3857
4905
  }
3858
4906
 
3859
4907
  case 'i':
3860
4908
  {
3861
4909
  // Iterator
3862
- var _id5 = parseInt(value.slice(2), 16);
3863
-
3864
- var _data3 = getOutlinedModel(response, _id5);
4910
+ var _ref5 = value.slice(2);
3865
4911
 
3866
- return _data3[Symbol.iterator]();
4912
+ return getOutlinedModel(response, _ref5, obj, key, extractIterator);
3867
4913
  }
3868
4914
 
3869
4915
  case 'I':
@@ -3908,51 +4954,104 @@ function parseModelString(response, obj, key, value) {
3908
4954
  }
3909
4955
  }
3910
4956
 
4957
+ {
4958
+ switch (value[1]) {
4959
+ case 'A':
4960
+ return parseTypedArray(response, value, ArrayBuffer, 1, obj, key);
3911
4961
 
3912
- var id = parseInt(value.slice(1), 16);
3913
- var chunk = getChunk(response, id);
4962
+ case 'O':
4963
+ return parseTypedArray(response, value, Int8Array, 1, obj, key);
3914
4964
 
3915
- switch (chunk.status) {
3916
- case RESOLVED_MODEL:
3917
- initializeModelChunk(chunk);
3918
- break;
3919
- } // The status might have changed after initialization.
4965
+ case 'o':
4966
+ return parseTypedArray(response, value, Uint8Array, 1, obj, key);
3920
4967
 
4968
+ case 'U':
4969
+ return parseTypedArray(response, value, Uint8ClampedArray, 1, obj, key);
4970
+
4971
+ case 'S':
4972
+ return parseTypedArray(response, value, Int16Array, 2, obj, key);
4973
+
4974
+ case 's':
4975
+ return parseTypedArray(response, value, Uint16Array, 2, obj, key);
4976
+
4977
+ case 'L':
4978
+ return parseTypedArray(response, value, Int32Array, 4, obj, key);
4979
+
4980
+ case 'l':
4981
+ return parseTypedArray(response, value, Uint32Array, 4, obj, key);
4982
+
4983
+ case 'G':
4984
+ return parseTypedArray(response, value, Float32Array, 4, obj, key);
4985
+
4986
+ case 'g':
4987
+ return parseTypedArray(response, value, Float64Array, 8, obj, key);
4988
+
4989
+ case 'M':
4990
+ return parseTypedArray(response, value, BigInt64Array, 8, obj, key);
4991
+
4992
+ case 'm':
4993
+ return parseTypedArray(response, value, BigUint64Array, 8, obj, key);
4994
+
4995
+ case 'V':
4996
+ return parseTypedArray(response, value, DataView, 1, obj, key);
4997
+
4998
+ case 'B':
4999
+ {
5000
+ // Blob
5001
+ var _id = parseInt(value.slice(2), 16);
3921
5002
 
3922
- switch (chunk.status) {
3923
- case INITIALIZED:
3924
- return chunk.value;
5003
+ var prefix = response._prefix;
5004
+ var blobKey = prefix + _id; // We should have this backingEntry in the store already because we emitted
5005
+ // it before referencing it. It should be a Blob.
3925
5006
 
3926
- case PENDING:
3927
- case BLOCKED:
3928
- var parentChunk = initializingChunk;
3929
- chunk.then(createModelResolver(parentChunk, obj, key), createModelReject(parentChunk));
3930
- return null;
5007
+ var backingEntry = response._formData.get(blobKey);
3931
5008
 
3932
- default:
3933
- throw chunk.reason;
5009
+ return backingEntry;
5010
+ }
5011
+ }
3934
5012
  }
5013
+
5014
+ {
5015
+ switch (value[1]) {
5016
+ case 'R':
5017
+ {
5018
+ return parseReadableStream(response, value, undefined);
5019
+ }
5020
+
5021
+ case 'r':
5022
+ {
5023
+ return parseReadableStream(response, value, 'bytes');
5024
+ }
5025
+
5026
+ case 'X':
5027
+ {
5028
+ return parseAsyncIterable(response, value, false);
5029
+ }
5030
+
5031
+ case 'x':
5032
+ {
5033
+ return parseAsyncIterable(response, value, true);
5034
+ }
5035
+ }
5036
+ } // We assume that anything else is a reference ID.
5037
+
5038
+
5039
+ var ref = value.slice(1);
5040
+ return getOutlinedModel(response, ref, obj, key, createModel);
3935
5041
  }
3936
5042
 
3937
5043
  return value;
3938
5044
  }
3939
5045
 
3940
- function createResponse(bundlerConfig, formFieldPrefix) {
3941
- var backingFormData = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : new FormData();
5046
+ function createResponse(bundlerConfig, formFieldPrefix, temporaryReferences) {
5047
+ var backingFormData = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : new FormData();
3942
5048
  var chunks = new Map();
3943
5049
  var response = {
3944
5050
  _bundlerConfig: bundlerConfig,
3945
5051
  _prefix: formFieldPrefix,
3946
5052
  _formData: backingFormData,
3947
5053
  _chunks: chunks,
3948
- _fromJSON: function (key, value) {
3949
- if (typeof value === 'string') {
3950
- // We can't use .bind here because we need the "this" value.
3951
- return parseModelString(response, this, key, value);
3952
- }
3953
-
3954
- return value;
3955
- }
5054
+ _temporaryReferences: temporaryReferences
3956
5055
  };
3957
5056
  return response;
3958
5057
  }
@@ -3992,7 +5091,7 @@ function loadServerReference(bundlerConfig, id, bound) {
3992
5091
 
3993
5092
  function decodeBoundActionMetaData(body, serverManifest, formFieldPrefix) {
3994
5093
  // The data for this reference is encoded in multiple fields under this prefix.
3995
- var actionResponse = createResponse(serverManifest, formFieldPrefix, body);
5094
+ var actionResponse = createResponse(serverManifest, formFieldPrefix, undefined, body);
3996
5095
  close(actionResponse);
3997
5096
  var refPromise = getRoot(actionResponse); // Force it to initialize
3998
5097
  // $FlowFixMe
@@ -4087,7 +5186,7 @@ function decodeFormState(actionResult, body, serverManifest) {
4087
5186
  }
4088
5187
 
4089
5188
  function renderToReadableStream(model, webpackMap, options) {
4090
- var request = createRequest(model, webpackMap, options ? options.onError : undefined, options ? options.identifierPrefix : undefined, options ? options.onPostpone : undefined, options ? options.environmentName : undefined);
5189
+ var request = createRequest(model, webpackMap, options ? options.onError : undefined, options ? options.identifierPrefix : undefined, options ? options.onPostpone : undefined, options ? options.environmentName : undefined, options ? options.temporaryReferences : undefined);
4091
5190
 
4092
5191
  if (options && options.signal) {
4093
5192
  var signal = options.signal;
@@ -4123,20 +5222,21 @@ function renderToReadableStream(model, webpackMap, options) {
4123
5222
  return stream;
4124
5223
  }
4125
5224
 
4126
- function decodeReply(body, webpackMap) {
5225
+ function decodeReply(body, webpackMap, options) {
4127
5226
  if (typeof body === 'string') {
4128
5227
  var form = new FormData();
4129
5228
  form.append('0', body);
4130
5229
  body = form;
4131
5230
  }
4132
5231
 
4133
- var response = createResponse(webpackMap, '', body);
5232
+ var response = createResponse(webpackMap, '', options ? options.temporaryReferences : undefined, body);
4134
5233
  var root = getRoot(response);
4135
5234
  close(response);
4136
5235
  return root;
4137
5236
  }
4138
5237
 
4139
5238
  exports.createClientModuleProxy = createClientModuleProxy;
5239
+ exports.createTemporaryReferenceSet = createTemporaryReferenceSet;
4140
5240
  exports.decodeAction = decodeAction;
4141
5241
  exports.decodeFormState = decodeFormState;
4142
5242
  exports.decodeReply = decodeReply;