react-server-dom-webpack 19.0.0-canary-cf5ab8b8b2-20240425 → 19.0.0-rc-3f1436cca1-20240516

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') {
@@ -764,7 +777,9 @@ function createHints() {
764
777
  }
765
778
 
766
779
  var supportsRequestStorage = typeof AsyncLocalStorage === 'function';
767
- var requestStorage = supportsRequestStorage ? new AsyncLocalStorage() : null; // We use the Node version but get access to async_hooks from a global.
780
+ var requestStorage = supportsRequestStorage ? new AsyncLocalStorage() : null;
781
+ var supportsComponentStorage = supportsRequestStorage;
782
+ var componentStorage = supportsComponentStorage ? new AsyncLocalStorage() : null; // We use the Node version but get access to async_hooks from a global.
768
783
 
769
784
  typeof async_hooks === 'object' ? async_hooks.createHook : function () {
770
785
  return {
@@ -776,11 +791,14 @@ typeof async_hooks === 'object' ? async_hooks.executionAsyncId : null;
776
791
 
777
792
  var TEMPORARY_REFERENCE_TAG = Symbol.for('react.temporary.reference'); // eslint-disable-next-line no-unused-vars
778
793
 
779
- function isTemporaryReference(reference) {
794
+ function createTemporaryReferenceSet() {
795
+ return new WeakMap();
796
+ }
797
+ function isOpaqueTemporaryReference(reference) {
780
798
  return reference.$$typeof === TEMPORARY_REFERENCE_TAG;
781
799
  }
782
- function resolveTemporaryReferenceID(temporaryReference) {
783
- return temporaryReference.$$id;
800
+ function resolveTemporaryReference(temporaryReferences, temporaryReference) {
801
+ return temporaryReferences.get(temporaryReference);
784
802
  }
785
803
  var proxyHandlers = {
786
804
  get: function (target, name, receiver) {
@@ -791,12 +809,6 @@ var proxyHandlers = {
791
809
  // have the Flight runtime extract the inner target instead.
792
810
  return target.$$typeof;
793
811
 
794
- case '$$id':
795
- return target.$$id;
796
-
797
- case '$$async':
798
- return target.$$async;
799
-
800
812
  case 'name':
801
813
  return undefined;
802
814
 
@@ -831,21 +843,28 @@ var proxyHandlers = {
831
843
  throw new Error('Cannot assign to a temporary client reference from a server module.');
832
844
  }
833
845
  };
834
- function createTemporaryReference(id) {
846
+ function createTemporaryReference(temporaryReferences, id) {
835
847
  var reference = Object.defineProperties(function () {
836
848
  throw new Error( // eslint-disable-next-line react-internal/safe-string-coercion
837
849
  "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.");
838
850
  }, {
839
851
  $$typeof: {
840
852
  value: TEMPORARY_REFERENCE_TAG
841
- },
842
- $$id: {
843
- value: id
844
853
  }
845
854
  });
846
- return new Proxy(reference, proxyHandlers);
855
+ var wrapper = new Proxy(reference, proxyHandlers);
856
+ registerTemporaryReference(temporaryReferences, wrapper, id);
857
+ return wrapper;
847
858
  }
859
+ function registerTemporaryReference(temporaryReferences, object, id) {
860
+ temporaryReferences.set(object, id);
861
+ }
862
+
863
+ // When adding new symbols to this file,
864
+ // Please consider also adding to 'react-devtools-shared/src/backend/ReactSymbols'
865
+ // The Symbol used to tag the ReactElement-like types.
848
866
 
867
+ var REACT_LEGACY_ELEMENT_TYPE = Symbol.for('react.element');
849
868
  var REACT_ELEMENT_TYPE = Symbol.for('react.transitional.element') ;
850
869
  var REACT_FRAGMENT_TYPE = Symbol.for('react.fragment');
851
870
  var REACT_CONTEXT_TYPE = Symbol.for('react.context');
@@ -871,6 +890,7 @@ function getIteratorFn(maybeIterable) {
871
890
 
872
891
  return null;
873
892
  }
893
+ var ASYNC_ITERATOR = Symbol.asyncIterator;
874
894
 
875
895
  // Corresponds to ReactFiberWakeable and ReactFizzWakeable modules. Generally,
876
896
  // changes to one module should be reflected in the others.
@@ -1119,6 +1139,21 @@ function use(usable) {
1119
1139
  }
1120
1140
  }
1121
1141
 
1142
+ var currentOwner = null;
1143
+ function setCurrentOwner(componentInfo) {
1144
+ currentOwner = componentInfo;
1145
+ }
1146
+ function resolveOwner() {
1147
+ if (currentOwner) return currentOwner;
1148
+
1149
+ if (supportsComponentStorage) {
1150
+ var owner = componentStorage.getStore();
1151
+ if (owner) return owner;
1152
+ }
1153
+
1154
+ return null;
1155
+ }
1156
+
1122
1157
  function resolveCache() {
1123
1158
  var request = resolveRequest();
1124
1159
 
@@ -1129,7 +1164,7 @@ function resolveCache() {
1129
1164
  return new Map();
1130
1165
  }
1131
1166
 
1132
- var DefaultCacheDispatcher = {
1167
+ var DefaultAsyncDispatcher = {
1133
1168
  getCacheForType: function (resourceType) {
1134
1169
  var cache = resolveCache();
1135
1170
  var entry = cache.get(resourceType);
@@ -1144,6 +1179,10 @@ var DefaultCacheDispatcher = {
1144
1179
  }
1145
1180
  };
1146
1181
 
1182
+ {
1183
+ DefaultAsyncDispatcher.getOwner = resolveOwner;
1184
+ }
1185
+
1147
1186
  var isArrayImpl = Array.isArray; // eslint-disable-next-line no-redeclare
1148
1187
 
1149
1188
  function isArray(a) {
@@ -1492,10 +1531,7 @@ var stringify = JSON.stringify; // Serializable values
1492
1531
  var PENDING$1 = 0;
1493
1532
  var COMPLETED = 1;
1494
1533
  var ABORTED = 3;
1495
- var ERRORED$1 = 4; // object reference status
1496
-
1497
- var SEEN_BUT_NOT_YET_OUTLINED = -1;
1498
- var NEVER_OUTLINED = -2;
1534
+ var ERRORED$1 = 4;
1499
1535
 
1500
1536
  function defaultErrorHandler(error) {
1501
1537
  console['error'](error); // Don't transform to our wrapper
@@ -1507,12 +1543,12 @@ function defaultPostponeHandler(reason) {// Noop
1507
1543
  var OPEN = 0;
1508
1544
  var CLOSING = 1;
1509
1545
  var CLOSED = 2;
1510
- function createRequest(model, bundlerConfig, onError, identifierPrefix, onPostpone, environmentName) {
1511
- if (ReactSharedInternals.C !== null && ReactSharedInternals.C !== DefaultCacheDispatcher) {
1546
+ function createRequest(model, bundlerConfig, onError, identifierPrefix, onPostpone, environmentName, temporaryReferences) {
1547
+ if (ReactSharedInternals.A !== null && ReactSharedInternals.A !== DefaultAsyncDispatcher) {
1512
1548
  throw new Error('Currently React only supports one RSC renderer at a time.');
1513
1549
  }
1514
1550
 
1515
- ReactSharedInternals.C = DefaultCacheDispatcher;
1551
+ ReactSharedInternals.A = DefaultAsyncDispatcher;
1516
1552
  var abortSet = new Set();
1517
1553
  var pingedTasks = [];
1518
1554
  var cleanupQueue = [];
@@ -1539,6 +1575,7 @@ function createRequest(model, bundlerConfig, onError, identifierPrefix, onPostpo
1539
1575
  writtenClientReferences: new Map(),
1540
1576
  writtenServerReferences: new Map(),
1541
1577
  writtenObjects: new WeakMap(),
1578
+ temporaryReferences: temporaryReferences,
1542
1579
  identifierPrefix: identifierPrefix || '',
1543
1580
  identifierCount: 1,
1544
1581
  taintCleanupQueue: cleanupQueue,
@@ -1646,6 +1683,192 @@ function serializeThenable(request, task, thenable) {
1646
1683
  return newTask.id;
1647
1684
  }
1648
1685
 
1686
+ function serializeReadableStream(request, task, stream) {
1687
+ // Detect if this is a BYOB stream. BYOB streams should be able to be read as bytes on the
1688
+ // receiving side. It also implies that different chunks can be split up or merged as opposed
1689
+ // to a readable stream that happens to have Uint8Array as the type which might expect it to be
1690
+ // received in the same slices.
1691
+ // $FlowFixMe: This is a Node.js extension.
1692
+ var supportsBYOB = stream.supportsBYOB;
1693
+
1694
+ if (supportsBYOB === undefined) {
1695
+ try {
1696
+ // $FlowFixMe[extra-arg]: This argument is accepted.
1697
+ stream.getReader({
1698
+ mode: 'byob'
1699
+ }).releaseLock();
1700
+ supportsBYOB = true;
1701
+ } catch (x) {
1702
+ supportsBYOB = false;
1703
+ }
1704
+ }
1705
+
1706
+ var reader = stream.getReader(); // This task won't actually be retried. We just use it to attempt synchronous renders.
1707
+
1708
+ var streamTask = createTask(request, task.model, task.keyPath, task.implicitSlot, request.abortableTasks);
1709
+ request.abortableTasks.delete(streamTask);
1710
+ request.pendingChunks++; // The task represents the Start row. This adds a Stop row.
1711
+
1712
+ var startStreamRow = streamTask.id.toString(16) + ':' + (supportsBYOB ? 'r' : 'R') + '\n';
1713
+ request.completedRegularChunks.push(stringToChunk(startStreamRow)); // There's a race condition between when the stream is aborted and when the promise
1714
+ // resolves so we track whether we already aborted it to avoid writing twice.
1715
+
1716
+ var aborted = false;
1717
+
1718
+ function progress(entry) {
1719
+ if (aborted) {
1720
+ return;
1721
+ }
1722
+
1723
+ if (entry.done) {
1724
+ request.abortListeners.delete(error);
1725
+ var endStreamRow = streamTask.id.toString(16) + ':C\n';
1726
+ request.completedRegularChunks.push(stringToChunk(endStreamRow));
1727
+ enqueueFlush(request);
1728
+ aborted = true;
1729
+ } else {
1730
+ try {
1731
+ streamTask.model = entry.value;
1732
+ request.pendingChunks++;
1733
+ tryStreamTask(request, streamTask);
1734
+ enqueueFlush(request);
1735
+ reader.read().then(progress, error);
1736
+ } catch (x) {
1737
+ error(x);
1738
+ }
1739
+ }
1740
+ }
1741
+
1742
+ function error(reason) {
1743
+ if (aborted) {
1744
+ return;
1745
+ }
1746
+
1747
+ aborted = true;
1748
+ request.abortListeners.delete(error);
1749
+
1750
+ {
1751
+ var digest = logRecoverableError(request, reason);
1752
+ emitErrorChunk(request, streamTask.id, digest, reason);
1753
+ }
1754
+
1755
+ enqueueFlush(request); // $FlowFixMe should be able to pass mixed
1756
+
1757
+ reader.cancel(reason).then(error, error);
1758
+ }
1759
+
1760
+ request.abortListeners.add(error);
1761
+ reader.read().then(progress, error);
1762
+ return serializeByValueID(streamTask.id);
1763
+ } // This indirect exists so we can exclude its stack frame in DEV (and anything below it).
1764
+
1765
+ /** @noinline */
1766
+
1767
+
1768
+ function callIteratorInDEV(iterator, progress, error) {
1769
+ iterator.next().then(progress, error);
1770
+ }
1771
+
1772
+ function serializeAsyncIterable(request, task, iterable, iterator) {
1773
+ // Generators/Iterators are Iterables but they're also their own iterator
1774
+ // functions. If that's the case, we treat them as single-shot. Otherwise,
1775
+ // we assume that this iterable might be a multi-shot and allow it to be
1776
+ // iterated more than once on the client.
1777
+ var isIterator = iterable === iterator; // This task won't actually be retried. We just use it to attempt synchronous renders.
1778
+
1779
+ var streamTask = createTask(request, task.model, task.keyPath, task.implicitSlot, request.abortableTasks);
1780
+ request.abortableTasks.delete(streamTask);
1781
+ request.pendingChunks++; // The task represents the Start row. This adds a Stop row.
1782
+
1783
+ var startStreamRow = streamTask.id.toString(16) + ':' + (isIterator ? 'x' : 'X') + '\n';
1784
+ request.completedRegularChunks.push(stringToChunk(startStreamRow));
1785
+
1786
+ {
1787
+ var debugInfo = iterable._debugInfo;
1788
+
1789
+ if (debugInfo) {
1790
+ forwardDebugInfo(request, streamTask.id, debugInfo);
1791
+ }
1792
+ } // There's a race condition between when the stream is aborted and when the promise
1793
+ // resolves so we track whether we already aborted it to avoid writing twice.
1794
+
1795
+
1796
+ var aborted = false;
1797
+
1798
+ function progress(entry) {
1799
+ if (aborted) {
1800
+ return;
1801
+ }
1802
+
1803
+ if (entry.done) {
1804
+ request.abortListeners.delete(error);
1805
+ var endStreamRow;
1806
+
1807
+ if (entry.value === undefined) {
1808
+ endStreamRow = streamTask.id.toString(16) + ':C\n';
1809
+ } else {
1810
+ // Unlike streams, the last value may not be undefined. If it's not
1811
+ // we outline it and encode a reference to it in the closing instruction.
1812
+ try {
1813
+ var chunkId = outlineModel(request, entry.value);
1814
+ endStreamRow = streamTask.id.toString(16) + ':C' + stringify(serializeByValueID(chunkId)) + '\n';
1815
+ } catch (x) {
1816
+ error(x);
1817
+ return;
1818
+ }
1819
+ }
1820
+
1821
+ request.completedRegularChunks.push(stringToChunk(endStreamRow));
1822
+ enqueueFlush(request);
1823
+ aborted = true;
1824
+ } else {
1825
+ try {
1826
+ streamTask.model = entry.value;
1827
+ request.pendingChunks++;
1828
+ tryStreamTask(request, streamTask);
1829
+ enqueueFlush(request);
1830
+
1831
+ if (true) {
1832
+ callIteratorInDEV(iterator, progress, error);
1833
+ }
1834
+ } catch (x) {
1835
+ error(x);
1836
+ return;
1837
+ }
1838
+ }
1839
+ }
1840
+
1841
+ function error(reason) {
1842
+ if (aborted) {
1843
+ return;
1844
+ }
1845
+
1846
+ aborted = true;
1847
+ request.abortListeners.delete(error);
1848
+
1849
+ {
1850
+ var digest = logRecoverableError(request, reason);
1851
+ emitErrorChunk(request, streamTask.id, digest, reason);
1852
+ }
1853
+
1854
+ enqueueFlush(request);
1855
+
1856
+ if (typeof iterator.throw === 'function') {
1857
+ // The iterator protocol doesn't necessarily include this but a generator do.
1858
+ // $FlowFixMe should be able to pass mixed
1859
+ iterator.throw(reason).then(error, error);
1860
+ }
1861
+ }
1862
+
1863
+ request.abortListeners.add(error);
1864
+
1865
+ {
1866
+ callIteratorInDEV(iterator, progress, error);
1867
+ }
1868
+
1869
+ return serializeByValueID(streamTask.id);
1870
+ }
1871
+
1649
1872
  function emitHint(request, code, model) {
1650
1873
  emitHintChunk(request, code, model);
1651
1874
  enqueueFlush(request);
@@ -1717,15 +1940,47 @@ function createLazyWrapperAroundWakeable(wakeable) {
1717
1940
  }
1718
1941
 
1719
1942
  return lazyType;
1943
+ } // This indirect exists so we can exclude its stack frame in DEV (and anything below it).
1944
+
1945
+ /** @noinline */
1946
+
1947
+
1948
+ function callComponentInDEV(Component, props, componentDebugInfo) {
1949
+ // The secondArg is always undefined in Server Components since refs error early.
1950
+ var secondArg = undefined;
1951
+ setCurrentOwner(componentDebugInfo);
1952
+
1953
+ try {
1954
+ if (supportsComponentStorage) {
1955
+ // Run the component in an Async Context that tracks the current owner.
1956
+ return componentStorage.run(componentDebugInfo, Component, props, secondArg);
1957
+ } else {
1958
+ return Component(props, secondArg);
1959
+ }
1960
+ } finally {
1961
+ setCurrentOwner(null);
1962
+ }
1963
+ } // This indirect exists so we can exclude its stack frame in DEV (and anything below it).
1964
+
1965
+ /** @noinline */
1966
+
1967
+
1968
+ function callLazyInitInDEV(lazy) {
1969
+ var payload = lazy._payload;
1970
+ var init = lazy._init;
1971
+ return init(payload);
1720
1972
  }
1721
1973
 
1722
- function renderFunctionComponent(request, task, key, Component, props, owner) {
1974
+ function renderFunctionComponent(request, task, key, Component, props, owner, // DEV-only
1975
+ stack) // DEV-only
1976
+ {
1723
1977
  // Reset the task's thenable state before continuing, so that if a later
1724
1978
  // component suspends we can reuse the same task object. If the same
1725
1979
  // component suspends again, the thenable state will be restored.
1726
1980
  var prevThenableState = task.thenableState;
1727
1981
  task.thenableState = null;
1728
- var componentDebugInfo = null;
1982
+ var result;
1983
+ var componentDebugInfo;
1729
1984
 
1730
1985
  {
1731
1986
  if (debugID === null) {
@@ -1746,28 +2001,17 @@ function renderFunctionComponent(request, task, key, Component, props, owner) {
1746
2001
  name: componentName,
1747
2002
  env: request.environmentName,
1748
2003
  owner: owner
1749
- }; // We outline this model eagerly so that we can refer to by reference as an owner.
2004
+ };
1750
2005
  // If we had a smarter way to dedupe we might not have to do this if there ends up
1751
2006
  // being no references to this as an owner.
1752
2007
 
2008
+
1753
2009
  outlineModel(request, componentDebugInfo);
1754
2010
  emitDebugChunk(request, componentDebugID, componentDebugInfo);
1755
2011
  }
1756
- }
1757
-
1758
- prepareToUseHooksForComponent(prevThenableState, componentDebugInfo); // The secondArg is always undefined in Server Components since refs error early.
1759
-
1760
- var secondArg = undefined;
1761
- var result;
1762
-
1763
- {
1764
- ReactSharedInternals.owner = componentDebugInfo;
1765
2012
 
1766
- try {
1767
- result = Component(props, secondArg);
1768
- } finally {
1769
- ReactSharedInternals.owner = null;
1770
- }
2013
+ prepareToUseHooksForComponent(prevThenableState, componentDebugInfo);
2014
+ result = callComponentInDEV(Component, props, componentDebugInfo);
1771
2015
  }
1772
2016
 
1773
2017
  if (typeof result === 'object' && result !== null) {
@@ -1819,6 +2063,33 @@ function renderFunctionComponent(request, task, key, Component, props, owner) {
1819
2063
  {
1820
2064
  result._debugInfo = iterableChild._debugInfo;
1821
2065
  }
2066
+ } else if (typeof result[ASYNC_ITERATOR] === 'function' && (typeof ReadableStream !== 'function' || !(result instanceof ReadableStream))) {
2067
+ var _iterableChild = result;
2068
+ result = _defineProperty({}, ASYNC_ITERATOR, function () {
2069
+ var iterator = _iterableChild[ASYNC_ITERATOR]();
2070
+
2071
+ {
2072
+ // If this was an AsyncIterator but not an AsyncGeneratorFunction we warn because
2073
+ // it might have been a mistake. Technically you can make this mistake with
2074
+ // AsyncGeneratorFunctions and even single-shot AsyncIterables too but it's extra
2075
+ // tempting to try to return the value from a generator.
2076
+ if (iterator === _iterableChild) {
2077
+ var isGeneratorComponent = // $FlowIgnore[method-unbinding]
2078
+ Object.prototype.toString.call(Component) === '[object AsyncGeneratorFunction]' && // $FlowIgnore[method-unbinding]
2079
+ Object.prototype.toString.call(_iterableChild) === '[object AsyncGenerator]';
2080
+
2081
+ if (!isGeneratorComponent) {
2082
+ error('Returning an AsyncIterator from a Server Component is not supported ' + 'since it cannot be looped over more than once. ');
2083
+ }
2084
+ }
2085
+ }
2086
+
2087
+ return iterator;
2088
+ });
2089
+
2090
+ {
2091
+ result._debugInfo = _iterableChild._debugInfo;
2092
+ }
1822
2093
  }
1823
2094
  } // Track this element's key on the Server Component on the keyPath context..
1824
2095
 
@@ -1901,11 +2172,47 @@ function renderFragment(request, task, children) {
1901
2172
  return children;
1902
2173
  }
1903
2174
 
1904
- function renderClientElement(task, type, key, props, owner) // DEV-only
1905
- {
1906
- // the keys of any Server Components which are not serialized.
2175
+ function renderAsyncFragment(request, task, children, getAsyncIterator) {
2176
+ if (task.keyPath !== null) {
2177
+ // We have a Server Component that specifies a key but we're now splitting
2178
+ // the tree using a fragment.
2179
+ var fragment = [REACT_ELEMENT_TYPE, REACT_FRAGMENT_TYPE, task.keyPath, {
2180
+ children: children
2181
+ }];
2182
+
2183
+ if (!task.implicitSlot) {
2184
+ // If this was keyed inside a set. I.e. the outer Server Component was keyed
2185
+ // then we need to handle reorders of the whole set. To do this we need to wrap
2186
+ // this array in a keyed Fragment.
2187
+ return fragment;
2188
+ } // If the outer Server Component was implicit but then an inner one had a key
2189
+ // we don't actually need to be able to move the whole set around. It'll always be
2190
+ // in an implicit slot. The key only exists to be able to reset the state of the
2191
+ // children. We could achieve the same effect by passing on the keyPath to the next
2192
+ // set of components inside the fragment. This would also allow a keyless fragment
2193
+ // reconcile against a single child.
2194
+ // Unfortunately because of JSON.stringify, we can't call the recursive loop for
2195
+ // each child within this context because we can't return a set with already resolved
2196
+ // values. E.g. a string would get double encoded. Returning would pop the context.
2197
+ // So instead, we wrap it with an unkeyed fragment and inner keyed fragment.
2198
+
2199
+
2200
+ return [fragment];
2201
+ } // Since we're yielding here, that implicitly resets the keyPath context on the
2202
+ // way up. Which is what we want since we've consumed it. If this changes to
2203
+ // be recursive serialization, we need to reset the keyPath and implicitSlot,
2204
+ // before recursing here.
1907
2205
 
1908
2206
 
2207
+ var asyncIterator = getAsyncIterator.call(children);
2208
+ return serializeAsyncIterable(request, task, children, asyncIterator);
2209
+ }
2210
+
2211
+ function renderClientElement(task, type, key, props, owner, // DEV-only
2212
+ stack) // DEV-only
2213
+ {
2214
+ // We prepend the terminal client element that actually gets serialized with
2215
+ // the keys of any Server Components which are not serialized.
1909
2216
  var keyPath = task.keyPath;
1910
2217
 
1911
2218
  if (key === null) {
@@ -1952,7 +2259,8 @@ function outlineTask(request, task) {
1952
2259
  return serializeLazyID(newTask.id);
1953
2260
  }
1954
2261
 
1955
- function renderElement(request, task, type, key, ref, props, owner) // DEV only
2262
+ function renderElement(request, task, type, key, ref, props, owner, // DEV only
2263
+ stack) // DEV only
1956
2264
  {
1957
2265
  if (ref !== null && ref !== undefined) {
1958
2266
  // When the ref moves to the regular props object this will implicitly
@@ -1972,7 +2280,7 @@ function renderElement(request, task, type, key, ref, props, owner) // DEV only
1972
2280
  }
1973
2281
 
1974
2282
  if (typeof type === 'function') {
1975
- if (isClientReference(type) || isTemporaryReference(type)) {
2283
+ if (isClientReference(type) || isOpaqueTemporaryReference(type)) {
1976
2284
  // This is a reference to a Client Component.
1977
2285
  return renderClientElement(task, type, key, props, owner);
1978
2286
  } // This is a Server Component.
@@ -2009,9 +2317,12 @@ function renderElement(request, task, type, key, ref, props, owner) // DEV only
2009
2317
  switch (type.$$typeof) {
2010
2318
  case REACT_LAZY_TYPE:
2011
2319
  {
2012
- var payload = type._payload;
2013
- var init = type._init;
2014
- var wrappedType = init(payload);
2320
+ var wrappedType;
2321
+
2322
+ {
2323
+ wrappedType = callLazyInitInDEV(type);
2324
+ }
2325
+
2015
2326
  return renderElement(request, task, wrappedType, key, ref, props, owner);
2016
2327
  }
2017
2328
 
@@ -2049,8 +2360,8 @@ function createTask(request, model, keyPath, implicitSlot, abortSet) {
2049
2360
  if (typeof model === 'object' && model !== null) {
2050
2361
  // If we're about to write this into a new task we can assign it an ID early so that
2051
2362
  // any other references can refer to the value we're about to write.
2052
- if ((keyPath !== null || implicitSlot)) ; else {
2053
- request.writtenObjects.set(model, id);
2363
+ if (keyPath !== null || implicitSlot) ; else {
2364
+ request.writtenObjects.set(model, serializeByValueID(id));
2054
2365
  }
2055
2366
  }
2056
2367
 
@@ -2113,10 +2424,6 @@ function serializeServerReferenceID(id) {
2113
2424
  return '$F' + id.toString(16);
2114
2425
  }
2115
2426
 
2116
- function serializeTemporaryReferenceID(id) {
2117
- return '$T' + id;
2118
- }
2119
-
2120
2427
  function serializeSymbolReference(name) {
2121
2428
  return '$S' + name;
2122
2429
  }
@@ -2233,9 +2540,8 @@ function serializeServerReference(request, serverReference) {
2233
2540
  return serializeServerReferenceID(metadataId);
2234
2541
  }
2235
2542
 
2236
- function serializeTemporaryReference(request, temporaryReference) {
2237
- var id = resolveTemporaryReferenceID(temporaryReference);
2238
- return serializeTemporaryReferenceID(id);
2543
+ function serializeTemporaryReference(request, reference) {
2544
+ return '$T' + reference;
2239
2545
  }
2240
2546
 
2241
2547
  function serializeLargeTextString(request, text) {
@@ -2247,20 +2553,6 @@ function serializeLargeTextString(request, text) {
2247
2553
 
2248
2554
  function serializeMap(request, map) {
2249
2555
  var entries = Array.from(map);
2250
-
2251
- for (var i = 0; i < entries.length; i++) {
2252
- var key = entries[i][0];
2253
-
2254
- if (typeof key === 'object' && key !== null) {
2255
- var writtenObjects = request.writtenObjects;
2256
- var existingId = writtenObjects.get(key);
2257
-
2258
- if (existingId === undefined) {
2259
- writtenObjects.set(key, SEEN_BUT_NOT_YET_OUTLINED);
2260
- }
2261
- }
2262
- }
2263
-
2264
2556
  var id = outlineModel(request, entries);
2265
2557
  return '$Q' + id.toString(16);
2266
2558
  }
@@ -2273,20 +2565,6 @@ function serializeFormData(request, formData) {
2273
2565
 
2274
2566
  function serializeSet(request, set) {
2275
2567
  var entries = Array.from(set);
2276
-
2277
- for (var i = 0; i < entries.length; i++) {
2278
- var key = entries[i];
2279
-
2280
- if (typeof key === 'object' && key !== null) {
2281
- var writtenObjects = request.writtenObjects;
2282
- var existingId = writtenObjects.get(key);
2283
-
2284
- if (existingId === undefined) {
2285
- writtenObjects.set(key, SEEN_BUT_NOT_YET_OUTLINED);
2286
- }
2287
- }
2288
- }
2289
-
2290
2568
  var id = outlineModel(request, entries);
2291
2569
  return '$W' + id.toString(16);
2292
2570
  }
@@ -2296,6 +2574,58 @@ function serializeIterator(request, iterator) {
2296
2574
  return '$i' + id.toString(16);
2297
2575
  }
2298
2576
 
2577
+ function serializeTypedArray(request, tag, typedArray) {
2578
+ request.pendingChunks++;
2579
+ var bufferId = request.nextChunkId++;
2580
+ emitTypedArrayChunk(request, bufferId, tag, typedArray);
2581
+ return serializeByValueID(bufferId);
2582
+ }
2583
+
2584
+ function serializeBlob(request, blob) {
2585
+ var model = [blob.type];
2586
+ var newTask = createTask(request, model, null, false, request.abortableTasks);
2587
+ var reader = blob.stream().getReader();
2588
+ var aborted = false;
2589
+
2590
+ function progress(entry) {
2591
+ if (aborted) {
2592
+ return;
2593
+ }
2594
+
2595
+ if (entry.done) {
2596
+ request.abortListeners.delete(error);
2597
+ aborted = true;
2598
+ pingTask(request, newTask);
2599
+ return;
2600
+ } // TODO: Emit the chunk early and refer to it later by dedupe.
2601
+
2602
+
2603
+ model.push(entry.value); // $FlowFixMe[incompatible-call]
2604
+
2605
+ return reader.read().then(progress).catch(error);
2606
+ }
2607
+
2608
+ function error(reason) {
2609
+ if (aborted) {
2610
+ return;
2611
+ }
2612
+
2613
+ aborted = true;
2614
+ request.abortListeners.delete(error);
2615
+ var digest = logRecoverableError(request, reason);
2616
+ emitErrorChunk(request, newTask.id, digest, reason);
2617
+ request.abortableTasks.delete(newTask);
2618
+ enqueueFlush(request); // $FlowFixMe should be able to pass mixed
2619
+
2620
+ reader.cancel(reason).then(error, error);
2621
+ }
2622
+
2623
+ request.abortListeners.add(error); // $FlowFixMe[incompatible-call]
2624
+
2625
+ reader.read().then(progress).catch(error);
2626
+ return '$B' + newTask.id.toString(16);
2627
+ }
2628
+
2299
2629
  function escapeStringValue(value) {
2300
2630
  if (value[0] === '$') {
2301
2631
  // We need to escape $ prefixed strings since we use those to encode
@@ -2388,37 +2718,34 @@ function renderModelDestructive(request, task, parent, parentPropertyName, value
2388
2718
  {
2389
2719
  var _writtenObjects = request.writtenObjects;
2390
2720
 
2391
- var _existingId = _writtenObjects.get(value);
2392
-
2393
- if (_existingId !== undefined) {
2394
- if ((task.keyPath !== null || task.implicitSlot)) ; else if (modelRoot === value) {
2395
- // This is the ID we're currently emitting so we need to write it
2396
- // once but if we discover it again, we refer to it by id.
2397
- modelRoot = null;
2398
- } else if (_existingId === SEEN_BUT_NOT_YET_OUTLINED) {
2399
- // TODO: If we throw here we can treat this as suspending which causes an outline
2400
- // but that is able to reuse the same task if we're already in one but then that
2401
- // will be a lazy future value rather than guaranteed to exist but maybe that's good.
2402
- var newId = outlineModel(request, value);
2403
- return serializeByValueID(newId);
2404
- } else {
2405
- // We've already emitted this as an outlined object, so we can refer to that by its
2406
- // existing ID. TODO: We should use a lazy reference since, unlike plain objects,
2407
- // elements might suspend so it might not have emitted yet even if we have the ID for
2408
- // it. However, this creates an extra wrapper when it's not needed. We should really
2409
- // detect whether this already was emitted and synchronously available. In that
2410
- // case we can refer to it synchronously and only make it lazy otherwise.
2411
- // We currently don't have a data structure that lets us see that though.
2412
- return serializeByValueID(_existingId);
2413
- }
2414
- } else {
2415
- // This is the first time we've seen this object. We may never see it again
2416
- // so we'll inline it. Mark it as seen. If we see it again, we'll outline.
2417
- _writtenObjects.set(value, SEEN_BUT_NOT_YET_OUTLINED); // The element's props are marked as "never outlined" so that they are inlined into
2418
- // the same row as the element itself.
2419
-
2721
+ if (task.keyPath !== null || task.implicitSlot) ; else {
2722
+ var _existingReference = _writtenObjects.get(value);
2420
2723
 
2421
- _writtenObjects.set(value.props, NEVER_OUTLINED);
2724
+ if (_existingReference !== undefined) {
2725
+ if (modelRoot === value) {
2726
+ // This is the ID we're currently emitting so we need to write it
2727
+ // once but if we discover it again, we refer to it by id.
2728
+ modelRoot = null;
2729
+ } else {
2730
+ // We've already emitted this as an outlined object, so we can refer to that by its
2731
+ // existing ID. TODO: We should use a lazy reference since, unlike plain objects,
2732
+ // elements might suspend so it might not have emitted yet even if we have the ID for
2733
+ // it. However, this creates an extra wrapper when it's not needed. We should really
2734
+ // detect whether this already was emitted and synchronously available. In that
2735
+ // case we can refer to it synchronously and only make it lazy otherwise.
2736
+ // We currently don't have a data structure that lets us see that though.
2737
+ return _existingReference;
2738
+ }
2739
+ } else if (parentPropertyName.indexOf(':') === -1) {
2740
+ // TODO: If the property name contains a colon, we don't dedupe. Escape instead.
2741
+ var parentReference = _writtenObjects.get(parent);
2742
+
2743
+ if (parentReference !== undefined) {
2744
+ // If the parent has a reference, we can refer to this object indirectly
2745
+ // through the property name inside that parent.
2746
+ _writtenObjects.set(value, parentReference + ':' + parentPropertyName);
2747
+ }
2748
+ }
2422
2749
  }
2423
2750
 
2424
2751
  var element = value;
@@ -2461,9 +2788,11 @@ function renderModelDestructive(request, task, parent, parentPropertyName, value
2461
2788
  // from suspending the lazy before.
2462
2789
  task.thenableState = null;
2463
2790
  var lazy = value;
2464
- var payload = lazy._payload;
2465
- var init = lazy._init;
2466
- var resolvedModel = init(payload);
2791
+ var resolvedModel;
2792
+
2793
+ {
2794
+ resolvedModel = callLazyInitInDEV(lazy);
2795
+ }
2467
2796
 
2468
2797
  {
2469
2798
  var _debugInfo = lazy._debugInfo;
@@ -2485,18 +2814,31 @@ function renderModelDestructive(request, task, parent, parentPropertyName, value
2485
2814
 
2486
2815
  return renderModelDestructive(request, task, emptyRoot, '', resolvedModel);
2487
2816
  }
2817
+
2818
+ case REACT_LEGACY_ELEMENT_TYPE:
2819
+ {
2820
+ 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.');
2821
+ }
2488
2822
  }
2489
2823
 
2490
2824
  if (isClientReference(value)) {
2491
2825
  return serializeClientReference(request, parent, parentPropertyName, value);
2492
2826
  }
2493
2827
 
2828
+ if (request.temporaryReferences !== undefined) {
2829
+ var tempRef = resolveTemporaryReference(request.temporaryReferences, value);
2830
+
2831
+ if (tempRef !== undefined) {
2832
+ return serializeTemporaryReference(request, tempRef);
2833
+ }
2834
+ }
2835
+
2494
2836
  var writtenObjects = request.writtenObjects;
2495
- var existingId = writtenObjects.get(value); // $FlowFixMe[method-unbinding]
2837
+ var existingReference = writtenObjects.get(value); // $FlowFixMe[method-unbinding]
2496
2838
 
2497
2839
  if (typeof value.then === 'function') {
2498
- if (existingId !== undefined) {
2499
- if ((task.keyPath !== null || task.implicitSlot)) {
2840
+ if (existingReference !== undefined) {
2841
+ if (task.keyPath !== null || task.implicitSlot) {
2500
2842
  // If we're in some kind of context we can't reuse the result of this render or
2501
2843
  // previous renders of this element. We only reuse Promises if they're not wrapped
2502
2844
  // by another Server Component.
@@ -2509,35 +2851,58 @@ function renderModelDestructive(request, task, parent, parentPropertyName, value
2509
2851
  modelRoot = null;
2510
2852
  } else {
2511
2853
  // We've seen this promise before, so we can just refer to the same result.
2512
- return serializePromiseID(existingId);
2854
+ return existingReference;
2513
2855
  }
2514
2856
  } // We assume that any object with a .then property is a "Thenable" type,
2515
2857
  // or a Promise type. Either of which can be represented by a Promise.
2516
2858
 
2517
2859
 
2518
2860
  var promiseId = serializeThenable(request, task, value);
2519
- writtenObjects.set(value, promiseId);
2520
- return serializePromiseID(promiseId);
2861
+ var promiseReference = serializePromiseID(promiseId);
2862
+ writtenObjects.set(value, promiseReference);
2863
+ return promiseReference;
2521
2864
  }
2522
2865
 
2523
- if (existingId !== undefined) {
2866
+ if (existingReference !== undefined) {
2524
2867
  if (modelRoot === value) {
2525
2868
  // This is the ID we're currently emitting so we need to write it
2526
2869
  // once but if we discover it again, we refer to it by id.
2527
2870
  modelRoot = null;
2528
- } else if (existingId === SEEN_BUT_NOT_YET_OUTLINED) {
2529
- var _newId = outlineModel(request, value);
2530
-
2531
- return serializeByValueID(_newId);
2532
- } else if (existingId !== NEVER_OUTLINED) {
2871
+ } else {
2533
2872
  // We've already emitted this as an outlined object, so we can
2534
2873
  // just refer to that by its existing ID.
2535
- return serializeByValueID(existingId);
2874
+ return existingReference;
2875
+ }
2876
+ } else if (parentPropertyName.indexOf(':') === -1) {
2877
+ // TODO: If the property name contains a colon, we don't dedupe. Escape instead.
2878
+ var _parentReference = writtenObjects.get(parent);
2879
+
2880
+ if (_parentReference !== undefined) {
2881
+ // If the parent has a reference, we can refer to this object indirectly
2882
+ // through the property name inside that parent.
2883
+ var propertyName = parentPropertyName;
2884
+
2885
+ if (isArray(parent) && parent[0] === REACT_ELEMENT_TYPE) {
2886
+ // For elements, we've converted it to an array but we'll have converted
2887
+ // it back to an element before we read the references so the property
2888
+ // needs to be aliased.
2889
+ switch (parentPropertyName) {
2890
+ case '1':
2891
+ propertyName = 'type';
2892
+ break;
2893
+
2894
+ case '2':
2895
+ propertyName = 'key';
2896
+ break;
2897
+
2898
+ case '3':
2899
+ propertyName = 'props';
2900
+ break;
2901
+ }
2902
+ }
2903
+
2904
+ writtenObjects.set(value, _parentReference + ':' + propertyName);
2536
2905
  }
2537
- } else {
2538
- // This is the first time we've seen this object. We may never see it again
2539
- // so we'll inline it. Mark it as seen. If we see it again, we'll outline.
2540
- writtenObjects.set(value, SEEN_BUT_NOT_YET_OUTLINED);
2541
2906
  }
2542
2907
 
2543
2908
  if (isArray(value)) {
@@ -2557,11 +2922,82 @@ function renderModelDestructive(request, task, parent, parentPropertyName, value
2557
2922
  return serializeFormData(request, value);
2558
2923
  }
2559
2924
 
2560
- var iteratorFn = getIteratorFn(value);
2925
+ {
2926
+ if (value instanceof ArrayBuffer) {
2927
+ return serializeTypedArray(request, 'A', new Uint8Array(value));
2928
+ }
2561
2929
 
2562
- if (iteratorFn) {
2563
- // TODO: Should we serialize the return value as well like we do for AsyncIterables?
2564
- var iterator = iteratorFn.call(value);
2930
+ if (value instanceof Int8Array) {
2931
+ // char
2932
+ return serializeTypedArray(request, 'O', value);
2933
+ }
2934
+
2935
+ if (value instanceof Uint8Array) {
2936
+ // unsigned char
2937
+ return serializeTypedArray(request, 'o', value);
2938
+ }
2939
+
2940
+ if (value instanceof Uint8ClampedArray) {
2941
+ // unsigned clamped char
2942
+ return serializeTypedArray(request, 'U', value);
2943
+ }
2944
+
2945
+ if (value instanceof Int16Array) {
2946
+ // sort
2947
+ return serializeTypedArray(request, 'S', value);
2948
+ }
2949
+
2950
+ if (value instanceof Uint16Array) {
2951
+ // unsigned short
2952
+ return serializeTypedArray(request, 's', value);
2953
+ }
2954
+
2955
+ if (value instanceof Int32Array) {
2956
+ // long
2957
+ return serializeTypedArray(request, 'L', value);
2958
+ }
2959
+
2960
+ if (value instanceof Uint32Array) {
2961
+ // unsigned long
2962
+ return serializeTypedArray(request, 'l', value);
2963
+ }
2964
+
2965
+ if (value instanceof Float32Array) {
2966
+ // float
2967
+ return serializeTypedArray(request, 'G', value);
2968
+ }
2969
+
2970
+ if (value instanceof Float64Array) {
2971
+ // double
2972
+ return serializeTypedArray(request, 'g', value);
2973
+ }
2974
+
2975
+ if (value instanceof BigInt64Array) {
2976
+ // number
2977
+ return serializeTypedArray(request, 'M', value);
2978
+ }
2979
+
2980
+ if (value instanceof BigUint64Array) {
2981
+ // unsigned number
2982
+ // We use "m" instead of "n" since JSON can start with "null"
2983
+ return serializeTypedArray(request, 'm', value);
2984
+ }
2985
+
2986
+ if (value instanceof DataView) {
2987
+ return serializeTypedArray(request, 'V', value);
2988
+ } // TODO: Blob is not available in old Node. Remove the typeof check later.
2989
+
2990
+
2991
+ if (typeof Blob === 'function' && value instanceof Blob) {
2992
+ return serializeBlob(request, value);
2993
+ }
2994
+ }
2995
+
2996
+ var iteratorFn = getIteratorFn(value);
2997
+
2998
+ if (iteratorFn) {
2999
+ // TODO: Should we serialize the return value as well like we do for AsyncIterables?
3000
+ var iterator = iteratorFn.call(value);
2565
3001
 
2566
3002
  if (iterator === value) {
2567
3003
  // Iterator, not Iterable
@@ -2571,6 +3007,20 @@ function renderModelDestructive(request, task, parent, parentPropertyName, value
2571
3007
  return renderFragment(request, task, Array.from(iterator));
2572
3008
  }
2573
3009
 
3010
+ {
3011
+ // TODO: Blob is not available in old Node. Remove the typeof check later.
3012
+ if (typeof ReadableStream === 'function' && value instanceof ReadableStream) {
3013
+ return serializeReadableStream(request, task, value);
3014
+ }
3015
+
3016
+ var getAsyncIterator = value[ASYNC_ITERATOR];
3017
+
3018
+ if (typeof getAsyncIterator === 'function') {
3019
+ // We treat AsyncIterables as a Fragment and as such we might need to key them.
3020
+ return renderAsyncFragment(request, task, value, getAsyncIterator);
3021
+ }
3022
+ } // Verify that this is a simple plain object.
3023
+
2574
3024
 
2575
3025
  var proto = getPrototypeOf(value);
2576
3026
 
@@ -2640,11 +3090,17 @@ function renderModelDestructive(request, task, parent, parentPropertyName, value
2640
3090
  return serializeServerReference(request, value);
2641
3091
  }
2642
3092
 
2643
- if (isTemporaryReference(value)) {
2644
- return serializeTemporaryReference(request, value);
3093
+ if (request.temporaryReferences !== undefined) {
3094
+ var _tempRef = resolveTemporaryReference(request.temporaryReferences, value);
3095
+
3096
+ if (_tempRef !== undefined) {
3097
+ return serializeTemporaryReference(request, _tempRef);
3098
+ }
2645
3099
  }
2646
3100
 
2647
- if (/^on[A-Z]/.test(parentPropertyName)) {
3101
+ if (isOpaqueTemporaryReference(value)) {
3102
+ throw new Error('Could not reference an opaque temporary reference. ' + 'This is likely due to misconfiguring the temporaryReferences options ' + 'on the server.');
3103
+ } else if (/^on[A-Z]/.test(parentPropertyName)) {
2648
3104
  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.');
2649
3105
  } else if ((jsxChildrenParents.has(parent) || jsxPropsParents.has(parent) && parentPropertyName === 'children')) {
2650
3106
  var componentName = value.displayName || value.name || 'Component';
@@ -2656,11 +3112,10 @@ function renderModelDestructive(request, task, parent, parentPropertyName, value
2656
3112
 
2657
3113
  if (typeof value === 'symbol') {
2658
3114
  var writtenSymbols = request.writtenSymbols;
3115
+ var existingId = writtenSymbols.get(value);
2659
3116
 
2660
- var _existingId2 = writtenSymbols.get(value);
2661
-
2662
- if (_existingId2 !== undefined) {
2663
- return serializeByValueID(_existingId2);
3117
+ if (existingId !== undefined) {
3118
+ return serializeByValueID(existingId);
2664
3119
  } // $FlowFixMe[incompatible-type] `description` might be undefined
2665
3120
 
2666
3121
 
@@ -2848,6 +3303,18 @@ function emitDebugChunk(request, id, debugInfo) {
2848
3303
  request.completedRegularChunks.push(processedChunk);
2849
3304
  }
2850
3305
 
3306
+ function emitTypedArrayChunk(request, id, tag, typedArray) {
3307
+
3308
+ request.pendingChunks++; // Extra chunk for the header.
3309
+ // TODO: Convert to little endian if that's not the server default.
3310
+
3311
+ var binaryChunk = typedArrayToBinaryChunk(typedArray);
3312
+ var binaryLength = byteLengthOfBinaryChunk(binaryChunk);
3313
+ var row = id.toString(16) + ':' + tag + binaryLength.toString(16) + ',';
3314
+ var headerChunk = stringToChunk(row);
3315
+ request.completedRegularChunks.push(headerChunk, binaryChunk);
3316
+ }
3317
+
2851
3318
  function emitTextChunk(request, id, text) {
2852
3319
  request.pendingChunks++; // Extra chunk for the header.
2853
3320
 
@@ -2883,6 +3350,14 @@ function renderConsoleValue(request, counter, parent, parentPropertyName, value)
2883
3350
  return serializeClientReference(request, parent, parentPropertyName, value);
2884
3351
  }
2885
3352
 
3353
+ if (request.temporaryReferences !== undefined) {
3354
+ var tempRef = resolveTemporaryReference(request.temporaryReferences, value);
3355
+
3356
+ if (tempRef !== undefined) {
3357
+ return serializeTemporaryReference(request, tempRef);
3358
+ }
3359
+ }
3360
+
2886
3361
  if (counter.objectCount > 20) {
2887
3362
  // We've reached our max number of objects to serialize across the wire so we serialize this
2888
3363
  // object but no properties inside of it, as a place holder.
@@ -2891,12 +3366,12 @@ function renderConsoleValue(request, counter, parent, parentPropertyName, value)
2891
3366
 
2892
3367
  counter.objectCount++;
2893
3368
  var writtenObjects = request.writtenObjects;
2894
- var existingId = writtenObjects.get(value); // $FlowFixMe[method-unbinding]
3369
+ var existingReference = writtenObjects.get(value); // $FlowFixMe[method-unbinding]
2895
3370
 
2896
3371
  if (typeof value.then === 'function') {
2897
- if (existingId !== undefined) {
3372
+ if (existingReference !== undefined) {
2898
3373
  // We've seen this promise before, so we can just refer to the same result.
2899
- return serializePromiseID(existingId);
3374
+ return existingReference;
2900
3375
  }
2901
3376
 
2902
3377
  var thenable = value;
@@ -2928,10 +3403,10 @@ function renderConsoleValue(request, counter, parent, parentPropertyName, value)
2928
3403
  return serializeInfinitePromise();
2929
3404
  }
2930
3405
 
2931
- if (existingId !== undefined && existingId >= 0) {
3406
+ if (existingReference !== undefined) {
2932
3407
  // We've already emitted this as a real object, so we can
2933
- // just refer to that by its existing ID.
2934
- return serializeByValueID(existingId);
3408
+ // just refer to that by its existing reference.
3409
+ return existingReference;
2935
3410
  }
2936
3411
 
2937
3412
  if (isArray(value)) {
@@ -2951,6 +3426,77 @@ function renderConsoleValue(request, counter, parent, parentPropertyName, value)
2951
3426
  return serializeFormData(request, value);
2952
3427
  }
2953
3428
 
3429
+ {
3430
+ if (value instanceof ArrayBuffer) {
3431
+ return serializeTypedArray(request, 'A', new Uint8Array(value));
3432
+ }
3433
+
3434
+ if (value instanceof Int8Array) {
3435
+ // char
3436
+ return serializeTypedArray(request, 'O', value);
3437
+ }
3438
+
3439
+ if (value instanceof Uint8Array) {
3440
+ // unsigned char
3441
+ return serializeTypedArray(request, 'o', value);
3442
+ }
3443
+
3444
+ if (value instanceof Uint8ClampedArray) {
3445
+ // unsigned clamped char
3446
+ return serializeTypedArray(request, 'U', value);
3447
+ }
3448
+
3449
+ if (value instanceof Int16Array) {
3450
+ // sort
3451
+ return serializeTypedArray(request, 'S', value);
3452
+ }
3453
+
3454
+ if (value instanceof Uint16Array) {
3455
+ // unsigned short
3456
+ return serializeTypedArray(request, 's', value);
3457
+ }
3458
+
3459
+ if (value instanceof Int32Array) {
3460
+ // long
3461
+ return serializeTypedArray(request, 'L', value);
3462
+ }
3463
+
3464
+ if (value instanceof Uint32Array) {
3465
+ // unsigned long
3466
+ return serializeTypedArray(request, 'l', value);
3467
+ }
3468
+
3469
+ if (value instanceof Float32Array) {
3470
+ // float
3471
+ return serializeTypedArray(request, 'G', value);
3472
+ }
3473
+
3474
+ if (value instanceof Float64Array) {
3475
+ // double
3476
+ return serializeTypedArray(request, 'g', value);
3477
+ }
3478
+
3479
+ if (value instanceof BigInt64Array) {
3480
+ // number
3481
+ return serializeTypedArray(request, 'M', value);
3482
+ }
3483
+
3484
+ if (value instanceof BigUint64Array) {
3485
+ // unsigned number
3486
+ // We use "m" instead of "n" since JSON can start with "null"
3487
+ return serializeTypedArray(request, 'm', value);
3488
+ }
3489
+
3490
+ if (value instanceof DataView) {
3491
+ return serializeTypedArray(request, 'V', value);
3492
+ } // TODO: Blob is not available in old Node. Remove the typeof check later.
3493
+
3494
+
3495
+ if (typeof Blob === 'function' && value instanceof Blob) {
3496
+ return serializeBlob(request, value);
3497
+ }
3498
+ }
3499
+
2954
3500
  var iteratorFn = getIteratorFn(value);
2955
3501
 
2956
3502
  if (iteratorFn) {
@@ -2996,8 +3542,12 @@ function renderConsoleValue(request, counter, parent, parentPropertyName, value)
2996
3542
  return serializeClientReference(request, parent, parentPropertyName, value);
2997
3543
  }
2998
3544
 
2999
- if (isTemporaryReference(value)) {
3000
- return serializeTemporaryReference(request, value);
3545
+ if (request.temporaryReferences !== undefined) {
3546
+ var _tempRef2 = resolveTemporaryReference(request.temporaryReferences, value);
3547
+
3548
+ if (_tempRef2 !== undefined) {
3549
+ return serializeTemporaryReference(request, _tempRef2);
3550
+ }
3001
3551
  } // Serialize the body of the function as an eval so it can be printed.
3002
3552
  // $FlowFixMe[method-unbinding]
3003
3553
 
@@ -3007,11 +3557,10 @@ function renderConsoleValue(request, counter, parent, parentPropertyName, value)
3007
3557
 
3008
3558
  if (typeof value === 'symbol') {
3009
3559
  var writtenSymbols = request.writtenSymbols;
3560
+ var existingId = writtenSymbols.get(value);
3010
3561
 
3011
- var _existingId3 = writtenSymbols.get(value);
3012
-
3013
- if (_existingId3 !== undefined) {
3014
- return serializeByValueID(_existingId3);
3562
+ if (existingId !== undefined) {
3563
+ return serializeByValueID(existingId);
3015
3564
  } // $FlowFixMe[incompatible-type] `description` might be undefined
3016
3565
 
3017
3566
 
@@ -3066,6 +3615,85 @@ function emitChunk(request, task, value) {
3066
3615
  emitTextChunk(request, id, value);
3067
3616
  return;
3068
3617
  }
3618
+
3619
+ {
3620
+ if (value instanceof ArrayBuffer) {
3621
+ emitTypedArrayChunk(request, id, 'A', new Uint8Array(value));
3622
+ return;
3623
+ }
3624
+
3625
+ if (value instanceof Int8Array) {
3626
+ // char
3627
+ emitTypedArrayChunk(request, id, 'O', value);
3628
+ return;
3629
+ }
3630
+
3631
+ if (value instanceof Uint8Array) {
3632
+ // unsigned char
3633
+ emitTypedArrayChunk(request, id, 'o', value);
3634
+ return;
3635
+ }
3636
+
3637
+ if (value instanceof Uint8ClampedArray) {
3638
+ // unsigned clamped char
3639
+ emitTypedArrayChunk(request, id, 'U', value);
3640
+ return;
3641
+ }
3642
+
3643
+ if (value instanceof Int16Array) {
3644
+ // sort
3645
+ emitTypedArrayChunk(request, id, 'S', value);
3646
+ return;
3647
+ }
3648
+
3649
+ if (value instanceof Uint16Array) {
3650
+ // unsigned short
3651
+ emitTypedArrayChunk(request, id, 's', value);
3652
+ return;
3653
+ }
3654
+
3655
+ if (value instanceof Int32Array) {
3656
+ // long
3657
+ emitTypedArrayChunk(request, id, 'L', value);
3658
+ return;
3659
+ }
3660
+
3661
+ if (value instanceof Uint32Array) {
3662
+ // unsigned long
3663
+ emitTypedArrayChunk(request, id, 'l', value);
3664
+ return;
3665
+ }
3666
+
3667
+ if (value instanceof Float32Array) {
3668
+ // float
3669
+ emitTypedArrayChunk(request, id, 'G', value);
3670
+ return;
3671
+ }
3672
+
3673
+ if (value instanceof Float64Array) {
3674
+ // double
3675
+ emitTypedArrayChunk(request, id, 'g', value);
3676
+ return;
3677
+ }
3678
+
3679
+ if (value instanceof BigInt64Array) {
3680
+ // number
3681
+ emitTypedArrayChunk(request, id, 'M', value);
3682
+ return;
3683
+ }
3684
+
3685
+ if (value instanceof BigUint64Array) {
3686
+ // unsigned number
3687
+ // We use "m" instead of "n" since JSON can start with "null"
3688
+ emitTypedArrayChunk(request, id, 'm', value);
3689
+ return;
3690
+ }
3691
+
3692
+ if (value instanceof DataView) {
3693
+ emitTypedArrayChunk(request, id, 'V', value);
3694
+ return;
3695
+ }
3696
+ } // For anything else we need to try to serialize it using JSON.
3069
3697
  // $FlowFixMe[incompatible-type] stringify can return null for undefined but we never do
3070
3698
 
3071
3699
 
@@ -3111,8 +3739,11 @@ function retryTask(request, task) {
3111
3739
  task.implicitSlot = false;
3112
3740
 
3113
3741
  if (typeof resolvedModel === 'object' && resolvedModel !== null) {
3114
- // Object might contain unresolved values like additional elements.
3742
+ // We're not in a contextual place here so we can refer to this object by this ID for
3743
+ // any future references.
3744
+ request.writtenObjects.set(resolvedModel, serializeByValueID(task.id)); // Object might contain unresolved values like additional elements.
3115
3745
  // This is simulating what the JSON loop would do if this was part of it.
3746
+
3116
3747
  emitChunk(request, task, resolvedModel);
3117
3748
  } else {
3118
3749
  // If the value is a string, it means it's a terminal value and we already escaped it
@@ -3154,6 +3785,26 @@ function retryTask(request, task) {
3154
3785
  }
3155
3786
  }
3156
3787
 
3788
+ function tryStreamTask(request, task) {
3789
+ // This is used to try to emit something synchronously but if it suspends,
3790
+ // we emit a reference to a new outlined task immediately instead.
3791
+ var prevDebugID = debugID;
3792
+
3793
+ {
3794
+ // We don't use the id of the stream task for debugID. Instead we leave it null
3795
+ // so that we instead outline the row to get a new debugID if needed.
3796
+ debugID = null;
3797
+ }
3798
+
3799
+ try {
3800
+ emitChunk(request, task, task.model);
3801
+ } finally {
3802
+ {
3803
+ debugID = prevDebugID;
3804
+ }
3805
+ }
3806
+ }
3807
+
3157
3808
  function performWork(request) {
3158
3809
  var prevDispatcher = ReactSharedInternals.H;
3159
3810
  ReactSharedInternals.H = HooksDispatcher;
@@ -3528,9 +4179,12 @@ function loadChunk(chunkId, filename) {
3528
4179
  return __webpack_chunk_load__(chunkId);
3529
4180
  }
3530
4181
 
3531
- // The server acts as a Client of itself when resolving Server References.
4182
+ // $FlowFixMe[method-unbinding]
4183
+ var hasOwnProperty = Object.prototype.hasOwnProperty;
4184
+
3532
4185
  var PENDING = 'pending';
3533
4186
  var BLOCKED = 'blocked';
4187
+ var CYCLIC = 'cyclic';
3534
4188
  var RESOLVED_MODEL = 'resolved_model';
3535
4189
  var INITIALIZED = 'fulfilled';
3536
4190
  var ERRORED = 'rejected'; // $FlowFixMe[missing-this-annot]
@@ -3563,6 +4217,7 @@ Chunk.prototype.then = function (resolve, reject) {
3563
4217
 
3564
4218
  case PENDING:
3565
4219
  case BLOCKED:
4220
+ case CYCLIC:
3566
4221
  if (resolve) {
3567
4222
  if (chunk.value === null) {
3568
4223
  chunk.value = [];
@@ -3604,9 +4259,39 @@ function wakeChunk(listeners, value) {
3604
4259
  }
3605
4260
  }
3606
4261
 
4262
+ function wakeChunkIfInitialized(chunk, resolveListeners, rejectListeners) {
4263
+ switch (chunk.status) {
4264
+ case INITIALIZED:
4265
+ wakeChunk(resolveListeners, chunk.value);
4266
+ break;
4267
+
4268
+ case PENDING:
4269
+ case BLOCKED:
4270
+ case CYCLIC:
4271
+ chunk.value = resolveListeners;
4272
+ chunk.reason = rejectListeners;
4273
+ break;
4274
+
4275
+ case ERRORED:
4276
+ if (rejectListeners) {
4277
+ wakeChunk(rejectListeners, chunk.reason);
4278
+ }
4279
+
4280
+ break;
4281
+ }
4282
+ }
4283
+
3607
4284
  function triggerErrorOnChunk(chunk, error) {
3608
4285
  if (chunk.status !== PENDING && chunk.status !== BLOCKED) {
3609
- // We already resolved. We didn't expect to see this.
4286
+ {
4287
+ // If we get more data to an already resolved ID, we assume that it's
4288
+ // a stream chunk since any other row shouldn't have more than one entry.
4289
+ var streamChunk = chunk;
4290
+ var controller = streamChunk.reason; // $FlowFixMe[incompatible-call]: The error method should accept mixed.
4291
+
4292
+ controller.error(error);
4293
+ }
4294
+
3610
4295
  return;
3611
4296
  }
3612
4297
 
@@ -3620,9 +4305,64 @@ function triggerErrorOnChunk(chunk, error) {
3620
4305
  }
3621
4306
  }
3622
4307
 
3623
- function createResolvedModelChunk(response, value) {
4308
+ function createResolvedModelChunk(response, value, id) {
4309
+ // $FlowFixMe[invalid-constructor] Flow doesn't support functions as constructors
4310
+ return new Chunk(RESOLVED_MODEL, value, id, response);
4311
+ }
4312
+
4313
+ function resolveModelChunk(chunk, value, id) {
4314
+ if (chunk.status !== PENDING) {
4315
+ {
4316
+ // If we get more data to an already resolved ID, we assume that it's
4317
+ // a stream chunk since any other row shouldn't have more than one entry.
4318
+ var streamChunk = chunk;
4319
+ var controller = streamChunk.reason;
4320
+
4321
+ if (value[0] === 'C') {
4322
+ controller.close(value === 'C' ? '"$undefined"' : value.slice(1));
4323
+ } else {
4324
+ controller.enqueueModel(value);
4325
+ }
4326
+ }
4327
+
4328
+ return;
4329
+ }
4330
+
4331
+ var resolveListeners = chunk.value;
4332
+ var rejectListeners = chunk.reason;
4333
+ var resolvedChunk = chunk;
4334
+ resolvedChunk.status = RESOLVED_MODEL;
4335
+ resolvedChunk.value = value;
4336
+ resolvedChunk.reason = id;
4337
+
4338
+ if (resolveListeners !== null) {
4339
+ // This is unfortunate that we're reading this eagerly if
4340
+ // we already have listeners attached since they might no
4341
+ // longer be rendered or might not be the highest pri.
4342
+ initializeModelChunk(resolvedChunk); // The status might have changed after initialization.
4343
+
4344
+ wakeChunkIfInitialized(chunk, resolveListeners, rejectListeners);
4345
+ }
4346
+ }
4347
+
4348
+ function createInitializedStreamChunk(response, value, controller) {
4349
+ // We use the reason field to stash the controller since we already have that
4350
+ // field. It's a bit of a hack but efficient.
3624
4351
  // $FlowFixMe[invalid-constructor] Flow doesn't support functions as constructors
3625
- return new Chunk(RESOLVED_MODEL, value, null, response);
4352
+ return new Chunk(INITIALIZED, value, controller, response);
4353
+ }
4354
+
4355
+ function createResolvedIteratorResultChunk(response, value, done) {
4356
+ // To reuse code as much code as possible we add the wrapper element as part of the JSON.
4357
+ var iteratorResultJSON = (done ? '{"done":true,"value":' : '{"done":false,"value":') + value + '}'; // $FlowFixMe[invalid-constructor] Flow doesn't support functions as constructors
4358
+
4359
+ return new Chunk(RESOLVED_MODEL, iteratorResultJSON, -1, response);
4360
+ }
4361
+
4362
+ function resolveIteratorResultChunk(chunk, value, done) {
4363
+ // To reuse code as much code as possible we add the wrapper element as part of the JSON.
4364
+ var iteratorResultJSON = (done ? '{"done":true,"value":' : '{"done":false,"value":') + value + '}';
4365
+ resolveModelChunk(chunk, iteratorResultJSON, -1);
3626
4366
  }
3627
4367
 
3628
4368
  function bindArgs$1(fn, args) {
@@ -3653,11 +4393,51 @@ function loadServerReference$1(response, id, bound, parentChunk, parentObject, k
3653
4393
  }
3654
4394
  }
3655
4395
 
3656
- promise.then(createModelResolver(parentChunk, parentObject, key), createModelReject(parentChunk)); // We need a placeholder value that will be replaced later.
4396
+ promise.then(createModelResolver(parentChunk, parentObject, key, false, response, createModel, []), createModelReject(parentChunk)); // We need a placeholder value that will be replaced later.
3657
4397
 
3658
4398
  return null;
3659
4399
  }
3660
4400
 
4401
+ function reviveModel(response, parentObj, parentKey, value, reference) {
4402
+ if (typeof value === 'string') {
4403
+ // We can't use .bind here because we need the "this" value.
4404
+ return parseModelString(response, parentObj, parentKey, value, reference);
4405
+ }
4406
+
4407
+ if (typeof value === 'object' && value !== null) {
4408
+ if (reference !== undefined && response._temporaryReferences !== undefined) {
4409
+ // Store this object's reference in case it's returned later.
4410
+ registerTemporaryReference(response._temporaryReferences, value, reference);
4411
+ }
4412
+
4413
+ if (Array.isArray(value)) {
4414
+ for (var i = 0; i < value.length; i++) {
4415
+ var childRef = reference !== undefined ? reference + ':' + i : undefined; // $FlowFixMe[cannot-write]
4416
+
4417
+ value[i] = reviveModel(response, value, '' + i, value[i], childRef);
4418
+ }
4419
+ } else {
4420
+ for (var key in value) {
4421
+ if (hasOwnProperty.call(value, key)) {
4422
+ var _childRef = reference !== undefined && key.indexOf(':') === -1 ? reference + ':' + key : undefined;
4423
+
4424
+ var newValue = reviveModel(response, value, key, value[key], _childRef);
4425
+
4426
+ if (newValue !== undefined) {
4427
+ // $FlowFixMe[cannot-write]
4428
+ value[key] = newValue;
4429
+ } else {
4430
+ // $FlowFixMe[cannot-write]
4431
+ delete value[key];
4432
+ }
4433
+ }
4434
+ }
4435
+ }
4436
+ }
4437
+
4438
+ return value;
4439
+ }
4440
+
3661
4441
  var initializingChunk = null;
3662
4442
  var initializingChunkBlockedModel = null;
3663
4443
 
@@ -3666,9 +4446,21 @@ function initializeModelChunk(chunk) {
3666
4446
  var prevBlocked = initializingChunkBlockedModel;
3667
4447
  initializingChunk = chunk;
3668
4448
  initializingChunkBlockedModel = null;
4449
+ var rootReference = chunk.reason === -1 ? undefined : chunk.reason.toString(16);
4450
+ var resolvedModel = chunk.value; // We go to the CYCLIC state until we've fully resolved this.
4451
+ // We do this before parsing in case we try to initialize the same chunk
4452
+ // while parsing the model. Such as in a cyclic reference.
4453
+
4454
+ var cyclicChunk = chunk;
4455
+ cyclicChunk.status = CYCLIC;
4456
+ cyclicChunk.value = null;
4457
+ cyclicChunk.reason = null;
3669
4458
 
3670
4459
  try {
3671
- var value = JSON.parse(chunk.value, chunk._response._fromJSON);
4460
+ var rawModel = JSON.parse(resolvedModel);
4461
+ var value = reviveModel(chunk._response, {
4462
+ '': rawModel
4463
+ }, '', rawModel, rootReference);
3672
4464
 
3673
4465
  if (initializingChunkBlockedModel !== null && initializingChunkBlockedModel.deps > 0) {
3674
4466
  initializingChunkBlockedModel.value = value; // We discovered new dependencies on modules that are not yet resolved.
@@ -3679,9 +4471,14 @@ function initializeModelChunk(chunk) {
3679
4471
  blockedChunk.value = null;
3680
4472
  blockedChunk.reason = null;
3681
4473
  } else {
4474
+ var resolveListeners = cyclicChunk.value;
3682
4475
  var initializedChunk = chunk;
3683
4476
  initializedChunk.status = INITIALIZED;
3684
4477
  initializedChunk.value = value;
4478
+
4479
+ if (resolveListeners !== null) {
4480
+ wakeChunk(resolveListeners, value);
4481
+ }
3685
4482
  }
3686
4483
  } catch (error) {
3687
4484
  var erroredChunk = chunk;
@@ -3718,7 +4515,7 @@ function getChunk(response, id) {
3718
4515
 
3719
4516
  if (backingEntry != null) {
3720
4517
  // We assume that this is a string entry for now.
3721
- chunk = createResolvedModelChunk(response, backingEntry);
4518
+ chunk = createResolvedModelChunk(response, backingEntry, id);
3722
4519
  } else {
3723
4520
  // We're still waiting on this entry to stream in.
3724
4521
  chunk = createPendingChunk(response);
@@ -3730,21 +4527,34 @@ function getChunk(response, id) {
3730
4527
  return chunk;
3731
4528
  }
3732
4529
 
3733
- function createModelResolver(chunk, parentObject, key) {
4530
+ function createModelResolver(chunk, parentObject, key, cyclic, response, map, path) {
3734
4531
  var blocked;
3735
4532
 
3736
4533
  if (initializingChunkBlockedModel) {
3737
4534
  blocked = initializingChunkBlockedModel;
3738
- blocked.deps++;
4535
+
4536
+ if (!cyclic) {
4537
+ blocked.deps++;
4538
+ }
3739
4539
  } else {
3740
4540
  blocked = initializingChunkBlockedModel = {
3741
- deps: 1,
4541
+ deps: cyclic ? 0 : 1,
3742
4542
  value: null
3743
4543
  };
3744
4544
  }
3745
4545
 
3746
4546
  return function (value) {
3747
- parentObject[key] = value;
4547
+ for (var i = 1; i < path.length; i++) {
4548
+ value = value[path[i]];
4549
+ }
4550
+
4551
+ parentObject[key] = map(response, value); // If this is the root object for a model reference, where `blocked.value`
4552
+ // is a stale `null`, the resolved value can be used directly.
4553
+
4554
+ if (key === '' && blocked.value === null) {
4555
+ blocked.value = parentObject[key];
4556
+ }
4557
+
3748
4558
  blocked.deps--;
3749
4559
 
3750
4560
  if (blocked.deps === 0) {
@@ -3770,22 +4580,271 @@ function createModelReject(chunk) {
3770
4580
  };
3771
4581
  }
3772
4582
 
3773
- function getOutlinedModel(response, id) {
4583
+ function getOutlinedModel(response, reference, parentObject, key, map) {
4584
+ var path = reference.split(':');
4585
+ var id = parseInt(path[0], 16);
3774
4586
  var chunk = getChunk(response, id);
3775
4587
 
3776
- if (chunk.status === RESOLVED_MODEL) {
3777
- initializeModelChunk(chunk);
4588
+ switch (chunk.status) {
4589
+ case RESOLVED_MODEL:
4590
+ initializeModelChunk(chunk);
4591
+ break;
4592
+ } // The status might have changed after initialization.
4593
+
4594
+
4595
+ switch (chunk.status) {
4596
+ case INITIALIZED:
4597
+ var value = chunk.value;
4598
+
4599
+ for (var i = 1; i < path.length; i++) {
4600
+ value = value[path[i]];
4601
+ }
4602
+
4603
+ return map(response, value);
4604
+
4605
+ case PENDING:
4606
+ case BLOCKED:
4607
+ case CYCLIC:
4608
+ var parentChunk = initializingChunk;
4609
+ chunk.then(createModelResolver(parentChunk, parentObject, key, chunk.status === CYCLIC, response, map, path), createModelReject(parentChunk));
4610
+ return null;
4611
+
4612
+ default:
4613
+ throw chunk.reason;
3778
4614
  }
4615
+ }
4616
+
4617
+ function createMap(response, model) {
4618
+ return new Map(model);
4619
+ }
4620
+
4621
+ function createSet(response, model) {
4622
+ return new Set(model);
4623
+ }
4624
+
4625
+ function extractIterator(response, model) {
4626
+ // $FlowFixMe[incompatible-use]: This uses raw Symbols because we're extracting from a native array.
4627
+ return model[Symbol.iterator]();
4628
+ }
4629
+
4630
+ function createModel(response, model) {
4631
+ return model;
4632
+ }
4633
+
4634
+ function parseTypedArray(response, reference, constructor, bytesPerElement, parentObject, parentKey) {
4635
+ var id = parseInt(reference.slice(2), 16);
4636
+ var prefix = response._prefix;
4637
+ var key = prefix + id; // We should have this backingEntry in the store already because we emitted
4638
+ // it before referencing it. It should be a Blob.
4639
+
4640
+ var backingEntry = response._formData.get(key);
4641
+
4642
+ var promise = constructor === ArrayBuffer ? backingEntry.arrayBuffer() : backingEntry.arrayBuffer().then(function (buffer) {
4643
+ return new constructor(buffer);
4644
+ }); // Since loading the buffer is an async operation we'll be blocking the parent
4645
+ // chunk.
4646
+
4647
+ var parentChunk = initializingChunk;
4648
+ promise.then(createModelResolver(parentChunk, parentObject, parentKey, false, response, createModel, []), createModelReject(parentChunk));
4649
+ return null;
4650
+ }
4651
+
4652
+ function resolveStream(response, id, stream, controller) {
4653
+ var chunks = response._chunks;
4654
+ var chunk = createInitializedStreamChunk(response, stream, controller);
4655
+ chunks.set(id, chunk);
4656
+ var prefix = response._prefix;
4657
+ var key = prefix + id;
4658
+
4659
+ var existingEntries = response._formData.getAll(key);
4660
+
4661
+ for (var i = 0; i < existingEntries.length; i++) {
4662
+ // We assume that this is a string entry for now.
4663
+ var value = existingEntries[i];
3779
4664
 
3780
- if (chunk.status !== INITIALIZED) {
3781
- // We know that this is emitted earlier so otherwise it's an error.
3782
- throw chunk.reason;
4665
+ if (value[0] === 'C') {
4666
+ controller.close(value === 'C' ? '"$undefined"' : value.slice(1));
4667
+ } else {
4668
+ controller.enqueueModel(value);
4669
+ }
3783
4670
  }
4671
+ }
4672
+
4673
+ function parseReadableStream(response, reference, type, parentObject, parentKey) {
4674
+ var id = parseInt(reference.slice(2), 16);
4675
+ var controller = null;
4676
+ var stream = new ReadableStream({
4677
+ type: type,
4678
+ start: function (c) {
4679
+ controller = c;
4680
+ }
4681
+ });
4682
+ var previousBlockedChunk = null;
4683
+ var flightController = {
4684
+ enqueueModel: function (json) {
4685
+ if (previousBlockedChunk === null) {
4686
+ // If we're not blocked on any other chunks, we can try to eagerly initialize
4687
+ // this as a fast-path to avoid awaiting them.
4688
+ var chunk = createResolvedModelChunk(response, json, -1);
4689
+ initializeModelChunk(chunk);
4690
+ var initializedChunk = chunk;
4691
+
4692
+ if (initializedChunk.status === INITIALIZED) {
4693
+ controller.enqueue(initializedChunk.value);
4694
+ } else {
4695
+ chunk.then(function (v) {
4696
+ return controller.enqueue(v);
4697
+ }, function (e) {
4698
+ return controller.error(e);
4699
+ });
4700
+ previousBlockedChunk = chunk;
4701
+ }
4702
+ } else {
4703
+ // We're still waiting on a previous chunk so we can't enqueue quite yet.
4704
+ var blockedChunk = previousBlockedChunk;
4705
+
4706
+ var _chunk = createPendingChunk(response);
4707
+
4708
+ _chunk.then(function (v) {
4709
+ return controller.enqueue(v);
4710
+ }, function (e) {
4711
+ return controller.error(e);
4712
+ });
4713
+
4714
+ previousBlockedChunk = _chunk;
4715
+ blockedChunk.then(function () {
4716
+ if (previousBlockedChunk === _chunk) {
4717
+ // We were still the last chunk so we can now clear the queue and return
4718
+ // to synchronous emitting.
4719
+ previousBlockedChunk = null;
4720
+ }
4721
+
4722
+ resolveModelChunk(_chunk, json, -1);
4723
+ });
4724
+ }
4725
+ },
4726
+ close: function (json) {
4727
+ if (previousBlockedChunk === null) {
4728
+ controller.close();
4729
+ } else {
4730
+ var blockedChunk = previousBlockedChunk; // We shouldn't get any more enqueues after this so we can set it back to null.
4731
+
4732
+ previousBlockedChunk = null;
4733
+ blockedChunk.then(function () {
4734
+ return controller.close();
4735
+ });
4736
+ }
4737
+ },
4738
+ error: function (error) {
4739
+ if (previousBlockedChunk === null) {
4740
+ // $FlowFixMe[incompatible-call]
4741
+ controller.error(error);
4742
+ } else {
4743
+ var blockedChunk = previousBlockedChunk; // We shouldn't get any more enqueues after this so we can set it back to null.
3784
4744
 
3785
- return chunk.value;
4745
+ previousBlockedChunk = null;
4746
+ blockedChunk.then(function () {
4747
+ return controller.error(error);
4748
+ });
4749
+ }
4750
+ }
4751
+ };
4752
+ resolveStream(response, id, stream, flightController);
4753
+ return stream;
3786
4754
  }
3787
4755
 
3788
- function parseModelString(response, obj, key, value) {
4756
+ function asyncIterator() {
4757
+ // Self referencing iterator.
4758
+ return this;
4759
+ }
4760
+
4761
+ function createIterator(next) {
4762
+ var iterator = {
4763
+ next: next // TODO: Add return/throw as options for aborting.
4764
+
4765
+ }; // TODO: The iterator could inherit the AsyncIterator prototype which is not exposed as
4766
+ // a global but exists as a prototype of an AsyncGenerator. However, it's not needed
4767
+ // to satisfy the iterable protocol.
4768
+
4769
+ iterator[ASYNC_ITERATOR] = asyncIterator;
4770
+ return iterator;
4771
+ }
4772
+
4773
+ function parseAsyncIterable(response, reference, iterator, parentObject, parentKey) {
4774
+ var id = parseInt(reference.slice(2), 16);
4775
+ var buffer = [];
4776
+ var closed = false;
4777
+ var nextWriteIndex = 0;
4778
+ var flightController = {
4779
+ enqueueModel: function (value) {
4780
+ if (nextWriteIndex === buffer.length) {
4781
+ buffer[nextWriteIndex] = createResolvedIteratorResultChunk(response, value, false);
4782
+ } else {
4783
+ resolveIteratorResultChunk(buffer[nextWriteIndex], value, false);
4784
+ }
4785
+
4786
+ nextWriteIndex++;
4787
+ },
4788
+ close: function (value) {
4789
+ closed = true;
4790
+
4791
+ if (nextWriteIndex === buffer.length) {
4792
+ buffer[nextWriteIndex] = createResolvedIteratorResultChunk(response, value, true);
4793
+ } else {
4794
+ resolveIteratorResultChunk(buffer[nextWriteIndex], value, true);
4795
+ }
4796
+
4797
+ nextWriteIndex++;
4798
+
4799
+ while (nextWriteIndex < buffer.length) {
4800
+ // In generators, any extra reads from the iterator have the value undefined.
4801
+ resolveIteratorResultChunk(buffer[nextWriteIndex++], '"$undefined"', true);
4802
+ }
4803
+ },
4804
+ error: function (error) {
4805
+ closed = true;
4806
+
4807
+ if (nextWriteIndex === buffer.length) {
4808
+ buffer[nextWriteIndex] = createPendingChunk(response);
4809
+ }
4810
+
4811
+ while (nextWriteIndex < buffer.length) {
4812
+ triggerErrorOnChunk(buffer[nextWriteIndex++], error);
4813
+ }
4814
+ }
4815
+ };
4816
+
4817
+ var iterable = _defineProperty({}, ASYNC_ITERATOR, function () {
4818
+ var nextReadIndex = 0;
4819
+ return createIterator(function (arg) {
4820
+ if (arg !== undefined) {
4821
+ throw new Error('Values cannot be passed to next() of AsyncIterables passed to Client Components.');
4822
+ }
4823
+
4824
+ if (nextReadIndex === buffer.length) {
4825
+ if (closed) {
4826
+ // $FlowFixMe[invalid-constructor] Flow doesn't support functions as constructors
4827
+ return new Chunk(INITIALIZED, {
4828
+ done: true,
4829
+ value: undefined
4830
+ }, null, response);
4831
+ }
4832
+
4833
+ buffer[nextReadIndex] = createPendingChunk(response);
4834
+ }
4835
+
4836
+ return buffer[nextReadIndex++];
4837
+ });
4838
+ }); // TODO: If it's a single shot iterator we can optimize memory by cleaning up the buffer after
4839
+ // reading through the end, but currently we favor code size over this optimization.
4840
+
4841
+
4842
+ var stream = iterator ? iterable[ASYNC_ITERATOR]() : iterable;
4843
+ resolveStream(response, id, stream, flightController);
4844
+ return stream;
4845
+ }
4846
+
4847
+ function parseModelString(response, obj, key, value, reference) {
3789
4848
  if (value[0] === '$') {
3790
4849
  switch (value[1]) {
3791
4850
  case '$':
@@ -3797,46 +4856,45 @@ function parseModelString(response, obj, key, value) {
3797
4856
  case '@':
3798
4857
  {
3799
4858
  // Promise
3800
- var _id = parseInt(value.slice(2), 16);
3801
-
3802
- var _chunk = getChunk(response, _id);
3803
-
3804
- return _chunk;
4859
+ var id = parseInt(value.slice(2), 16);
4860
+ var chunk = getChunk(response, id);
4861
+ return chunk;
3805
4862
  }
3806
4863
 
3807
4864
  case 'F':
3808
4865
  {
3809
4866
  // Server Reference
3810
- var _id2 = parseInt(value.slice(2), 16); // TODO: Just encode this in the reference inline instead of as a model.
4867
+ var _ref2 = value.slice(2); // TODO: Just encode this in the reference inline instead of as a model.
3811
4868
 
3812
4869
 
3813
- var metaData = getOutlinedModel(response, _id2);
4870
+ var metaData = getOutlinedModel(response, _ref2, obj, key, createModel);
3814
4871
  return loadServerReference$1(response, metaData.id, metaData.bound, initializingChunk, obj, key);
3815
4872
  }
3816
4873
 
3817
4874
  case 'T':
3818
4875
  {
3819
4876
  // Temporary Reference
3820
- return createTemporaryReference(value.slice(2));
4877
+ if (reference === undefined || response._temporaryReferences === undefined) {
4878
+ throw new Error('Could not reference an opaque temporary reference. ' + 'This is likely due to misconfiguring the temporaryReferences options ' + 'on the server.');
4879
+ }
4880
+
4881
+ return createTemporaryReference(response._temporaryReferences, reference);
3821
4882
  }
3822
4883
 
3823
4884
  case 'Q':
3824
4885
  {
3825
4886
  // Map
3826
- var _id3 = parseInt(value.slice(2), 16);
4887
+ var _ref3 = value.slice(2);
3827
4888
 
3828
- var data = getOutlinedModel(response, _id3);
3829
- return new Map(data);
4889
+ return getOutlinedModel(response, _ref3, obj, key, createMap);
3830
4890
  }
3831
4891
 
3832
4892
  case 'W':
3833
4893
  {
3834
4894
  // Set
3835
- var _id4 = parseInt(value.slice(2), 16);
3836
-
3837
- var _data = getOutlinedModel(response, _id4);
4895
+ var _ref4 = value.slice(2);
3838
4896
 
3839
- return new Set(_data);
4897
+ return getOutlinedModel(response, _ref4, obj, key, createSet);
3840
4898
  }
3841
4899
 
3842
4900
  case 'K':
@@ -3844,9 +4902,7 @@ function parseModelString(response, obj, key, value) {
3844
4902
  // FormData
3845
4903
  var stringId = value.slice(2);
3846
4904
  var formPrefix = response._prefix + stringId + '_';
3847
-
3848
- var _data2 = new FormData();
3849
-
4905
+ var data = new FormData();
3850
4906
  var backingFormData = response._formData; // We assume that the reference to FormData always comes after each
3851
4907
  // entry that it references so we can assume they all exist in the
3852
4908
  // backing store already.
@@ -3854,20 +4910,18 @@ function parseModelString(response, obj, key, value) {
3854
4910
 
3855
4911
  backingFormData.forEach(function (entry, entryKey) {
3856
4912
  if (entryKey.startsWith(formPrefix)) {
3857
- _data2.append(entryKey.slice(formPrefix.length), entry);
4913
+ data.append(entryKey.slice(formPrefix.length), entry);
3858
4914
  }
3859
4915
  });
3860
- return _data2;
4916
+ return data;
3861
4917
  }
3862
4918
 
3863
4919
  case 'i':
3864
4920
  {
3865
4921
  // Iterator
3866
- var _id5 = parseInt(value.slice(2), 16);
3867
-
3868
- var _data3 = getOutlinedModel(response, _id5);
4922
+ var _ref5 = value.slice(2);
3869
4923
 
3870
- return _data3[Symbol.iterator]();
4924
+ return getOutlinedModel(response, _ref5, obj, key, extractIterator);
3871
4925
  }
3872
4926
 
3873
4927
  case 'I':
@@ -3912,51 +4966,104 @@ function parseModelString(response, obj, key, value) {
3912
4966
  }
3913
4967
  }
3914
4968
 
4969
+ {
4970
+ switch (value[1]) {
4971
+ case 'A':
4972
+ return parseTypedArray(response, value, ArrayBuffer, 1, obj, key);
3915
4973
 
3916
- var id = parseInt(value.slice(1), 16);
3917
- var chunk = getChunk(response, id);
4974
+ case 'O':
4975
+ return parseTypedArray(response, value, Int8Array, 1, obj, key);
3918
4976
 
3919
- switch (chunk.status) {
3920
- case RESOLVED_MODEL:
3921
- initializeModelChunk(chunk);
3922
- break;
3923
- } // The status might have changed after initialization.
4977
+ case 'o':
4978
+ return parseTypedArray(response, value, Uint8Array, 1, obj, key);
3924
4979
 
4980
+ case 'U':
4981
+ return parseTypedArray(response, value, Uint8ClampedArray, 1, obj, key);
4982
+
4983
+ case 'S':
4984
+ return parseTypedArray(response, value, Int16Array, 2, obj, key);
4985
+
4986
+ case 's':
4987
+ return parseTypedArray(response, value, Uint16Array, 2, obj, key);
4988
+
4989
+ case 'L':
4990
+ return parseTypedArray(response, value, Int32Array, 4, obj, key);
4991
+
4992
+ case 'l':
4993
+ return parseTypedArray(response, value, Uint32Array, 4, obj, key);
4994
+
4995
+ case 'G':
4996
+ return parseTypedArray(response, value, Float32Array, 4, obj, key);
4997
+
4998
+ case 'g':
4999
+ return parseTypedArray(response, value, Float64Array, 8, obj, key);
5000
+
5001
+ case 'M':
5002
+ return parseTypedArray(response, value, BigInt64Array, 8, obj, key);
5003
+
5004
+ case 'm':
5005
+ return parseTypedArray(response, value, BigUint64Array, 8, obj, key);
5006
+
5007
+ case 'V':
5008
+ return parseTypedArray(response, value, DataView, 1, obj, key);
5009
+
5010
+ case 'B':
5011
+ {
5012
+ // Blob
5013
+ var _id = parseInt(value.slice(2), 16);
3925
5014
 
3926
- switch (chunk.status) {
3927
- case INITIALIZED:
3928
- return chunk.value;
5015
+ var prefix = response._prefix;
5016
+ var blobKey = prefix + _id; // We should have this backingEntry in the store already because we emitted
5017
+ // it before referencing it. It should be a Blob.
3929
5018
 
3930
- case PENDING:
3931
- case BLOCKED:
3932
- var parentChunk = initializingChunk;
3933
- chunk.then(createModelResolver(parentChunk, obj, key), createModelReject(parentChunk));
3934
- return null;
5019
+ var backingEntry = response._formData.get(blobKey);
3935
5020
 
3936
- default:
3937
- throw chunk.reason;
5021
+ return backingEntry;
5022
+ }
5023
+ }
3938
5024
  }
5025
+
5026
+ {
5027
+ switch (value[1]) {
5028
+ case 'R':
5029
+ {
5030
+ return parseReadableStream(response, value, undefined);
5031
+ }
5032
+
5033
+ case 'r':
5034
+ {
5035
+ return parseReadableStream(response, value, 'bytes');
5036
+ }
5037
+
5038
+ case 'X':
5039
+ {
5040
+ return parseAsyncIterable(response, value, false);
5041
+ }
5042
+
5043
+ case 'x':
5044
+ {
5045
+ return parseAsyncIterable(response, value, true);
5046
+ }
5047
+ }
5048
+ } // We assume that anything else is a reference ID.
5049
+
5050
+
5051
+ var ref = value.slice(1);
5052
+ return getOutlinedModel(response, ref, obj, key, createModel);
3939
5053
  }
3940
5054
 
3941
5055
  return value;
3942
5056
  }
3943
5057
 
3944
- function createResponse(bundlerConfig, formFieldPrefix) {
3945
- var backingFormData = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : new FormData();
5058
+ function createResponse(bundlerConfig, formFieldPrefix, temporaryReferences) {
5059
+ var backingFormData = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : new FormData();
3946
5060
  var chunks = new Map();
3947
5061
  var response = {
3948
5062
  _bundlerConfig: bundlerConfig,
3949
5063
  _prefix: formFieldPrefix,
3950
5064
  _formData: backingFormData,
3951
5065
  _chunks: chunks,
3952
- _fromJSON: function (key, value) {
3953
- if (typeof value === 'string') {
3954
- // We can't use .bind here because we need the "this" value.
3955
- return parseModelString(response, this, key, value);
3956
- }
3957
-
3958
- return value;
3959
- }
5066
+ _temporaryReferences: temporaryReferences
3960
5067
  };
3961
5068
  return response;
3962
5069
  }
@@ -3996,7 +5103,7 @@ function loadServerReference(bundlerConfig, id, bound) {
3996
5103
 
3997
5104
  function decodeBoundActionMetaData(body, serverManifest, formFieldPrefix) {
3998
5105
  // The data for this reference is encoded in multiple fields under this prefix.
3999
- var actionResponse = createResponse(serverManifest, formFieldPrefix, body);
5106
+ var actionResponse = createResponse(serverManifest, formFieldPrefix, undefined, body);
4000
5107
  close(actionResponse);
4001
5108
  var refPromise = getRoot(actionResponse); // Force it to initialize
4002
5109
  // $FlowFixMe
@@ -4091,7 +5198,7 @@ function decodeFormState(actionResult, body, serverManifest) {
4091
5198
  }
4092
5199
 
4093
5200
  function renderToReadableStream(model, webpackMap, options) {
4094
- var request = createRequest(model, webpackMap, options ? options.onError : undefined, options ? options.identifierPrefix : undefined, options ? options.onPostpone : undefined, options ? options.environmentName : undefined);
5201
+ 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);
4095
5202
 
4096
5203
  if (options && options.signal) {
4097
5204
  var signal = options.signal;
@@ -4127,20 +5234,21 @@ function renderToReadableStream(model, webpackMap, options) {
4127
5234
  return stream;
4128
5235
  }
4129
5236
 
4130
- function decodeReply(body, webpackMap) {
5237
+ function decodeReply(body, webpackMap, options) {
4131
5238
  if (typeof body === 'string') {
4132
5239
  var form = new FormData();
4133
5240
  form.append('0', body);
4134
5241
  body = form;
4135
5242
  }
4136
5243
 
4137
- var response = createResponse(webpackMap, '', body);
5244
+ var response = createResponse(webpackMap, '', options ? options.temporaryReferences : undefined, body);
4138
5245
  var root = getRoot(response);
4139
5246
  close(response);
4140
5247
  return root;
4141
5248
  }
4142
5249
 
4143
5250
  exports.createClientModuleProxy = createClientModuleProxy;
5251
+ exports.createTemporaryReferenceSet = createTemporaryReferenceSet;
4144
5252
  exports.decodeAction = decodeAction;
4145
5253
  exports.decodeFormState = decodeFormState;
4146
5254
  exports.decodeReply = decodeReply;