react-server-dom-webpack 19.0.0-beta-04b058868c-20240508 → 19.0.0-beta-9d76c954cf-20240510

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') {
@@ -770,11 +783,14 @@ var componentStorage = null;
770
783
 
771
784
  var TEMPORARY_REFERENCE_TAG = Symbol.for('react.temporary.reference'); // eslint-disable-next-line no-unused-vars
772
785
 
773
- function isTemporaryReference(reference) {
786
+ function createTemporaryReferenceSet() {
787
+ return new WeakMap();
788
+ }
789
+ function isOpaqueTemporaryReference(reference) {
774
790
  return reference.$$typeof === TEMPORARY_REFERENCE_TAG;
775
791
  }
776
- function resolveTemporaryReferenceID(temporaryReference) {
777
- return temporaryReference.$$id;
792
+ function resolveTemporaryReference(temporaryReferences, temporaryReference) {
793
+ return temporaryReferences.get(temporaryReference);
778
794
  }
779
795
  var proxyHandlers = {
780
796
  get: function (target, name, receiver) {
@@ -785,12 +801,6 @@ var proxyHandlers = {
785
801
  // have the Flight runtime extract the inner target instead.
786
802
  return target.$$typeof;
787
803
 
788
- case '$$id':
789
- return target.$$id;
790
-
791
- case '$$async':
792
- return target.$$async;
793
-
794
804
  case 'name':
795
805
  return undefined;
796
806
 
@@ -825,21 +835,28 @@ var proxyHandlers = {
825
835
  throw new Error('Cannot assign to a temporary client reference from a server module.');
826
836
  }
827
837
  };
828
- function createTemporaryReference(id) {
838
+ function createTemporaryReference(temporaryReferences, id) {
829
839
  var reference = Object.defineProperties(function () {
830
840
  throw new Error( // eslint-disable-next-line react-internal/safe-string-coercion
831
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.");
832
842
  }, {
833
843
  $$typeof: {
834
844
  value: TEMPORARY_REFERENCE_TAG
835
- },
836
- $$id: {
837
- value: id
838
845
  }
839
846
  });
840
- return new Proxy(reference, proxyHandlers);
847
+ var wrapper = new Proxy(reference, proxyHandlers);
848
+ registerTemporaryReference(temporaryReferences, wrapper, id);
849
+ return wrapper;
841
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.
842
858
 
859
+ var REACT_LEGACY_ELEMENT_TYPE = Symbol.for('react.element');
843
860
  var REACT_ELEMENT_TYPE = Symbol.for('react.transitional.element') ;
844
861
  var REACT_FRAGMENT_TYPE = Symbol.for('react.fragment');
845
862
  var REACT_CONTEXT_TYPE = Symbol.for('react.context');
@@ -865,6 +882,7 @@ function getIteratorFn(maybeIterable) {
865
882
 
866
883
  return null;
867
884
  }
885
+ var ASYNC_ITERATOR = Symbol.asyncIterator;
868
886
 
869
887
  // Corresponds to ReactFiberWakeable and ReactFizzWakeable modules. Generally,
870
888
  // changes to one module should be reflected in the others.
@@ -1500,10 +1518,7 @@ var stringify = JSON.stringify; // Serializable values
1500
1518
  var PENDING$1 = 0;
1501
1519
  var COMPLETED = 1;
1502
1520
  var ABORTED = 3;
1503
- var ERRORED$1 = 4; // object reference status
1504
-
1505
- var SEEN_BUT_NOT_YET_OUTLINED = -1;
1506
- var NEVER_OUTLINED = -2;
1521
+ var ERRORED$1 = 4;
1507
1522
 
1508
1523
  function defaultErrorHandler(error) {
1509
1524
  console['error'](error); // Don't transform to our wrapper
@@ -1515,7 +1530,7 @@ function defaultPostponeHandler(reason) {// Noop
1515
1530
  var OPEN = 0;
1516
1531
  var CLOSING = 1;
1517
1532
  var CLOSED = 2;
1518
- function createRequest(model, bundlerConfig, onError, identifierPrefix, onPostpone, environmentName) {
1533
+ function createRequest(model, bundlerConfig, onError, identifierPrefix, onPostpone, environmentName, temporaryReferences) {
1519
1534
  if (ReactSharedInternals.A !== null && ReactSharedInternals.A !== DefaultAsyncDispatcher) {
1520
1535
  throw new Error('Currently React only supports one RSC renderer at a time.');
1521
1536
  }
@@ -1547,6 +1562,7 @@ function createRequest(model, bundlerConfig, onError, identifierPrefix, onPostpo
1547
1562
  writtenClientReferences: new Map(),
1548
1563
  writtenServerReferences: new Map(),
1549
1564
  writtenObjects: new WeakMap(),
1565
+ temporaryReferences: temporaryReferences,
1550
1566
  identifierPrefix: identifierPrefix || '',
1551
1567
  identifierCount: 1,
1552
1568
  taintCleanupQueue: cleanupQueue,
@@ -1649,6 +1665,192 @@ function serializeThenable(request, task, thenable) {
1649
1665
  return newTask.id;
1650
1666
  }
1651
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
+
1652
1854
  function emitHint(request, code, model) {
1653
1855
  emitHintChunk(request, code, model);
1654
1856
  enqueueFlush(request);
@@ -1720,16 +1922,42 @@ function createLazyWrapperAroundWakeable(wakeable) {
1720
1922
  }
1721
1923
 
1722
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);
1723
1951
  }
1724
1952
 
1725
- function renderFunctionComponent(request, task, key, Component, props, owner) {
1953
+ function renderFunctionComponent(request, task, key, Component, props, owner, // DEV-only
1954
+ stack) // DEV-only
1955
+ {
1726
1956
  // Reset the task's thenable state before continuing, so that if a later
1727
1957
  // component suspends we can reuse the same task object. If the same
1728
1958
  // component suspends again, the thenable state will be restored.
1729
1959
  var prevThenableState = task.thenableState;
1730
- task.thenableState = null; // The secondArg is always undefined in Server Components since refs error early.
1731
-
1732
- var secondArg = undefined;
1960
+ task.thenableState = null;
1733
1961
  var result;
1734
1962
  var componentDebugInfo;
1735
1963
 
@@ -1752,24 +1980,17 @@ function renderFunctionComponent(request, task, key, Component, props, owner) {
1752
1980
  name: componentName,
1753
1981
  env: request.environmentName,
1754
1982
  owner: owner
1755
- }; // We outline this model eagerly so that we can refer to by reference as an owner.
1983
+ };
1756
1984
  // If we had a smarter way to dedupe we might not have to do this if there ends up
1757
1985
  // being no references to this as an owner.
1758
1986
 
1987
+
1759
1988
  outlineModel(request, componentDebugInfo);
1760
1989
  emitDebugChunk(request, componentDebugID, componentDebugInfo);
1761
1990
  }
1762
1991
 
1763
1992
  prepareToUseHooksForComponent(prevThenableState, componentDebugInfo);
1764
- setCurrentOwner(componentDebugInfo);
1765
-
1766
- try {
1767
- if (supportsComponentStorage) ; else {
1768
- result = Component(props, secondArg);
1769
- }
1770
- } finally {
1771
- setCurrentOwner(null);
1772
- }
1993
+ result = callComponentInDEV(Component, props, componentDebugInfo);
1773
1994
  }
1774
1995
 
1775
1996
  if (typeof result === 'object' && result !== null) {
@@ -1821,6 +2042,33 @@ function renderFunctionComponent(request, task, key, Component, props, owner) {
1821
2042
  {
1822
2043
  result._debugInfo = iterableChild._debugInfo;
1823
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
+ }
1824
2072
  }
1825
2073
  } // Track this element's key on the Server Component on the keyPath context..
1826
2074
 
@@ -1903,7 +2151,44 @@ function renderFragment(request, task, children) {
1903
2151
  return children;
1904
2152
  }
1905
2153
 
1906
- function renderClientElement(task, type, key, props, owner) // DEV-only
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
+
2185
+
2186
+ var asyncIterator = getAsyncIterator.call(children);
2187
+ return serializeAsyncIterable(request, task, children, asyncIterator);
2188
+ }
2189
+
2190
+ function renderClientElement(task, type, key, props, owner, // DEV-only
2191
+ stack) // DEV-only
1907
2192
  {
1908
2193
  // We prepend the terminal client element that actually gets serialized with
1909
2194
  // the keys of any Server Components which are not serialized.
@@ -1953,7 +2238,8 @@ function outlineTask(request, task) {
1953
2238
  return serializeLazyID(newTask.id);
1954
2239
  }
1955
2240
 
1956
- 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
1957
2243
  {
1958
2244
  if (ref !== null && ref !== undefined) {
1959
2245
  // When the ref moves to the regular props object this will implicitly
@@ -1973,7 +2259,7 @@ function renderElement(request, task, type, key, ref, props, owner) // DEV only
1973
2259
  }
1974
2260
 
1975
2261
  if (typeof type === 'function') {
1976
- if (isClientReference(type) || isTemporaryReference(type)) {
2262
+ if (isClientReference(type) || isOpaqueTemporaryReference(type)) {
1977
2263
  // This is a reference to a Client Component.
1978
2264
  return renderClientElement(task, type, key, props, owner);
1979
2265
  } // This is a Server Component.
@@ -2010,9 +2296,12 @@ function renderElement(request, task, type, key, ref, props, owner) // DEV only
2010
2296
  switch (type.$$typeof) {
2011
2297
  case REACT_LAZY_TYPE:
2012
2298
  {
2013
- var payload = type._payload;
2014
- var init = type._init;
2015
- var wrappedType = init(payload);
2299
+ var wrappedType;
2300
+
2301
+ {
2302
+ wrappedType = callLazyInitInDEV(type);
2303
+ }
2304
+
2016
2305
  return renderElement(request, task, wrappedType, key, ref, props, owner);
2017
2306
  }
2018
2307
 
@@ -2051,7 +2340,7 @@ function createTask(request, model, keyPath, implicitSlot, abortSet) {
2051
2340
  // If we're about to write this into a new task we can assign it an ID early so that
2052
2341
  // any other references can refer to the value we're about to write.
2053
2342
  if (keyPath !== null || implicitSlot) ; else {
2054
- request.writtenObjects.set(model, id);
2343
+ request.writtenObjects.set(model, serializeByValueID(id));
2055
2344
  }
2056
2345
  }
2057
2346
 
@@ -2114,10 +2403,6 @@ function serializeServerReferenceID(id) {
2114
2403
  return '$F' + id.toString(16);
2115
2404
  }
2116
2405
 
2117
- function serializeTemporaryReferenceID(id) {
2118
- return '$T' + id;
2119
- }
2120
-
2121
2406
  function serializeSymbolReference(name) {
2122
2407
  return '$S' + name;
2123
2408
  }
@@ -2234,9 +2519,8 @@ function serializeServerReference(request, serverReference) {
2234
2519
  return serializeServerReferenceID(metadataId);
2235
2520
  }
2236
2521
 
2237
- function serializeTemporaryReference(request, temporaryReference) {
2238
- var id = resolveTemporaryReferenceID(temporaryReference);
2239
- return serializeTemporaryReferenceID(id);
2522
+ function serializeTemporaryReference(request, reference) {
2523
+ return '$T' + reference;
2240
2524
  }
2241
2525
 
2242
2526
  function serializeLargeTextString(request, text) {
@@ -2248,20 +2532,6 @@ function serializeLargeTextString(request, text) {
2248
2532
 
2249
2533
  function serializeMap(request, map) {
2250
2534
  var entries = Array.from(map);
2251
-
2252
- for (var i = 0; i < entries.length; i++) {
2253
- var key = entries[i][0];
2254
-
2255
- if (typeof key === 'object' && key !== null) {
2256
- var writtenObjects = request.writtenObjects;
2257
- var existingId = writtenObjects.get(key);
2258
-
2259
- if (existingId === undefined) {
2260
- writtenObjects.set(key, SEEN_BUT_NOT_YET_OUTLINED);
2261
- }
2262
- }
2263
- }
2264
-
2265
2535
  var id = outlineModel(request, entries);
2266
2536
  return '$Q' + id.toString(16);
2267
2537
  }
@@ -2274,20 +2544,6 @@ function serializeFormData(request, formData) {
2274
2544
 
2275
2545
  function serializeSet(request, set) {
2276
2546
  var entries = Array.from(set);
2277
-
2278
- for (var i = 0; i < entries.length; i++) {
2279
- var key = entries[i];
2280
-
2281
- if (typeof key === 'object' && key !== null) {
2282
- var writtenObjects = request.writtenObjects;
2283
- var existingId = writtenObjects.get(key);
2284
-
2285
- if (existingId === undefined) {
2286
- writtenObjects.set(key, SEEN_BUT_NOT_YET_OUTLINED);
2287
- }
2288
- }
2289
- }
2290
-
2291
2547
  var id = outlineModel(request, entries);
2292
2548
  return '$W' + id.toString(16);
2293
2549
  }
@@ -2297,6 +2553,58 @@ function serializeIterator(request, iterator) {
2297
2553
  return '$i' + id.toString(16);
2298
2554
  }
2299
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
+
2300
2608
  function escapeStringValue(value) {
2301
2609
  if (value[0] === '$') {
2302
2610
  // We need to escape $ prefixed strings since we use those to encode
@@ -2389,37 +2697,34 @@ function renderModelDestructive(request, task, parent, parentPropertyName, value
2389
2697
  {
2390
2698
  var _writtenObjects = request.writtenObjects;
2391
2699
 
2392
- var _existingId = _writtenObjects.get(value);
2393
-
2394
- if (_existingId !== undefined) {
2395
- if (task.keyPath !== null || task.implicitSlot) ; else if (modelRoot === value) {
2396
- // This is the ID we're currently emitting so we need to write it
2397
- // once but if we discover it again, we refer to it by id.
2398
- modelRoot = null;
2399
- } else if (_existingId === SEEN_BUT_NOT_YET_OUTLINED) {
2400
- // TODO: If we throw here we can treat this as suspending which causes an outline
2401
- // but that is able to reuse the same task if we're already in one but then that
2402
- // will be a lazy future value rather than guaranteed to exist but maybe that's good.
2403
- var newId = outlineModel(request, value);
2404
- return serializeByValueID(newId);
2405
- } else {
2406
- // We've already emitted this as an outlined object, so we can refer to that by its
2407
- // existing ID. TODO: We should use a lazy reference since, unlike plain objects,
2408
- // elements might suspend so it might not have emitted yet even if we have the ID for
2409
- // it. However, this creates an extra wrapper when it's not needed. We should really
2410
- // detect whether this already was emitted and synchronously available. In that
2411
- // case we can refer to it synchronously and only make it lazy otherwise.
2412
- // We currently don't have a data structure that lets us see that though.
2413
- return serializeByValueID(_existingId);
2414
- }
2415
- } else {
2416
- // This is the first time we've seen this object. We may never see it again
2417
- // so we'll inline it. Mark it as seen. If we see it again, we'll outline.
2418
- _writtenObjects.set(value, SEEN_BUT_NOT_YET_OUTLINED); // The element's props are marked as "never outlined" so that they are inlined into
2419
- // the same row as the element itself.
2420
-
2700
+ if (task.keyPath !== null || task.implicitSlot) ; else {
2701
+ var _existingReference = _writtenObjects.get(value);
2421
2702
 
2422
- _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
+ }
2423
2728
  }
2424
2729
 
2425
2730
  var element = value;
@@ -2462,9 +2767,11 @@ function renderModelDestructive(request, task, parent, parentPropertyName, value
2462
2767
  // from suspending the lazy before.
2463
2768
  task.thenableState = null;
2464
2769
  var lazy = value;
2465
- var payload = lazy._payload;
2466
- var init = lazy._init;
2467
- var resolvedModel = init(payload);
2770
+ var resolvedModel;
2771
+
2772
+ {
2773
+ resolvedModel = callLazyInitInDEV(lazy);
2774
+ }
2468
2775
 
2469
2776
  {
2470
2777
  var _debugInfo = lazy._debugInfo;
@@ -2486,17 +2793,30 @@ function renderModelDestructive(request, task, parent, parentPropertyName, value
2486
2793
 
2487
2794
  return renderModelDestructive(request, task, emptyRoot, '', resolvedModel);
2488
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
+ }
2489
2801
  }
2490
2802
 
2491
2803
  if (isClientReference(value)) {
2492
2804
  return serializeClientReference(request, parent, parentPropertyName, value);
2493
2805
  }
2494
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
+
2495
2815
  var writtenObjects = request.writtenObjects;
2496
- var existingId = writtenObjects.get(value); // $FlowFixMe[method-unbinding]
2816
+ var existingReference = writtenObjects.get(value); // $FlowFixMe[method-unbinding]
2497
2817
 
2498
2818
  if (typeof value.then === 'function') {
2499
- if (existingId !== undefined) {
2819
+ if (existingReference !== undefined) {
2500
2820
  if (task.keyPath !== null || task.implicitSlot) {
2501
2821
  // If we're in some kind of context we can't reuse the result of this render or
2502
2822
  // previous renders of this element. We only reuse Promises if they're not wrapped
@@ -2510,35 +2830,58 @@ function renderModelDestructive(request, task, parent, parentPropertyName, value
2510
2830
  modelRoot = null;
2511
2831
  } else {
2512
2832
  // We've seen this promise before, so we can just refer to the same result.
2513
- return serializePromiseID(existingId);
2833
+ return existingReference;
2514
2834
  }
2515
2835
  } // We assume that any object with a .then property is a "Thenable" type,
2516
2836
  // or a Promise type. Either of which can be represented by a Promise.
2517
2837
 
2518
2838
 
2519
2839
  var promiseId = serializeThenable(request, task, value);
2520
- writtenObjects.set(value, promiseId);
2521
- return serializePromiseID(promiseId);
2840
+ var promiseReference = serializePromiseID(promiseId);
2841
+ writtenObjects.set(value, promiseReference);
2842
+ return promiseReference;
2522
2843
  }
2523
2844
 
2524
- if (existingId !== undefined) {
2845
+ if (existingReference !== undefined) {
2525
2846
  if (modelRoot === value) {
2526
2847
  // This is the ID we're currently emitting so we need to write it
2527
2848
  // once but if we discover it again, we refer to it by id.
2528
2849
  modelRoot = null;
2529
- } else if (existingId === SEEN_BUT_NOT_YET_OUTLINED) {
2530
- var _newId = outlineModel(request, value);
2531
-
2532
- return serializeByValueID(_newId);
2533
- } else if (existingId !== NEVER_OUTLINED) {
2850
+ } else {
2534
2851
  // We've already emitted this as an outlined object, so we can
2535
2852
  // just refer to that by its existing ID.
2536
- 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);
2537
2884
  }
2538
- } else {
2539
- // This is the first time we've seen this object. We may never see it again
2540
- // so we'll inline it. Mark it as seen. If we see it again, we'll outline.
2541
- writtenObjects.set(value, SEEN_BUT_NOT_YET_OUTLINED);
2542
2885
  }
2543
2886
 
2544
2887
  if (isArray(value)) {
@@ -2558,31 +2901,116 @@ function renderModelDestructive(request, task, parent, parentPropertyName, value
2558
2901
  return serializeFormData(request, value);
2559
2902
  }
2560
2903
 
2561
- var iteratorFn = getIteratorFn(value);
2904
+ {
2905
+ if (value instanceof ArrayBuffer) {
2906
+ return serializeTypedArray(request, 'A', new Uint8Array(value));
2907
+ }
2562
2908
 
2563
- if (iteratorFn) {
2564
- // TODO: Should we serialize the return value as well like we do for AsyncIterables?
2565
- var iterator = iteratorFn.call(value);
2909
+ if (value instanceof Int8Array) {
2910
+ // char
2911
+ return serializeTypedArray(request, 'O', value);
2912
+ }
2566
2913
 
2567
- if (iterator === value) {
2568
- // Iterator, not Iterable
2569
- return serializeIterator(request, iterator);
2914
+ if (value instanceof Uint8Array) {
2915
+ // unsigned char
2916
+ return serializeTypedArray(request, 'o', value);
2570
2917
  }
2571
2918
 
2572
- return renderFragment(request, task, Array.from(iterator));
2573
- }
2919
+ if (value instanceof Uint8ClampedArray) {
2920
+ // unsigned clamped char
2921
+ return serializeTypedArray(request, 'U', value);
2922
+ }
2574
2923
 
2924
+ if (value instanceof Int16Array) {
2925
+ // sort
2926
+ return serializeTypedArray(request, 'S', value);
2927
+ }
2575
2928
 
2576
- var proto = getPrototypeOf(value);
2929
+ if (value instanceof Uint16Array) {
2930
+ // unsigned short
2931
+ return serializeTypedArray(request, 's', value);
2932
+ }
2577
2933
 
2578
- if (proto !== ObjectPrototype && (proto === null || getPrototypeOf(proto) !== null)) {
2579
- throw new Error('Only plain objects, and a few built-ins, can be passed to Client Components ' + 'from Server Components. Classes or null prototypes are not supported.');
2580
- }
2934
+ if (value instanceof Int32Array) {
2935
+ // long
2936
+ return serializeTypedArray(request, 'L', value);
2937
+ }
2581
2938
 
2582
- {
2583
- if (objectName(value) !== 'Object') {
2584
- error('Only plain objects can be passed to Client Components from Server Components. ' + '%s objects are not supported.%s', objectName(value), describeObjectForErrorMessage(parent, parentPropertyName));
2585
- } else if (!isSimpleObject(value)) {
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);
2984
+ }
2985
+
2986
+ return renderFragment(request, task, Array.from(iterator));
2987
+ }
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
+
3003
+
3004
+ var proto = getPrototypeOf(value);
3005
+
3006
+ if (proto !== ObjectPrototype && (proto === null || getPrototypeOf(proto) !== null)) {
3007
+ throw new Error('Only plain objects, and a few built-ins, can be passed to Client Components ' + 'from Server Components. Classes or null prototypes are not supported.');
3008
+ }
3009
+
3010
+ {
3011
+ if (objectName(value) !== 'Object') {
3012
+ error('Only plain objects can be passed to Client Components from Server Components. ' + '%s objects are not supported.%s', objectName(value), describeObjectForErrorMessage(parent, parentPropertyName));
3013
+ } else if (!isSimpleObject(value)) {
2586
3014
  error('Only plain objects can be passed to Client Components from Server Components. ' + 'Classes or other objects with methods are not supported.%s', describeObjectForErrorMessage(parent, parentPropertyName));
2587
3015
  } else if (Object.getOwnPropertySymbols) {
2588
3016
  var symbols = Object.getOwnPropertySymbols(value);
@@ -2641,11 +3069,17 @@ function renderModelDestructive(request, task, parent, parentPropertyName, value
2641
3069
  return serializeServerReference(request, value);
2642
3070
  }
2643
3071
 
2644
- if (isTemporaryReference(value)) {
2645
- 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
+ }
2646
3078
  }
2647
3079
 
2648
- 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)) {
2649
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.');
2650
3084
  } else if ((jsxChildrenParents.has(parent) || jsxPropsParents.has(parent) && parentPropertyName === 'children')) {
2651
3085
  var componentName = value.displayName || value.name || 'Component';
@@ -2657,11 +3091,10 @@ function renderModelDestructive(request, task, parent, parentPropertyName, value
2657
3091
 
2658
3092
  if (typeof value === 'symbol') {
2659
3093
  var writtenSymbols = request.writtenSymbols;
3094
+ var existingId = writtenSymbols.get(value);
2660
3095
 
2661
- var _existingId2 = writtenSymbols.get(value);
2662
-
2663
- if (_existingId2 !== undefined) {
2664
- return serializeByValueID(_existingId2);
3096
+ if (existingId !== undefined) {
3097
+ return serializeByValueID(existingId);
2665
3098
  } // $FlowFixMe[incompatible-type] `description` might be undefined
2666
3099
 
2667
3100
 
@@ -2843,6 +3276,18 @@ function emitDebugChunk(request, id, debugInfo) {
2843
3276
  request.completedRegularChunks.push(processedChunk);
2844
3277
  }
2845
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
+
2846
3291
  function emitTextChunk(request, id, text) {
2847
3292
  request.pendingChunks++; // Extra chunk for the header.
2848
3293
 
@@ -2878,6 +3323,14 @@ function renderConsoleValue(request, counter, parent, parentPropertyName, value)
2878
3323
  return serializeClientReference(request, parent, parentPropertyName, value);
2879
3324
  }
2880
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
+
2881
3334
  if (counter.objectCount > 20) {
2882
3335
  // We've reached our max number of objects to serialize across the wire so we serialize this
2883
3336
  // object but no properties inside of it, as a place holder.
@@ -2886,12 +3339,12 @@ function renderConsoleValue(request, counter, parent, parentPropertyName, value)
2886
3339
 
2887
3340
  counter.objectCount++;
2888
3341
  var writtenObjects = request.writtenObjects;
2889
- var existingId = writtenObjects.get(value); // $FlowFixMe[method-unbinding]
3342
+ var existingReference = writtenObjects.get(value); // $FlowFixMe[method-unbinding]
2890
3343
 
2891
3344
  if (typeof value.then === 'function') {
2892
- if (existingId !== undefined) {
3345
+ if (existingReference !== undefined) {
2893
3346
  // We've seen this promise before, so we can just refer to the same result.
2894
- return serializePromiseID(existingId);
3347
+ return existingReference;
2895
3348
  }
2896
3349
 
2897
3350
  var thenable = value;
@@ -2923,10 +3376,10 @@ function renderConsoleValue(request, counter, parent, parentPropertyName, value)
2923
3376
  return serializeInfinitePromise();
2924
3377
  }
2925
3378
 
2926
- if (existingId !== undefined && existingId >= 0) {
3379
+ if (existingReference !== undefined) {
2927
3380
  // We've already emitted this as a real object, so we can
2928
- // just refer to that by its existing ID.
2929
- return serializeByValueID(existingId);
3381
+ // just refer to that by its existing reference.
3382
+ return existingReference;
2930
3383
  }
2931
3384
 
2932
3385
  if (isArray(value)) {
@@ -2946,6 +3399,77 @@ function renderConsoleValue(request, counter, parent, parentPropertyName, value)
2946
3399
  return serializeFormData(request, value);
2947
3400
  }
2948
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
+
2949
3473
  var iteratorFn = getIteratorFn(value);
2950
3474
 
2951
3475
  if (iteratorFn) {
@@ -2991,8 +3515,12 @@ function renderConsoleValue(request, counter, parent, parentPropertyName, value)
2991
3515
  return serializeClientReference(request, parent, parentPropertyName, value);
2992
3516
  }
2993
3517
 
2994
- if (isTemporaryReference(value)) {
2995
- 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
+ }
2996
3524
  } // Serialize the body of the function as an eval so it can be printed.
2997
3525
  // $FlowFixMe[method-unbinding]
2998
3526
 
@@ -3002,11 +3530,10 @@ function renderConsoleValue(request, counter, parent, parentPropertyName, value)
3002
3530
 
3003
3531
  if (typeof value === 'symbol') {
3004
3532
  var writtenSymbols = request.writtenSymbols;
3533
+ var existingId = writtenSymbols.get(value);
3005
3534
 
3006
- var _existingId3 = writtenSymbols.get(value);
3007
-
3008
- if (_existingId3 !== undefined) {
3009
- return serializeByValueID(_existingId3);
3535
+ if (existingId !== undefined) {
3536
+ return serializeByValueID(existingId);
3010
3537
  } // $FlowFixMe[incompatible-type] `description` might be undefined
3011
3538
 
3012
3539
 
@@ -3061,6 +3588,85 @@ function emitChunk(request, task, value) {
3061
3588
  emitTextChunk(request, id, value);
3062
3589
  return;
3063
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.
3064
3670
  // $FlowFixMe[incompatible-type] stringify can return null for undefined but we never do
3065
3671
 
3066
3672
 
@@ -3106,8 +3712,11 @@ function retryTask(request, task) {
3106
3712
  task.implicitSlot = false;
3107
3713
 
3108
3714
  if (typeof resolvedModel === 'object' && resolvedModel !== null) {
3109
- // 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.
3110
3718
  // This is simulating what the JSON loop would do if this was part of it.
3719
+
3111
3720
  emitChunk(request, task, resolvedModel);
3112
3721
  } else {
3113
3722
  // If the value is a string, it means it's a terminal value and we already escaped it
@@ -3149,6 +3758,26 @@ function retryTask(request, task) {
3149
3758
  }
3150
3759
  }
3151
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
+
3152
3781
  function performWork(request) {
3153
3782
  var prevDispatcher = ReactSharedInternals.H;
3154
3783
  ReactSharedInternals.H = HooksDispatcher;
@@ -3538,8 +4167,12 @@ function loadChunk(chunkId, filename) {
3538
4167
  return __webpack_chunk_load__(chunkId);
3539
4168
  }
3540
4169
 
4170
+ // $FlowFixMe[method-unbinding]
4171
+ var hasOwnProperty = Object.prototype.hasOwnProperty;
4172
+
3541
4173
  var PENDING = 'pending';
3542
4174
  var BLOCKED = 'blocked';
4175
+ var CYCLIC = 'cyclic';
3543
4176
  var RESOLVED_MODEL = 'resolved_model';
3544
4177
  var INITIALIZED = 'fulfilled';
3545
4178
  var ERRORED = 'rejected'; // $FlowFixMe[missing-this-annot]
@@ -3572,6 +4205,7 @@ Chunk.prototype.then = function (resolve, reject) {
3572
4205
 
3573
4206
  case PENDING:
3574
4207
  case BLOCKED:
4208
+ case CYCLIC:
3575
4209
  if (resolve) {
3576
4210
  if (chunk.value === null) {
3577
4211
  chunk.value = [];
@@ -3613,8 +4247,38 @@ function wakeChunk(listeners, value) {
3613
4247
  }
3614
4248
  }
3615
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
+
3616
4272
  function triggerErrorOnChunk(chunk, error) {
3617
4273
  if (chunk.status !== PENDING && chunk.status !== BLOCKED) {
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
+ }
3618
4282
 
3619
4283
  return;
3620
4284
  }
@@ -3629,9 +4293,64 @@ function triggerErrorOnChunk(chunk, error) {
3629
4293
  }
3630
4294
  }
3631
4295
 
3632
- function createResolvedModelChunk(response, value) {
4296
+ function createResolvedModelChunk(response, value, id) {
4297
+ // $FlowFixMe[invalid-constructor] Flow doesn't support functions as constructors
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.
3633
4339
  // $FlowFixMe[invalid-constructor] Flow doesn't support functions as constructors
3634
- return new Chunk(RESOLVED_MODEL, value, null, response);
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);
3635
4354
  }
3636
4355
 
3637
4356
  function bindArgs$1(fn, args) {
@@ -3662,11 +4381,51 @@ function loadServerReference$1(response, id, bound, parentChunk, parentObject, k
3662
4381
  }
3663
4382
  }
3664
4383
 
3665
- promise.then(createModelResolver(parentChunk, parentObject, key, false, response, createModel), 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.
3666
4385
 
3667
4386
  return null;
3668
4387
  }
3669
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
+
3670
4429
  var initializingChunk = null;
3671
4430
  var initializingChunkBlockedModel = null;
3672
4431
 
@@ -3675,9 +4434,21 @@ function initializeModelChunk(chunk) {
3675
4434
  var prevBlocked = initializingChunkBlockedModel;
3676
4435
  initializingChunk = chunk;
3677
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;
3678
4446
 
3679
4447
  try {
3680
- 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);
3681
4452
 
3682
4453
  if (initializingChunkBlockedModel !== null && initializingChunkBlockedModel.deps > 0) {
3683
4454
  initializingChunkBlockedModel.value = value; // We discovered new dependencies on modules that are not yet resolved.
@@ -3688,9 +4459,14 @@ function initializeModelChunk(chunk) {
3688
4459
  blockedChunk.value = null;
3689
4460
  blockedChunk.reason = null;
3690
4461
  } else {
4462
+ var resolveListeners = cyclicChunk.value;
3691
4463
  var initializedChunk = chunk;
3692
4464
  initializedChunk.status = INITIALIZED;
3693
4465
  initializedChunk.value = value;
4466
+
4467
+ if (resolveListeners !== null) {
4468
+ wakeChunk(resolveListeners, value);
4469
+ }
3694
4470
  }
3695
4471
  } catch (error) {
3696
4472
  var erroredChunk = chunk;
@@ -3727,7 +4503,7 @@ function getChunk(response, id) {
3727
4503
 
3728
4504
  if (backingEntry != null) {
3729
4505
  // We assume that this is a string entry for now.
3730
- chunk = createResolvedModelChunk(response, backingEntry);
4506
+ chunk = createResolvedModelChunk(response, backingEntry, id);
3731
4507
  } else {
3732
4508
  // We're still waiting on this entry to stream in.
3733
4509
  chunk = createPendingChunk(response);
@@ -3739,7 +4515,7 @@ function getChunk(response, id) {
3739
4515
  return chunk;
3740
4516
  }
3741
4517
 
3742
- function createModelResolver(chunk, parentObject, key, cyclic, response, map) {
4518
+ function createModelResolver(chunk, parentObject, key, cyclic, response, map, path) {
3743
4519
  var blocked;
3744
4520
 
3745
4521
  if (initializingChunkBlockedModel) {
@@ -3756,6 +4532,10 @@ function createModelResolver(chunk, parentObject, key, cyclic, response, map) {
3756
4532
  }
3757
4533
 
3758
4534
  return function (value) {
4535
+ for (var i = 1; i < path.length; i++) {
4536
+ value = value[path[i]];
4537
+ }
4538
+
3759
4539
  parentObject[key] = map(response, value); // If this is the root object for a model reference, where `blocked.value`
3760
4540
  // is a stale `null`, the resolved value can be used directly.
3761
4541
 
@@ -3788,7 +4568,9 @@ function createModelReject(chunk) {
3788
4568
  };
3789
4569
  }
3790
4570
 
3791
- function getOutlinedModel(response, id, parentObject, key, map) {
4571
+ function getOutlinedModel(response, reference, parentObject, key, map) {
4572
+ var path = reference.split(':');
4573
+ var id = parseInt(path[0], 16);
3792
4574
  var chunk = getChunk(response, id);
3793
4575
 
3794
4576
  switch (chunk.status) {
@@ -3800,12 +4582,19 @@ function getOutlinedModel(response, id, parentObject, key, map) {
3800
4582
 
3801
4583
  switch (chunk.status) {
3802
4584
  case INITIALIZED:
3803
- return map(response, chunk.value);
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);
3804
4592
 
3805
4593
  case PENDING:
3806
4594
  case BLOCKED:
4595
+ case CYCLIC:
3807
4596
  var parentChunk = initializingChunk;
3808
- chunk.then(createModelResolver(parentChunk, parentObject, key, false, response, map), createModelReject(parentChunk));
4597
+ chunk.then(createModelResolver(parentChunk, parentObject, key, chunk.status === CYCLIC, response, map, path), createModelReject(parentChunk));
3809
4598
  return null;
3810
4599
 
3811
4600
  default:
@@ -3830,7 +4619,220 @@ function createModel(response, model) {
3830
4619
  return model;
3831
4620
  }
3832
4621
 
3833
- function parseModelString(response, obj, key, value) {
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);
4648
+
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
+ }
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;
4679
+
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;
4742
+ }
4743
+
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) {
3834
4836
  if (value[0] === '$') {
3835
4837
  switch (value[1]) {
3836
4838
  case '$':
@@ -3842,42 +4844,45 @@ function parseModelString(response, obj, key, value) {
3842
4844
  case '@':
3843
4845
  {
3844
4846
  // Promise
3845
- var _id = parseInt(value.slice(2), 16);
3846
-
3847
- var chunk = getChunk(response, _id);
4847
+ var id = parseInt(value.slice(2), 16);
4848
+ var chunk = getChunk(response, id);
3848
4849
  return chunk;
3849
4850
  }
3850
4851
 
3851
4852
  case 'F':
3852
4853
  {
3853
4854
  // Server Reference
3854
- 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.
3855
4856
 
3856
4857
 
3857
- var metaData = getOutlinedModel(response, _id2, obj, key, createModel);
4858
+ var metaData = getOutlinedModel(response, _ref2, obj, key, createModel);
3858
4859
  return loadServerReference$1(response, metaData.id, metaData.bound, initializingChunk, obj, key);
3859
4860
  }
3860
4861
 
3861
4862
  case 'T':
3862
4863
  {
3863
4864
  // Temporary Reference
3864
- 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);
3865
4870
  }
3866
4871
 
3867
4872
  case 'Q':
3868
4873
  {
3869
4874
  // Map
3870
- var _id3 = parseInt(value.slice(2), 16);
4875
+ var _ref3 = value.slice(2);
3871
4876
 
3872
- return getOutlinedModel(response, _id3, obj, key, createMap);
4877
+ return getOutlinedModel(response, _ref3, obj, key, createMap);
3873
4878
  }
3874
4879
 
3875
4880
  case 'W':
3876
4881
  {
3877
4882
  // Set
3878
- var _id4 = parseInt(value.slice(2), 16);
4883
+ var _ref4 = value.slice(2);
3879
4884
 
3880
- return getOutlinedModel(response, _id4, obj, key, createSet);
4885
+ return getOutlinedModel(response, _ref4, obj, key, createSet);
3881
4886
  }
3882
4887
 
3883
4888
  case 'K':
@@ -3902,9 +4907,9 @@ function parseModelString(response, obj, key, value) {
3902
4907
  case 'i':
3903
4908
  {
3904
4909
  // Iterator
3905
- var _id5 = parseInt(value.slice(2), 16);
4910
+ var _ref5 = value.slice(2);
3906
4911
 
3907
- return getOutlinedModel(response, _id5, obj, key, extractIterator);
4912
+ return getOutlinedModel(response, _ref5, obj, key, extractIterator);
3908
4913
  }
3909
4914
 
3910
4915
  case 'I':
@@ -3949,30 +4954,104 @@ function parseModelString(response, obj, key, value) {
3949
4954
  }
3950
4955
  }
3951
4956
 
4957
+ {
4958
+ switch (value[1]) {
4959
+ case 'A':
4960
+ return parseTypedArray(response, value, ArrayBuffer, 1, obj, key);
4961
+
4962
+ case 'O':
4963
+ return parseTypedArray(response, value, Int8Array, 1, obj, key);
4964
+
4965
+ case 'o':
4966
+ return parseTypedArray(response, value, Uint8Array, 1, obj, key);
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);
3952
4982
 
3953
- var id = parseInt(value.slice(1), 16);
3954
- return getOutlinedModel(response, id, obj, key, createModel);
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);
5002
+
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.
5006
+
5007
+ var backingEntry = response._formData.get(blobKey);
5008
+
5009
+ return backingEntry;
5010
+ }
5011
+ }
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);
3955
5041
  }
3956
5042
 
3957
5043
  return value;
3958
5044
  }
3959
5045
 
3960
- function createResponse(bundlerConfig, formFieldPrefix) {
3961
- 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();
3962
5048
  var chunks = new Map();
3963
5049
  var response = {
3964
5050
  _bundlerConfig: bundlerConfig,
3965
5051
  _prefix: formFieldPrefix,
3966
5052
  _formData: backingFormData,
3967
5053
  _chunks: chunks,
3968
- _fromJSON: function (key, value) {
3969
- if (typeof value === 'string') {
3970
- // We can't use .bind here because we need the "this" value.
3971
- return parseModelString(response, this, key, value);
3972
- }
3973
-
3974
- return value;
3975
- }
5054
+ _temporaryReferences: temporaryReferences
3976
5055
  };
3977
5056
  return response;
3978
5057
  }
@@ -4012,7 +5091,7 @@ function loadServerReference(bundlerConfig, id, bound) {
4012
5091
 
4013
5092
  function decodeBoundActionMetaData(body, serverManifest, formFieldPrefix) {
4014
5093
  // The data for this reference is encoded in multiple fields under this prefix.
4015
- var actionResponse = createResponse(serverManifest, formFieldPrefix, body);
5094
+ var actionResponse = createResponse(serverManifest, formFieldPrefix, undefined, body);
4016
5095
  close(actionResponse);
4017
5096
  var refPromise = getRoot(actionResponse); // Force it to initialize
4018
5097
  // $FlowFixMe
@@ -4107,7 +5186,7 @@ function decodeFormState(actionResult, body, serverManifest) {
4107
5186
  }
4108
5187
 
4109
5188
  function renderToReadableStream(model, webpackMap, options) {
4110
- 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);
4111
5190
 
4112
5191
  if (options && options.signal) {
4113
5192
  var signal = options.signal;
@@ -4143,20 +5222,21 @@ function renderToReadableStream(model, webpackMap, options) {
4143
5222
  return stream;
4144
5223
  }
4145
5224
 
4146
- function decodeReply(body, webpackMap) {
5225
+ function decodeReply(body, webpackMap, options) {
4147
5226
  if (typeof body === 'string') {
4148
5227
  var form = new FormData();
4149
5228
  form.append('0', body);
4150
5229
  body = form;
4151
5230
  }
4152
5231
 
4153
- var response = createResponse(webpackMap, '', body);
5232
+ var response = createResponse(webpackMap, '', options ? options.temporaryReferences : undefined, body);
4154
5233
  var root = getRoot(response);
4155
5234
  close(response);
4156
5235
  return root;
4157
5236
  }
4158
5237
 
4159
5238
  exports.createClientModuleProxy = createClientModuleProxy;
5239
+ exports.createTemporaryReferenceSet = createTemporaryReferenceSet;
4160
5240
  exports.decodeAction = decodeAction;
4161
5241
  exports.decodeFormState = decodeFormState;
4162
5242
  exports.decodeReply = decodeReply;