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.
@@ -229,9 +229,16 @@ var textEncoder = new util.TextEncoder();
229
229
  function stringToChunk(content) {
230
230
  return content;
231
231
  }
232
+ function typedArrayToBinaryChunk(content) {
233
+ // Convert any non-Uint8Array array to Uint8Array. We could avoid this for Uint8Arrays.
234
+ return new Uint8Array(content.buffer, content.byteOffset, content.byteLength);
235
+ }
232
236
  function byteLengthOfChunk(chunk) {
233
237
  return typeof chunk === 'string' ? Buffer.byteLength(chunk, 'utf8') : chunk.byteLength;
234
238
  }
239
+ function byteLengthOfBinaryChunk(chunk) {
240
+ return chunk.byteLength;
241
+ }
235
242
  function closeWithError(destination, error) {
236
243
  // $FlowFixMe[incompatible-call]: This is an Error object or the destination accepts other types.
237
244
  destination.destroy(error);
@@ -832,14 +839,19 @@ function createHints() {
832
839
 
833
840
  var supportsRequestStorage = true;
834
841
  var requestStorage = new async_hooks.AsyncLocalStorage();
842
+ var supportsComponentStorage = true;
843
+ var componentStorage = new async_hooks.AsyncLocalStorage() ;
835
844
 
836
845
  var TEMPORARY_REFERENCE_TAG = Symbol.for('react.temporary.reference'); // eslint-disable-next-line no-unused-vars
837
846
 
838
- function isTemporaryReference(reference) {
847
+ function createTemporaryReferenceSet() {
848
+ return new WeakMap();
849
+ }
850
+ function isOpaqueTemporaryReference(reference) {
839
851
  return reference.$$typeof === TEMPORARY_REFERENCE_TAG;
840
852
  }
841
- function resolveTemporaryReferenceID(temporaryReference) {
842
- return temporaryReference.$$id;
853
+ function resolveTemporaryReference(temporaryReferences, temporaryReference) {
854
+ return temporaryReferences.get(temporaryReference);
843
855
  }
844
856
  var proxyHandlers = {
845
857
  get: function (target, name, receiver) {
@@ -850,12 +862,6 @@ var proxyHandlers = {
850
862
  // have the Flight runtime extract the inner target instead.
851
863
  return target.$$typeof;
852
864
 
853
- case '$$id':
854
- return target.$$id;
855
-
856
- case '$$async':
857
- return target.$$async;
858
-
859
865
  case 'name':
860
866
  return undefined;
861
867
 
@@ -890,21 +896,28 @@ var proxyHandlers = {
890
896
  throw new Error('Cannot assign to a temporary client reference from a server module.');
891
897
  }
892
898
  };
893
- function createTemporaryReference(id) {
899
+ function createTemporaryReference(temporaryReferences, id) {
894
900
  var reference = Object.defineProperties(function () {
895
901
  throw new Error( // eslint-disable-next-line react-internal/safe-string-coercion
896
902
  "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.");
897
903
  }, {
898
904
  $$typeof: {
899
905
  value: TEMPORARY_REFERENCE_TAG
900
- },
901
- $$id: {
902
- value: id
903
906
  }
904
907
  });
905
- return new Proxy(reference, proxyHandlers);
908
+ var wrapper = new Proxy(reference, proxyHandlers);
909
+ registerTemporaryReference(temporaryReferences, wrapper, id);
910
+ return wrapper;
906
911
  }
912
+ function registerTemporaryReference(temporaryReferences, object, id) {
913
+ temporaryReferences.set(object, id);
914
+ }
915
+
916
+ // When adding new symbols to this file,
917
+ // Please consider also adding to 'react-devtools-shared/src/backend/ReactSymbols'
918
+ // The Symbol used to tag the ReactElement-like types.
907
919
 
920
+ var REACT_LEGACY_ELEMENT_TYPE = Symbol.for('react.element');
908
921
  var REACT_ELEMENT_TYPE = Symbol.for('react.transitional.element') ;
909
922
  var REACT_FRAGMENT_TYPE = Symbol.for('react.fragment');
910
923
  var REACT_CONTEXT_TYPE = Symbol.for('react.context');
@@ -930,6 +943,7 @@ function getIteratorFn(maybeIterable) {
930
943
 
931
944
  return null;
932
945
  }
946
+ var ASYNC_ITERATOR = Symbol.asyncIterator;
933
947
 
934
948
  // Corresponds to ReactFiberWakeable and ReactFizzWakeable modules. Generally,
935
949
  // changes to one module should be reflected in the others.
@@ -1178,6 +1192,21 @@ function use(usable) {
1178
1192
  }
1179
1193
  }
1180
1194
 
1195
+ var currentOwner = null;
1196
+ function setCurrentOwner(componentInfo) {
1197
+ currentOwner = componentInfo;
1198
+ }
1199
+ function resolveOwner() {
1200
+ if (currentOwner) return currentOwner;
1201
+
1202
+ {
1203
+ var owner = componentStorage.getStore();
1204
+ if (owner) return owner;
1205
+ }
1206
+
1207
+ return null;
1208
+ }
1209
+
1181
1210
  function resolveCache() {
1182
1211
  var request = resolveRequest();
1183
1212
 
@@ -1188,7 +1217,7 @@ function resolveCache() {
1188
1217
  return new Map();
1189
1218
  }
1190
1219
 
1191
- var DefaultCacheDispatcher = {
1220
+ var DefaultAsyncDispatcher = {
1192
1221
  getCacheForType: function (resourceType) {
1193
1222
  var cache = resolveCache();
1194
1223
  var entry = cache.get(resourceType);
@@ -1203,6 +1232,10 @@ var DefaultCacheDispatcher = {
1203
1232
  }
1204
1233
  };
1205
1234
 
1235
+ {
1236
+ DefaultAsyncDispatcher.getOwner = resolveOwner;
1237
+ }
1238
+
1206
1239
  var isArrayImpl = Array.isArray; // eslint-disable-next-line no-redeclare
1207
1240
 
1208
1241
  function isArray(a) {
@@ -1551,10 +1584,7 @@ var stringify = JSON.stringify; // Serializable values
1551
1584
  var PENDING$1 = 0;
1552
1585
  var COMPLETED = 1;
1553
1586
  var ABORTED = 3;
1554
- var ERRORED$1 = 4; // object reference status
1555
-
1556
- var SEEN_BUT_NOT_YET_OUTLINED = -1;
1557
- var NEVER_OUTLINED = -2;
1587
+ var ERRORED$1 = 4;
1558
1588
 
1559
1589
  function defaultErrorHandler(error) {
1560
1590
  console['error'](error); // Don't transform to our wrapper
@@ -1566,12 +1596,12 @@ function defaultPostponeHandler(reason) {// Noop
1566
1596
  var OPEN = 0;
1567
1597
  var CLOSING = 1;
1568
1598
  var CLOSED = 2;
1569
- function createRequest(model, bundlerConfig, onError, identifierPrefix, onPostpone, environmentName) {
1570
- if (ReactSharedInternals.C !== null && ReactSharedInternals.C !== DefaultCacheDispatcher) {
1599
+ function createRequest(model, bundlerConfig, onError, identifierPrefix, onPostpone, environmentName, temporaryReferences) {
1600
+ if (ReactSharedInternals.A !== null && ReactSharedInternals.A !== DefaultAsyncDispatcher) {
1571
1601
  throw new Error('Currently React only supports one RSC renderer at a time.');
1572
1602
  }
1573
1603
 
1574
- ReactSharedInternals.C = DefaultCacheDispatcher;
1604
+ ReactSharedInternals.A = DefaultAsyncDispatcher;
1575
1605
  var abortSet = new Set();
1576
1606
  var pingedTasks = [];
1577
1607
  var cleanupQueue = [];
@@ -1598,6 +1628,7 @@ function createRequest(model, bundlerConfig, onError, identifierPrefix, onPostpo
1598
1628
  writtenClientReferences: new Map(),
1599
1629
  writtenServerReferences: new Map(),
1600
1630
  writtenObjects: new WeakMap(),
1631
+ temporaryReferences: temporaryReferences,
1601
1632
  identifierPrefix: identifierPrefix || '',
1602
1633
  identifierCount: 1,
1603
1634
  taintCleanupQueue: cleanupQueue,
@@ -1705,6 +1736,192 @@ function serializeThenable(request, task, thenable) {
1705
1736
  return newTask.id;
1706
1737
  }
1707
1738
 
1739
+ function serializeReadableStream(request, task, stream) {
1740
+ // Detect if this is a BYOB stream. BYOB streams should be able to be read as bytes on the
1741
+ // receiving side. It also implies that different chunks can be split up or merged as opposed
1742
+ // to a readable stream that happens to have Uint8Array as the type which might expect it to be
1743
+ // received in the same slices.
1744
+ // $FlowFixMe: This is a Node.js extension.
1745
+ var supportsBYOB = stream.supportsBYOB;
1746
+
1747
+ if (supportsBYOB === undefined) {
1748
+ try {
1749
+ // $FlowFixMe[extra-arg]: This argument is accepted.
1750
+ stream.getReader({
1751
+ mode: 'byob'
1752
+ }).releaseLock();
1753
+ supportsBYOB = true;
1754
+ } catch (x) {
1755
+ supportsBYOB = false;
1756
+ }
1757
+ }
1758
+
1759
+ var reader = stream.getReader(); // 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) + ':' + (supportsBYOB ? 'r' : 'R') + '\n';
1766
+ request.completedRegularChunks.push(stringToChunk(startStreamRow)); // There's a race condition between when the stream is aborted and when the promise
1767
+ // resolves so we track whether we already aborted it to avoid writing twice.
1768
+
1769
+ var aborted = false;
1770
+
1771
+ function progress(entry) {
1772
+ if (aborted) {
1773
+ return;
1774
+ }
1775
+
1776
+ if (entry.done) {
1777
+ request.abortListeners.delete(error);
1778
+ var endStreamRow = streamTask.id.toString(16) + ':C\n';
1779
+ request.completedRegularChunks.push(stringToChunk(endStreamRow));
1780
+ enqueueFlush(request);
1781
+ aborted = true;
1782
+ } else {
1783
+ try {
1784
+ streamTask.model = entry.value;
1785
+ request.pendingChunks++;
1786
+ tryStreamTask(request, streamTask);
1787
+ enqueueFlush(request);
1788
+ reader.read().then(progress, error);
1789
+ } catch (x) {
1790
+ error(x);
1791
+ }
1792
+ }
1793
+ }
1794
+
1795
+ function error(reason) {
1796
+ if (aborted) {
1797
+ return;
1798
+ }
1799
+
1800
+ aborted = true;
1801
+ request.abortListeners.delete(error);
1802
+
1803
+ {
1804
+ var digest = logRecoverableError(request, reason);
1805
+ emitErrorChunk(request, streamTask.id, digest, reason);
1806
+ }
1807
+
1808
+ enqueueFlush(request); // $FlowFixMe should be able to pass mixed
1809
+
1810
+ reader.cancel(reason).then(error, error);
1811
+ }
1812
+
1813
+ request.abortListeners.add(error);
1814
+ reader.read().then(progress, error);
1815
+ return serializeByValueID(streamTask.id);
1816
+ } // This indirect exists so we can exclude its stack frame in DEV (and anything below it).
1817
+
1818
+ /** @noinline */
1819
+
1820
+
1821
+ function callIteratorInDEV(iterator, progress, error) {
1822
+ iterator.next().then(progress, error);
1823
+ }
1824
+
1825
+ function serializeAsyncIterable(request, task, iterable, iterator) {
1826
+ // Generators/Iterators are Iterables but they're also their own iterator
1827
+ // functions. If that's the case, we treat them as single-shot. Otherwise,
1828
+ // we assume that this iterable might be a multi-shot and allow it to be
1829
+ // iterated more than once on the client.
1830
+ var isIterator = iterable === iterator; // This task won't actually be retried. We just use it to attempt synchronous renders.
1831
+
1832
+ var streamTask = createTask(request, task.model, task.keyPath, task.implicitSlot, request.abortableTasks);
1833
+ request.abortableTasks.delete(streamTask);
1834
+ request.pendingChunks++; // The task represents the Start row. This adds a Stop row.
1835
+
1836
+ var startStreamRow = streamTask.id.toString(16) + ':' + (isIterator ? 'x' : 'X') + '\n';
1837
+ request.completedRegularChunks.push(stringToChunk(startStreamRow));
1838
+
1839
+ {
1840
+ var debugInfo = iterable._debugInfo;
1841
+
1842
+ if (debugInfo) {
1843
+ forwardDebugInfo(request, streamTask.id, debugInfo);
1844
+ }
1845
+ } // There's a race condition between when the stream is aborted and when the promise
1846
+ // resolves so we track whether we already aborted it to avoid writing twice.
1847
+
1848
+
1849
+ var aborted = false;
1850
+
1851
+ function progress(entry) {
1852
+ if (aborted) {
1853
+ return;
1854
+ }
1855
+
1856
+ if (entry.done) {
1857
+ request.abortListeners.delete(error);
1858
+ var endStreamRow;
1859
+
1860
+ if (entry.value === undefined) {
1861
+ endStreamRow = streamTask.id.toString(16) + ':C\n';
1862
+ } else {
1863
+ // Unlike streams, the last value may not be undefined. If it's not
1864
+ // we outline it and encode a reference to it in the closing instruction.
1865
+ try {
1866
+ var chunkId = outlineModel(request, entry.value);
1867
+ endStreamRow = streamTask.id.toString(16) + ':C' + stringify(serializeByValueID(chunkId)) + '\n';
1868
+ } catch (x) {
1869
+ error(x);
1870
+ return;
1871
+ }
1872
+ }
1873
+
1874
+ request.completedRegularChunks.push(stringToChunk(endStreamRow));
1875
+ enqueueFlush(request);
1876
+ aborted = true;
1877
+ } else {
1878
+ try {
1879
+ streamTask.model = entry.value;
1880
+ request.pendingChunks++;
1881
+ tryStreamTask(request, streamTask);
1882
+ enqueueFlush(request);
1883
+
1884
+ if (true) {
1885
+ callIteratorInDEV(iterator, progress, error);
1886
+ }
1887
+ } catch (x) {
1888
+ error(x);
1889
+ return;
1890
+ }
1891
+ }
1892
+ }
1893
+
1894
+ function error(reason) {
1895
+ if (aborted) {
1896
+ return;
1897
+ }
1898
+
1899
+ aborted = true;
1900
+ request.abortListeners.delete(error);
1901
+
1902
+ {
1903
+ var digest = logRecoverableError(request, reason);
1904
+ emitErrorChunk(request, streamTask.id, digest, reason);
1905
+ }
1906
+
1907
+ enqueueFlush(request);
1908
+
1909
+ if (typeof iterator.throw === 'function') {
1910
+ // The iterator protocol doesn't necessarily include this but a generator do.
1911
+ // $FlowFixMe should be able to pass mixed
1912
+ iterator.throw(reason).then(error, error);
1913
+ }
1914
+ }
1915
+
1916
+ request.abortListeners.add(error);
1917
+
1918
+ {
1919
+ callIteratorInDEV(iterator, progress, error);
1920
+ }
1921
+
1922
+ return serializeByValueID(streamTask.id);
1923
+ }
1924
+
1708
1925
  function emitHint(request, code, model) {
1709
1926
  emitHintChunk(request, code, model);
1710
1927
  enqueueFlush(request);
@@ -1776,15 +1993,45 @@ function createLazyWrapperAroundWakeable(wakeable) {
1776
1993
  }
1777
1994
 
1778
1995
  return lazyType;
1996
+ } // This indirect exists so we can exclude its stack frame in DEV (and anything below it).
1997
+
1998
+ /** @noinline */
1999
+
2000
+
2001
+ function callComponentInDEV(Component, props, componentDebugInfo) {
2002
+ // The secondArg is always undefined in Server Components since refs error early.
2003
+ var secondArg = undefined;
2004
+ setCurrentOwner(componentDebugInfo);
2005
+
2006
+ try {
2007
+ if (supportsComponentStorage) {
2008
+ // Run the component in an Async Context that tracks the current owner.
2009
+ return componentStorage.run(componentDebugInfo, Component, props, secondArg);
2010
+ }
2011
+ } finally {
2012
+ setCurrentOwner(null);
2013
+ }
2014
+ } // This indirect exists so we can exclude its stack frame in DEV (and anything below it).
2015
+
2016
+ /** @noinline */
2017
+
2018
+
2019
+ function callLazyInitInDEV(lazy) {
2020
+ var payload = lazy._payload;
2021
+ var init = lazy._init;
2022
+ return init(payload);
1779
2023
  }
1780
2024
 
1781
- function renderFunctionComponent(request, task, key, Component, props, owner) {
2025
+ function renderFunctionComponent(request, task, key, Component, props, owner, // DEV-only
2026
+ stack) // DEV-only
2027
+ {
1782
2028
  // Reset the task's thenable state before continuing, so that if a later
1783
2029
  // component suspends we can reuse the same task object. If the same
1784
2030
  // component suspends again, the thenable state will be restored.
1785
2031
  var prevThenableState = task.thenableState;
1786
2032
  task.thenableState = null;
1787
- var componentDebugInfo = null;
2033
+ var result;
2034
+ var componentDebugInfo;
1788
2035
 
1789
2036
  {
1790
2037
  if (debugID === null) {
@@ -1805,28 +2052,17 @@ function renderFunctionComponent(request, task, key, Component, props, owner) {
1805
2052
  name: componentName,
1806
2053
  env: request.environmentName,
1807
2054
  owner: owner
1808
- }; // We outline this model eagerly so that we can refer to by reference as an owner.
2055
+ };
1809
2056
  // If we had a smarter way to dedupe we might not have to do this if there ends up
1810
2057
  // being no references to this as an owner.
1811
2058
 
2059
+
1812
2060
  outlineModel(request, componentDebugInfo);
1813
2061
  emitDebugChunk(request, componentDebugID, componentDebugInfo);
1814
2062
  }
1815
- }
1816
-
1817
- prepareToUseHooksForComponent(prevThenableState, componentDebugInfo); // The secondArg is always undefined in Server Components since refs error early.
1818
2063
 
1819
- var secondArg = undefined;
1820
- var result;
1821
-
1822
- {
1823
- ReactSharedInternals.owner = componentDebugInfo;
1824
-
1825
- try {
1826
- result = Component(props, secondArg);
1827
- } finally {
1828
- ReactSharedInternals.owner = null;
1829
- }
2064
+ prepareToUseHooksForComponent(prevThenableState, componentDebugInfo);
2065
+ result = callComponentInDEV(Component, props, componentDebugInfo);
1830
2066
  }
1831
2067
 
1832
2068
  if (typeof result === 'object' && result !== null) {
@@ -1878,6 +2114,33 @@ function renderFunctionComponent(request, task, key, Component, props, owner) {
1878
2114
  {
1879
2115
  result._debugInfo = iterableChild._debugInfo;
1880
2116
  }
2117
+ } else if (typeof result[ASYNC_ITERATOR] === 'function' && (typeof ReadableStream !== 'function' || !(result instanceof ReadableStream))) {
2118
+ var _iterableChild = result;
2119
+ result = _defineProperty({}, ASYNC_ITERATOR, function () {
2120
+ var iterator = _iterableChild[ASYNC_ITERATOR]();
2121
+
2122
+ {
2123
+ // If this was an AsyncIterator but not an AsyncGeneratorFunction we warn because
2124
+ // it might have been a mistake. Technically you can make this mistake with
2125
+ // AsyncGeneratorFunctions and even single-shot AsyncIterables too but it's extra
2126
+ // tempting to try to return the value from a generator.
2127
+ if (iterator === _iterableChild) {
2128
+ var isGeneratorComponent = // $FlowIgnore[method-unbinding]
2129
+ Object.prototype.toString.call(Component) === '[object AsyncGeneratorFunction]' && // $FlowIgnore[method-unbinding]
2130
+ Object.prototype.toString.call(_iterableChild) === '[object AsyncGenerator]';
2131
+
2132
+ if (!isGeneratorComponent) {
2133
+ error('Returning an AsyncIterator from a Server Component is not supported ' + 'since it cannot be looped over more than once. ');
2134
+ }
2135
+ }
2136
+ }
2137
+
2138
+ return iterator;
2139
+ });
2140
+
2141
+ {
2142
+ result._debugInfo = _iterableChild._debugInfo;
2143
+ }
1881
2144
  }
1882
2145
  } // Track this element's key on the Server Component on the keyPath context..
1883
2146
 
@@ -1960,11 +2223,47 @@ function renderFragment(request, task, children) {
1960
2223
  return children;
1961
2224
  }
1962
2225
 
1963
- function renderClientElement(task, type, key, props, owner) // DEV-only
1964
- {
1965
- // the keys of any Server Components which are not serialized.
2226
+ function renderAsyncFragment(request, task, children, getAsyncIterator) {
2227
+ if (task.keyPath !== null) {
2228
+ // We have a Server Component that specifies a key but we're now splitting
2229
+ // the tree using a fragment.
2230
+ var fragment = [REACT_ELEMENT_TYPE, REACT_FRAGMENT_TYPE, task.keyPath, {
2231
+ children: children
2232
+ }];
2233
+
2234
+ if (!task.implicitSlot) {
2235
+ // If this was keyed inside a set. I.e. the outer Server Component was keyed
2236
+ // then we need to handle reorders of the whole set. To do this we need to wrap
2237
+ // this array in a keyed Fragment.
2238
+ return fragment;
2239
+ } // If the outer Server Component was implicit but then an inner one had a key
2240
+ // we don't actually need to be able to move the whole set around. It'll always be
2241
+ // in an implicit slot. The key only exists to be able to reset the state of the
2242
+ // children. We could achieve the same effect by passing on the keyPath to the next
2243
+ // set of components inside the fragment. This would also allow a keyless fragment
2244
+ // reconcile against a single child.
2245
+ // Unfortunately because of JSON.stringify, we can't call the recursive loop for
2246
+ // each child within this context because we can't return a set with already resolved
2247
+ // values. E.g. a string would get double encoded. Returning would pop the context.
2248
+ // So instead, we wrap it with an unkeyed fragment and inner keyed fragment.
2249
+
1966
2250
 
2251
+ return [fragment];
2252
+ } // Since we're yielding here, that implicitly resets the keyPath context on the
2253
+ // way up. Which is what we want since we've consumed it. If this changes to
2254
+ // be recursive serialization, we need to reset the keyPath and implicitSlot,
2255
+ // before recursing here.
2256
+
2257
+
2258
+ var asyncIterator = getAsyncIterator.call(children);
2259
+ return serializeAsyncIterable(request, task, children, asyncIterator);
2260
+ }
1967
2261
 
2262
+ function renderClientElement(task, type, key, props, owner, // DEV-only
2263
+ stack) // DEV-only
2264
+ {
2265
+ // We prepend the terminal client element that actually gets serialized with
2266
+ // the keys of any Server Components which are not serialized.
1968
2267
  var keyPath = task.keyPath;
1969
2268
 
1970
2269
  if (key === null) {
@@ -2011,7 +2310,8 @@ function outlineTask(request, task) {
2011
2310
  return serializeLazyID(newTask.id);
2012
2311
  }
2013
2312
 
2014
- function renderElement(request, task, type, key, ref, props, owner) // DEV only
2313
+ function renderElement(request, task, type, key, ref, props, owner, // DEV only
2314
+ stack) // DEV only
2015
2315
  {
2016
2316
  if (ref !== null && ref !== undefined) {
2017
2317
  // When the ref moves to the regular props object this will implicitly
@@ -2031,7 +2331,7 @@ function renderElement(request, task, type, key, ref, props, owner) // DEV only
2031
2331
  }
2032
2332
 
2033
2333
  if (typeof type === 'function') {
2034
- if (isClientReference(type) || isTemporaryReference(type)) {
2334
+ if (isClientReference(type) || isOpaqueTemporaryReference(type)) {
2035
2335
  // This is a reference to a Client Component.
2036
2336
  return renderClientElement(task, type, key, props, owner);
2037
2337
  } // This is a Server Component.
@@ -2068,9 +2368,12 @@ function renderElement(request, task, type, key, ref, props, owner) // DEV only
2068
2368
  switch (type.$$typeof) {
2069
2369
  case REACT_LAZY_TYPE:
2070
2370
  {
2071
- var payload = type._payload;
2072
- var init = type._init;
2073
- var wrappedType = init(payload);
2371
+ var wrappedType;
2372
+
2373
+ {
2374
+ wrappedType = callLazyInitInDEV(type);
2375
+ }
2376
+
2074
2377
  return renderElement(request, task, wrappedType, key, ref, props, owner);
2075
2378
  }
2076
2379
 
@@ -2108,8 +2411,8 @@ function createTask(request, model, keyPath, implicitSlot, abortSet) {
2108
2411
  if (typeof model === 'object' && model !== null) {
2109
2412
  // If we're about to write this into a new task we can assign it an ID early so that
2110
2413
  // any other references can refer to the value we're about to write.
2111
- if ((keyPath !== null || implicitSlot)) ; else {
2112
- request.writtenObjects.set(model, id);
2414
+ if (keyPath !== null || implicitSlot) ; else {
2415
+ request.writtenObjects.set(model, serializeByValueID(id));
2113
2416
  }
2114
2417
  }
2115
2418
 
@@ -2172,10 +2475,6 @@ function serializeServerReferenceID(id) {
2172
2475
  return '$F' + id.toString(16);
2173
2476
  }
2174
2477
 
2175
- function serializeTemporaryReferenceID(id) {
2176
- return '$T' + id;
2177
- }
2178
-
2179
2478
  function serializeSymbolReference(name) {
2180
2479
  return '$S' + name;
2181
2480
  }
@@ -2292,9 +2591,8 @@ function serializeServerReference(request, serverReference) {
2292
2591
  return serializeServerReferenceID(metadataId);
2293
2592
  }
2294
2593
 
2295
- function serializeTemporaryReference(request, temporaryReference) {
2296
- var id = resolveTemporaryReferenceID(temporaryReference);
2297
- return serializeTemporaryReferenceID(id);
2594
+ function serializeTemporaryReference(request, reference) {
2595
+ return '$T' + reference;
2298
2596
  }
2299
2597
 
2300
2598
  function serializeLargeTextString(request, text) {
@@ -2306,20 +2604,6 @@ function serializeLargeTextString(request, text) {
2306
2604
 
2307
2605
  function serializeMap(request, map) {
2308
2606
  var entries = Array.from(map);
2309
-
2310
- for (var i = 0; i < entries.length; i++) {
2311
- var key = entries[i][0];
2312
-
2313
- if (typeof key === 'object' && key !== null) {
2314
- var writtenObjects = request.writtenObjects;
2315
- var existingId = writtenObjects.get(key);
2316
-
2317
- if (existingId === undefined) {
2318
- writtenObjects.set(key, SEEN_BUT_NOT_YET_OUTLINED);
2319
- }
2320
- }
2321
- }
2322
-
2323
2607
  var id = outlineModel(request, entries);
2324
2608
  return '$Q' + id.toString(16);
2325
2609
  }
@@ -2332,20 +2616,6 @@ function serializeFormData(request, formData) {
2332
2616
 
2333
2617
  function serializeSet(request, set) {
2334
2618
  var entries = Array.from(set);
2335
-
2336
- for (var i = 0; i < entries.length; i++) {
2337
- var key = entries[i];
2338
-
2339
- if (typeof key === 'object' && key !== null) {
2340
- var writtenObjects = request.writtenObjects;
2341
- var existingId = writtenObjects.get(key);
2342
-
2343
- if (existingId === undefined) {
2344
- writtenObjects.set(key, SEEN_BUT_NOT_YET_OUTLINED);
2345
- }
2346
- }
2347
- }
2348
-
2349
2619
  var id = outlineModel(request, entries);
2350
2620
  return '$W' + id.toString(16);
2351
2621
  }
@@ -2355,6 +2625,58 @@ function serializeIterator(request, iterator) {
2355
2625
  return '$i' + id.toString(16);
2356
2626
  }
2357
2627
 
2628
+ function serializeTypedArray(request, tag, typedArray) {
2629
+ request.pendingChunks++;
2630
+ var bufferId = request.nextChunkId++;
2631
+ emitTypedArrayChunk(request, bufferId, tag, typedArray);
2632
+ return serializeByValueID(bufferId);
2633
+ }
2634
+
2635
+ function serializeBlob(request, blob) {
2636
+ var model = [blob.type];
2637
+ var newTask = createTask(request, model, null, false, request.abortableTasks);
2638
+ var reader = blob.stream().getReader();
2639
+ var aborted = false;
2640
+
2641
+ function progress(entry) {
2642
+ if (aborted) {
2643
+ return;
2644
+ }
2645
+
2646
+ if (entry.done) {
2647
+ request.abortListeners.delete(error);
2648
+ aborted = true;
2649
+ pingTask(request, newTask);
2650
+ return;
2651
+ } // TODO: Emit the chunk early and refer to it later by dedupe.
2652
+
2653
+
2654
+ model.push(entry.value); // $FlowFixMe[incompatible-call]
2655
+
2656
+ return reader.read().then(progress).catch(error);
2657
+ }
2658
+
2659
+ function error(reason) {
2660
+ if (aborted) {
2661
+ return;
2662
+ }
2663
+
2664
+ aborted = true;
2665
+ request.abortListeners.delete(error);
2666
+ var digest = logRecoverableError(request, reason);
2667
+ emitErrorChunk(request, newTask.id, digest, reason);
2668
+ request.abortableTasks.delete(newTask);
2669
+ enqueueFlush(request); // $FlowFixMe should be able to pass mixed
2670
+
2671
+ reader.cancel(reason).then(error, error);
2672
+ }
2673
+
2674
+ request.abortListeners.add(error); // $FlowFixMe[incompatible-call]
2675
+
2676
+ reader.read().then(progress).catch(error);
2677
+ return '$B' + newTask.id.toString(16);
2678
+ }
2679
+
2358
2680
  function escapeStringValue(value) {
2359
2681
  if (value[0] === '$') {
2360
2682
  // We need to escape $ prefixed strings since we use those to encode
@@ -2447,37 +2769,34 @@ function renderModelDestructive(request, task, parent, parentPropertyName, value
2447
2769
  {
2448
2770
  var _writtenObjects = request.writtenObjects;
2449
2771
 
2450
- var _existingId = _writtenObjects.get(value);
2451
-
2452
- if (_existingId !== undefined) {
2453
- if ((task.keyPath !== null || task.implicitSlot)) ; else if (modelRoot === value) {
2454
- // This is the ID we're currently emitting so we need to write it
2455
- // once but if we discover it again, we refer to it by id.
2456
- modelRoot = null;
2457
- } else if (_existingId === SEEN_BUT_NOT_YET_OUTLINED) {
2458
- // TODO: If we throw here we can treat this as suspending which causes an outline
2459
- // but that is able to reuse the same task if we're already in one but then that
2460
- // will be a lazy future value rather than guaranteed to exist but maybe that's good.
2461
- var newId = outlineModel(request, value);
2462
- return serializeByValueID(newId);
2463
- } else {
2464
- // We've already emitted this as an outlined object, so we can refer to that by its
2465
- // existing ID. TODO: We should use a lazy reference since, unlike plain objects,
2466
- // elements might suspend so it might not have emitted yet even if we have the ID for
2467
- // it. However, this creates an extra wrapper when it's not needed. We should really
2468
- // detect whether this already was emitted and synchronously available. In that
2469
- // case we can refer to it synchronously and only make it lazy otherwise.
2470
- // We currently don't have a data structure that lets us see that though.
2471
- return serializeByValueID(_existingId);
2472
- }
2473
- } else {
2474
- // This is the first time we've seen this object. We may never see it again
2475
- // so we'll inline it. Mark it as seen. If we see it again, we'll outline.
2476
- _writtenObjects.set(value, SEEN_BUT_NOT_YET_OUTLINED); // The element's props are marked as "never outlined" so that they are inlined into
2477
- // the same row as the element itself.
2478
-
2772
+ if (task.keyPath !== null || task.implicitSlot) ; else {
2773
+ var _existingReference = _writtenObjects.get(value);
2479
2774
 
2480
- _writtenObjects.set(value.props, NEVER_OUTLINED);
2775
+ if (_existingReference !== undefined) {
2776
+ if (modelRoot === value) {
2777
+ // This is the ID we're currently emitting so we need to write it
2778
+ // once but if we discover it again, we refer to it by id.
2779
+ modelRoot = null;
2780
+ } else {
2781
+ // We've already emitted this as an outlined object, so we can refer to that by its
2782
+ // existing ID. TODO: We should use a lazy reference since, unlike plain objects,
2783
+ // elements might suspend so it might not have emitted yet even if we have the ID for
2784
+ // it. However, this creates an extra wrapper when it's not needed. We should really
2785
+ // detect whether this already was emitted and synchronously available. In that
2786
+ // case we can refer to it synchronously and only make it lazy otherwise.
2787
+ // We currently don't have a data structure that lets us see that though.
2788
+ return _existingReference;
2789
+ }
2790
+ } else if (parentPropertyName.indexOf(':') === -1) {
2791
+ // TODO: If the property name contains a colon, we don't dedupe. Escape instead.
2792
+ var parentReference = _writtenObjects.get(parent);
2793
+
2794
+ if (parentReference !== undefined) {
2795
+ // If the parent has a reference, we can refer to this object indirectly
2796
+ // through the property name inside that parent.
2797
+ _writtenObjects.set(value, parentReference + ':' + parentPropertyName);
2798
+ }
2799
+ }
2481
2800
  }
2482
2801
 
2483
2802
  var element = value;
@@ -2520,9 +2839,11 @@ function renderModelDestructive(request, task, parent, parentPropertyName, value
2520
2839
  // from suspending the lazy before.
2521
2840
  task.thenableState = null;
2522
2841
  var lazy = value;
2523
- var payload = lazy._payload;
2524
- var init = lazy._init;
2525
- var resolvedModel = init(payload);
2842
+ var resolvedModel;
2843
+
2844
+ {
2845
+ resolvedModel = callLazyInitInDEV(lazy);
2846
+ }
2526
2847
 
2527
2848
  {
2528
2849
  var _debugInfo = lazy._debugInfo;
@@ -2544,18 +2865,31 @@ function renderModelDestructive(request, task, parent, parentPropertyName, value
2544
2865
 
2545
2866
  return renderModelDestructive(request, task, emptyRoot, '', resolvedModel);
2546
2867
  }
2868
+
2869
+ case REACT_LEGACY_ELEMENT_TYPE:
2870
+ {
2871
+ 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.');
2872
+ }
2547
2873
  }
2548
2874
 
2549
2875
  if (isClientReference(value)) {
2550
2876
  return serializeClientReference(request, parent, parentPropertyName, value);
2551
2877
  }
2552
2878
 
2879
+ if (request.temporaryReferences !== undefined) {
2880
+ var tempRef = resolveTemporaryReference(request.temporaryReferences, value);
2881
+
2882
+ if (tempRef !== undefined) {
2883
+ return serializeTemporaryReference(request, tempRef);
2884
+ }
2885
+ }
2886
+
2553
2887
  var writtenObjects = request.writtenObjects;
2554
- var existingId = writtenObjects.get(value); // $FlowFixMe[method-unbinding]
2888
+ var existingReference = writtenObjects.get(value); // $FlowFixMe[method-unbinding]
2555
2889
 
2556
2890
  if (typeof value.then === 'function') {
2557
- if (existingId !== undefined) {
2558
- if ((task.keyPath !== null || task.implicitSlot)) {
2891
+ if (existingReference !== undefined) {
2892
+ if (task.keyPath !== null || task.implicitSlot) {
2559
2893
  // If we're in some kind of context we can't reuse the result of this render or
2560
2894
  // previous renders of this element. We only reuse Promises if they're not wrapped
2561
2895
  // by another Server Component.
@@ -2568,35 +2902,58 @@ function renderModelDestructive(request, task, parent, parentPropertyName, value
2568
2902
  modelRoot = null;
2569
2903
  } else {
2570
2904
  // We've seen this promise before, so we can just refer to the same result.
2571
- return serializePromiseID(existingId);
2905
+ return existingReference;
2572
2906
  }
2573
2907
  } // We assume that any object with a .then property is a "Thenable" type,
2574
2908
  // or a Promise type. Either of which can be represented by a Promise.
2575
2909
 
2576
2910
 
2577
2911
  var promiseId = serializeThenable(request, task, value);
2578
- writtenObjects.set(value, promiseId);
2579
- return serializePromiseID(promiseId);
2912
+ var promiseReference = serializePromiseID(promiseId);
2913
+ writtenObjects.set(value, promiseReference);
2914
+ return promiseReference;
2580
2915
  }
2581
2916
 
2582
- if (existingId !== undefined) {
2917
+ if (existingReference !== undefined) {
2583
2918
  if (modelRoot === value) {
2584
2919
  // This is the ID we're currently emitting so we need to write it
2585
2920
  // once but if we discover it again, we refer to it by id.
2586
2921
  modelRoot = null;
2587
- } else if (existingId === SEEN_BUT_NOT_YET_OUTLINED) {
2588
- var _newId = outlineModel(request, value);
2589
-
2590
- return serializeByValueID(_newId);
2591
- } else if (existingId !== NEVER_OUTLINED) {
2922
+ } else {
2592
2923
  // We've already emitted this as an outlined object, so we can
2593
2924
  // just refer to that by its existing ID.
2594
- return serializeByValueID(existingId);
2925
+ return existingReference;
2926
+ }
2927
+ } else if (parentPropertyName.indexOf(':') === -1) {
2928
+ // TODO: If the property name contains a colon, we don't dedupe. Escape instead.
2929
+ var _parentReference = writtenObjects.get(parent);
2930
+
2931
+ if (_parentReference !== undefined) {
2932
+ // If the parent has a reference, we can refer to this object indirectly
2933
+ // through the property name inside that parent.
2934
+ var propertyName = parentPropertyName;
2935
+
2936
+ if (isArray(parent) && parent[0] === REACT_ELEMENT_TYPE) {
2937
+ // For elements, we've converted it to an array but we'll have converted
2938
+ // it back to an element before we read the references so the property
2939
+ // needs to be aliased.
2940
+ switch (parentPropertyName) {
2941
+ case '1':
2942
+ propertyName = 'type';
2943
+ break;
2944
+
2945
+ case '2':
2946
+ propertyName = 'key';
2947
+ break;
2948
+
2949
+ case '3':
2950
+ propertyName = 'props';
2951
+ break;
2952
+ }
2953
+ }
2954
+
2955
+ writtenObjects.set(value, _parentReference + ':' + propertyName);
2595
2956
  }
2596
- } else {
2597
- // This is the first time we've seen this object. We may never see it again
2598
- // so we'll inline it. Mark it as seen. If we see it again, we'll outline.
2599
- writtenObjects.set(value, SEEN_BUT_NOT_YET_OUTLINED);
2600
2957
  }
2601
2958
 
2602
2959
  if (isArray(value)) {
@@ -2616,20 +2973,105 @@ function renderModelDestructive(request, task, parent, parentPropertyName, value
2616
2973
  return serializeFormData(request, value);
2617
2974
  }
2618
2975
 
2619
- var iteratorFn = getIteratorFn(value);
2976
+ {
2977
+ if (value instanceof ArrayBuffer) {
2978
+ return serializeTypedArray(request, 'A', new Uint8Array(value));
2979
+ }
2620
2980
 
2621
- if (iteratorFn) {
2622
- // TODO: Should we serialize the return value as well like we do for AsyncIterables?
2623
- var iterator = iteratorFn.call(value);
2981
+ if (value instanceof Int8Array) {
2982
+ // char
2983
+ return serializeTypedArray(request, 'O', value);
2984
+ }
2624
2985
 
2625
- if (iterator === value) {
2626
- // Iterator, not Iterable
2986
+ if (value instanceof Uint8Array) {
2987
+ // unsigned char
2988
+ return serializeTypedArray(request, 'o', value);
2989
+ }
2990
+
2991
+ if (value instanceof Uint8ClampedArray) {
2992
+ // unsigned clamped char
2993
+ return serializeTypedArray(request, 'U', value);
2994
+ }
2995
+
2996
+ if (value instanceof Int16Array) {
2997
+ // sort
2998
+ return serializeTypedArray(request, 'S', value);
2999
+ }
3000
+
3001
+ if (value instanceof Uint16Array) {
3002
+ // unsigned short
3003
+ return serializeTypedArray(request, 's', value);
3004
+ }
3005
+
3006
+ if (value instanceof Int32Array) {
3007
+ // long
3008
+ return serializeTypedArray(request, 'L', value);
3009
+ }
3010
+
3011
+ if (value instanceof Uint32Array) {
3012
+ // unsigned long
3013
+ return serializeTypedArray(request, 'l', value);
3014
+ }
3015
+
3016
+ if (value instanceof Float32Array) {
3017
+ // float
3018
+ return serializeTypedArray(request, 'G', value);
3019
+ }
3020
+
3021
+ if (value instanceof Float64Array) {
3022
+ // double
3023
+ return serializeTypedArray(request, 'g', value);
3024
+ }
3025
+
3026
+ if (value instanceof BigInt64Array) {
3027
+ // number
3028
+ return serializeTypedArray(request, 'M', value);
3029
+ }
3030
+
3031
+ if (value instanceof BigUint64Array) {
3032
+ // unsigned number
3033
+ // We use "m" instead of "n" since JSON can start with "null"
3034
+ return serializeTypedArray(request, 'm', value);
3035
+ }
3036
+
3037
+ if (value instanceof DataView) {
3038
+ return serializeTypedArray(request, 'V', value);
3039
+ } // TODO: Blob is not available in old Node. Remove the typeof check later.
3040
+
3041
+
3042
+ if (typeof Blob === 'function' && value instanceof Blob) {
3043
+ return serializeBlob(request, value);
3044
+ }
3045
+ }
3046
+
3047
+ var iteratorFn = getIteratorFn(value);
3048
+
3049
+ if (iteratorFn) {
3050
+ // TODO: Should we serialize the return value as well like we do for AsyncIterables?
3051
+ var iterator = iteratorFn.call(value);
3052
+
3053
+ if (iterator === value) {
3054
+ // Iterator, not Iterable
2627
3055
  return serializeIterator(request, iterator);
2628
3056
  }
2629
3057
 
2630
3058
  return renderFragment(request, task, Array.from(iterator));
2631
3059
  }
2632
3060
 
3061
+ {
3062
+ // TODO: Blob is not available in old Node. Remove the typeof check later.
3063
+ if (typeof ReadableStream === 'function' && value instanceof ReadableStream) {
3064
+ return serializeReadableStream(request, task, value);
3065
+ }
3066
+
3067
+ var getAsyncIterator = value[ASYNC_ITERATOR];
3068
+
3069
+ if (typeof getAsyncIterator === 'function') {
3070
+ // We treat AsyncIterables as a Fragment and as such we might need to key them.
3071
+ return renderAsyncFragment(request, task, value, getAsyncIterator);
3072
+ }
3073
+ } // Verify that this is a simple plain object.
3074
+
2633
3075
 
2634
3076
  var proto = getPrototypeOf(value);
2635
3077
 
@@ -2699,11 +3141,17 @@ function renderModelDestructive(request, task, parent, parentPropertyName, value
2699
3141
  return serializeServerReference(request, value);
2700
3142
  }
2701
3143
 
2702
- if (isTemporaryReference(value)) {
2703
- return serializeTemporaryReference(request, value);
3144
+ if (request.temporaryReferences !== undefined) {
3145
+ var _tempRef = resolveTemporaryReference(request.temporaryReferences, value);
3146
+
3147
+ if (_tempRef !== undefined) {
3148
+ return serializeTemporaryReference(request, _tempRef);
3149
+ }
2704
3150
  }
2705
3151
 
2706
- if (/^on[A-Z]/.test(parentPropertyName)) {
3152
+ if (isOpaqueTemporaryReference(value)) {
3153
+ throw new Error('Could not reference an opaque temporary reference. ' + 'This is likely due to misconfiguring the temporaryReferences options ' + 'on the server.');
3154
+ } else if (/^on[A-Z]/.test(parentPropertyName)) {
2707
3155
  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.');
2708
3156
  } else if ((jsxChildrenParents.has(parent) || jsxPropsParents.has(parent) && parentPropertyName === 'children')) {
2709
3157
  var componentName = value.displayName || value.name || 'Component';
@@ -2715,11 +3163,10 @@ function renderModelDestructive(request, task, parent, parentPropertyName, value
2715
3163
 
2716
3164
  if (typeof value === 'symbol') {
2717
3165
  var writtenSymbols = request.writtenSymbols;
3166
+ var existingId = writtenSymbols.get(value);
2718
3167
 
2719
- var _existingId2 = writtenSymbols.get(value);
2720
-
2721
- if (_existingId2 !== undefined) {
2722
- return serializeByValueID(_existingId2);
3168
+ if (existingId !== undefined) {
3169
+ return serializeByValueID(existingId);
2723
3170
  } // $FlowFixMe[incompatible-type] `description` might be undefined
2724
3171
 
2725
3172
 
@@ -2903,6 +3350,18 @@ function emitDebugChunk(request, id, debugInfo) {
2903
3350
  request.completedRegularChunks.push(processedChunk);
2904
3351
  }
2905
3352
 
3353
+ function emitTypedArrayChunk(request, id, tag, typedArray) {
3354
+
3355
+ request.pendingChunks++; // Extra chunk for the header.
3356
+ // TODO: Convert to little endian if that's not the server default.
3357
+
3358
+ var binaryChunk = typedArrayToBinaryChunk(typedArray);
3359
+ var binaryLength = byteLengthOfBinaryChunk(binaryChunk);
3360
+ var row = id.toString(16) + ':' + tag + binaryLength.toString(16) + ',';
3361
+ var headerChunk = stringToChunk(row);
3362
+ request.completedRegularChunks.push(headerChunk, binaryChunk);
3363
+ }
3364
+
2906
3365
  function emitTextChunk(request, id, text) {
2907
3366
  request.pendingChunks++; // Extra chunk for the header.
2908
3367
 
@@ -2938,6 +3397,14 @@ function renderConsoleValue(request, counter, parent, parentPropertyName, value)
2938
3397
  return serializeClientReference(request, parent, parentPropertyName, value);
2939
3398
  }
2940
3399
 
3400
+ if (request.temporaryReferences !== undefined) {
3401
+ var tempRef = resolveTemporaryReference(request.temporaryReferences, value);
3402
+
3403
+ if (tempRef !== undefined) {
3404
+ return serializeTemporaryReference(request, tempRef);
3405
+ }
3406
+ }
3407
+
2941
3408
  if (counter.objectCount > 20) {
2942
3409
  // We've reached our max number of objects to serialize across the wire so we serialize this
2943
3410
  // object but no properties inside of it, as a place holder.
@@ -2946,12 +3413,12 @@ function renderConsoleValue(request, counter, parent, parentPropertyName, value)
2946
3413
 
2947
3414
  counter.objectCount++;
2948
3415
  var writtenObjects = request.writtenObjects;
2949
- var existingId = writtenObjects.get(value); // $FlowFixMe[method-unbinding]
3416
+ var existingReference = writtenObjects.get(value); // $FlowFixMe[method-unbinding]
2950
3417
 
2951
3418
  if (typeof value.then === 'function') {
2952
- if (existingId !== undefined) {
3419
+ if (existingReference !== undefined) {
2953
3420
  // We've seen this promise before, so we can just refer to the same result.
2954
- return serializePromiseID(existingId);
3421
+ return existingReference;
2955
3422
  }
2956
3423
 
2957
3424
  var thenable = value;
@@ -2983,10 +3450,10 @@ function renderConsoleValue(request, counter, parent, parentPropertyName, value)
2983
3450
  return serializeInfinitePromise();
2984
3451
  }
2985
3452
 
2986
- if (existingId !== undefined && existingId >= 0) {
3453
+ if (existingReference !== undefined) {
2987
3454
  // We've already emitted this as a real object, so we can
2988
- // just refer to that by its existing ID.
2989
- return serializeByValueID(existingId);
3455
+ // just refer to that by its existing reference.
3456
+ return existingReference;
2990
3457
  }
2991
3458
 
2992
3459
  if (isArray(value)) {
@@ -3006,6 +3473,77 @@ function renderConsoleValue(request, counter, parent, parentPropertyName, value)
3006
3473
  return serializeFormData(request, value);
3007
3474
  }
3008
3475
 
3476
+ {
3477
+ if (value instanceof ArrayBuffer) {
3478
+ return serializeTypedArray(request, 'A', new Uint8Array(value));
3479
+ }
3480
+
3481
+ if (value instanceof Int8Array) {
3482
+ // char
3483
+ return serializeTypedArray(request, 'O', value);
3484
+ }
3485
+
3486
+ if (value instanceof Uint8Array) {
3487
+ // unsigned char
3488
+ return serializeTypedArray(request, 'o', value);
3489
+ }
3490
+
3491
+ if (value instanceof Uint8ClampedArray) {
3492
+ // unsigned clamped char
3493
+ return serializeTypedArray(request, 'U', value);
3494
+ }
3495
+
3496
+ if (value instanceof Int16Array) {
3497
+ // sort
3498
+ return serializeTypedArray(request, 'S', value);
3499
+ }
3500
+
3501
+ if (value instanceof Uint16Array) {
3502
+ // unsigned short
3503
+ return serializeTypedArray(request, 's', value);
3504
+ }
3505
+
3506
+ if (value instanceof Int32Array) {
3507
+ // long
3508
+ return serializeTypedArray(request, 'L', value);
3509
+ }
3510
+
3511
+ if (value instanceof Uint32Array) {
3512
+ // unsigned long
3513
+ return serializeTypedArray(request, 'l', value);
3514
+ }
3515
+
3516
+ if (value instanceof Float32Array) {
3517
+ // float
3518
+ return serializeTypedArray(request, 'G', value);
3519
+ }
3520
+
3521
+ if (value instanceof Float64Array) {
3522
+ // double
3523
+ return serializeTypedArray(request, 'g', value);
3524
+ }
3525
+
3526
+ if (value instanceof BigInt64Array) {
3527
+ // number
3528
+ return serializeTypedArray(request, 'M', value);
3529
+ }
3530
+
3531
+ if (value instanceof BigUint64Array) {
3532
+ // unsigned number
3533
+ // We use "m" instead of "n" since JSON can start with "null"
3534
+ return serializeTypedArray(request, 'm', value);
3535
+ }
3536
+
3537
+ if (value instanceof DataView) {
3538
+ return serializeTypedArray(request, 'V', value);
3539
+ } // TODO: Blob is not available in old Node. Remove the typeof check later.
3540
+
3541
+
3542
+ if (typeof Blob === 'function' && value instanceof Blob) {
3543
+ return serializeBlob(request, value);
3544
+ }
3545
+ }
3546
+
3009
3547
  var iteratorFn = getIteratorFn(value);
3010
3548
 
3011
3549
  if (iteratorFn) {
@@ -3051,8 +3589,12 @@ function renderConsoleValue(request, counter, parent, parentPropertyName, value)
3051
3589
  return serializeClientReference(request, parent, parentPropertyName, value);
3052
3590
  }
3053
3591
 
3054
- if (isTemporaryReference(value)) {
3055
- return serializeTemporaryReference(request, value);
3592
+ if (request.temporaryReferences !== undefined) {
3593
+ var _tempRef2 = resolveTemporaryReference(request.temporaryReferences, value);
3594
+
3595
+ if (_tempRef2 !== undefined) {
3596
+ return serializeTemporaryReference(request, _tempRef2);
3597
+ }
3056
3598
  } // Serialize the body of the function as an eval so it can be printed.
3057
3599
  // $FlowFixMe[method-unbinding]
3058
3600
 
@@ -3062,11 +3604,10 @@ function renderConsoleValue(request, counter, parent, parentPropertyName, value)
3062
3604
 
3063
3605
  if (typeof value === 'symbol') {
3064
3606
  var writtenSymbols = request.writtenSymbols;
3607
+ var existingId = writtenSymbols.get(value);
3065
3608
 
3066
- var _existingId3 = writtenSymbols.get(value);
3067
-
3068
- if (_existingId3 !== undefined) {
3069
- return serializeByValueID(_existingId3);
3609
+ if (existingId !== undefined) {
3610
+ return serializeByValueID(existingId);
3070
3611
  } // $FlowFixMe[incompatible-type] `description` might be undefined
3071
3612
 
3072
3613
 
@@ -3121,6 +3662,85 @@ function emitChunk(request, task, value) {
3121
3662
  emitTextChunk(request, id, value);
3122
3663
  return;
3123
3664
  }
3665
+
3666
+ {
3667
+ if (value instanceof ArrayBuffer) {
3668
+ emitTypedArrayChunk(request, id, 'A', new Uint8Array(value));
3669
+ return;
3670
+ }
3671
+
3672
+ if (value instanceof Int8Array) {
3673
+ // char
3674
+ emitTypedArrayChunk(request, id, 'O', value);
3675
+ return;
3676
+ }
3677
+
3678
+ if (value instanceof Uint8Array) {
3679
+ // unsigned char
3680
+ emitTypedArrayChunk(request, id, 'o', value);
3681
+ return;
3682
+ }
3683
+
3684
+ if (value instanceof Uint8ClampedArray) {
3685
+ // unsigned clamped char
3686
+ emitTypedArrayChunk(request, id, 'U', value);
3687
+ return;
3688
+ }
3689
+
3690
+ if (value instanceof Int16Array) {
3691
+ // sort
3692
+ emitTypedArrayChunk(request, id, 'S', value);
3693
+ return;
3694
+ }
3695
+
3696
+ if (value instanceof Uint16Array) {
3697
+ // unsigned short
3698
+ emitTypedArrayChunk(request, id, 's', value);
3699
+ return;
3700
+ }
3701
+
3702
+ if (value instanceof Int32Array) {
3703
+ // long
3704
+ emitTypedArrayChunk(request, id, 'L', value);
3705
+ return;
3706
+ }
3707
+
3708
+ if (value instanceof Uint32Array) {
3709
+ // unsigned long
3710
+ emitTypedArrayChunk(request, id, 'l', value);
3711
+ return;
3712
+ }
3713
+
3714
+ if (value instanceof Float32Array) {
3715
+ // float
3716
+ emitTypedArrayChunk(request, id, 'G', value);
3717
+ return;
3718
+ }
3719
+
3720
+ if (value instanceof Float64Array) {
3721
+ // double
3722
+ emitTypedArrayChunk(request, id, 'g', value);
3723
+ return;
3724
+ }
3725
+
3726
+ if (value instanceof BigInt64Array) {
3727
+ // number
3728
+ emitTypedArrayChunk(request, id, 'M', value);
3729
+ return;
3730
+ }
3731
+
3732
+ if (value instanceof BigUint64Array) {
3733
+ // unsigned number
3734
+ // We use "m" instead of "n" since JSON can start with "null"
3735
+ emitTypedArrayChunk(request, id, 'm', value);
3736
+ return;
3737
+ }
3738
+
3739
+ if (value instanceof DataView) {
3740
+ emitTypedArrayChunk(request, id, 'V', value);
3741
+ return;
3742
+ }
3743
+ } // For anything else we need to try to serialize it using JSON.
3124
3744
  // $FlowFixMe[incompatible-type] stringify can return null for undefined but we never do
3125
3745
 
3126
3746
 
@@ -3166,8 +3786,11 @@ function retryTask(request, task) {
3166
3786
  task.implicitSlot = false;
3167
3787
 
3168
3788
  if (typeof resolvedModel === 'object' && resolvedModel !== null) {
3169
- // Object might contain unresolved values like additional elements.
3789
+ // We're not in a contextual place here so we can refer to this object by this ID for
3790
+ // any future references.
3791
+ request.writtenObjects.set(resolvedModel, serializeByValueID(task.id)); // Object might contain unresolved values like additional elements.
3170
3792
  // This is simulating what the JSON loop would do if this was part of it.
3793
+
3171
3794
  emitChunk(request, task, resolvedModel);
3172
3795
  } else {
3173
3796
  // If the value is a string, it means it's a terminal value and we already escaped it
@@ -3209,6 +3832,26 @@ function retryTask(request, task) {
3209
3832
  }
3210
3833
  }
3211
3834
 
3835
+ function tryStreamTask(request, task) {
3836
+ // This is used to try to emit something synchronously but if it suspends,
3837
+ // we emit a reference to a new outlined task immediately instead.
3838
+ var prevDebugID = debugID;
3839
+
3840
+ {
3841
+ // We don't use the id of the stream task for debugID. Instead we leave it null
3842
+ // so that we instead outline the row to get a new debugID if needed.
3843
+ debugID = null;
3844
+ }
3845
+
3846
+ try {
3847
+ emitChunk(request, task, task.model);
3848
+ } finally {
3849
+ {
3850
+ debugID = prevDebugID;
3851
+ }
3852
+ }
3853
+ }
3854
+
3212
3855
  function performWork(request) {
3213
3856
  var prevDispatcher = ReactSharedInternals.H;
3214
3857
  ReactSharedInternals.H = HooksDispatcher;
@@ -3508,9 +4151,12 @@ function requireModule(metadata) {
3508
4151
  return moduleExports[metadata.name];
3509
4152
  }
3510
4153
 
3511
- // The server acts as a Client of itself when resolving Server References.
4154
+ // $FlowFixMe[method-unbinding]
4155
+ var hasOwnProperty = Object.prototype.hasOwnProperty;
4156
+
3512
4157
  var PENDING = 'pending';
3513
4158
  var BLOCKED = 'blocked';
4159
+ var CYCLIC = 'cyclic';
3514
4160
  var RESOLVED_MODEL = 'resolved_model';
3515
4161
  var INITIALIZED = 'fulfilled';
3516
4162
  var ERRORED = 'rejected'; // $FlowFixMe[missing-this-annot]
@@ -3543,6 +4189,7 @@ Chunk.prototype.then = function (resolve, reject) {
3543
4189
 
3544
4190
  case PENDING:
3545
4191
  case BLOCKED:
4192
+ case CYCLIC:
3546
4193
  if (resolve) {
3547
4194
  if (chunk.value === null) {
3548
4195
  chunk.value = [];
@@ -3592,6 +4239,7 @@ function wakeChunkIfInitialized(chunk, resolveListeners, rejectListeners) {
3592
4239
 
3593
4240
  case PENDING:
3594
4241
  case BLOCKED:
4242
+ case CYCLIC:
3595
4243
  chunk.value = resolveListeners;
3596
4244
  chunk.reason = rejectListeners;
3597
4245
  break;
@@ -3607,7 +4255,15 @@ function wakeChunkIfInitialized(chunk, resolveListeners, rejectListeners) {
3607
4255
 
3608
4256
  function triggerErrorOnChunk(chunk, error) {
3609
4257
  if (chunk.status !== PENDING && chunk.status !== BLOCKED) {
3610
- // We already resolved. We didn't expect to see this.
4258
+ {
4259
+ // If we get more data to an already resolved ID, we assume that it's
4260
+ // a stream chunk since any other row shouldn't have more than one entry.
4261
+ var streamChunk = chunk;
4262
+ var controller = streamChunk.reason; // $FlowFixMe[incompatible-call]: The error method should accept mixed.
4263
+
4264
+ controller.error(error);
4265
+ }
4266
+
3611
4267
  return;
3612
4268
  }
3613
4269
 
@@ -3621,14 +4277,26 @@ function triggerErrorOnChunk(chunk, error) {
3621
4277
  }
3622
4278
  }
3623
4279
 
3624
- function createResolvedModelChunk(response, value) {
4280
+ function createResolvedModelChunk(response, value, id) {
3625
4281
  // $FlowFixMe[invalid-constructor] Flow doesn't support functions as constructors
3626
- return new Chunk(RESOLVED_MODEL, value, null, response);
4282
+ return new Chunk(RESOLVED_MODEL, value, id, response);
3627
4283
  }
3628
4284
 
3629
- function resolveModelChunk(chunk, value) {
4285
+ function resolveModelChunk(chunk, value, id) {
3630
4286
  if (chunk.status !== PENDING) {
3631
- // We already resolved. We didn't expect to see this.
4287
+ {
4288
+ // If we get more data to an already resolved ID, we assume that it's
4289
+ // a stream chunk since any other row shouldn't have more than one entry.
4290
+ var streamChunk = chunk;
4291
+ var controller = streamChunk.reason;
4292
+
4293
+ if (value[0] === 'C') {
4294
+ controller.close(value === 'C' ? '"$undefined"' : value.slice(1));
4295
+ } else {
4296
+ controller.enqueueModel(value);
4297
+ }
4298
+ }
4299
+
3632
4300
  return;
3633
4301
  }
3634
4302
 
@@ -3637,6 +4305,7 @@ function resolveModelChunk(chunk, value) {
3637
4305
  var resolvedChunk = chunk;
3638
4306
  resolvedChunk.status = RESOLVED_MODEL;
3639
4307
  resolvedChunk.value = value;
4308
+ resolvedChunk.reason = id;
3640
4309
 
3641
4310
  if (resolveListeners !== null) {
3642
4311
  // This is unfortunate that we're reading this eagerly if
@@ -3648,6 +4317,26 @@ function resolveModelChunk(chunk, value) {
3648
4317
  }
3649
4318
  }
3650
4319
 
4320
+ function createInitializedStreamChunk(response, value, controller) {
4321
+ // We use the reason field to stash the controller since we already have that
4322
+ // field. It's a bit of a hack but efficient.
4323
+ // $FlowFixMe[invalid-constructor] Flow doesn't support functions as constructors
4324
+ return new Chunk(INITIALIZED, value, controller, response);
4325
+ }
4326
+
4327
+ function createResolvedIteratorResultChunk(response, value, done) {
4328
+ // To reuse code as much code as possible we add the wrapper element as part of the JSON.
4329
+ var iteratorResultJSON = (done ? '{"done":true,"value":' : '{"done":false,"value":') + value + '}'; // $FlowFixMe[invalid-constructor] Flow doesn't support functions as constructors
4330
+
4331
+ return new Chunk(RESOLVED_MODEL, iteratorResultJSON, -1, response);
4332
+ }
4333
+
4334
+ function resolveIteratorResultChunk(chunk, value, done) {
4335
+ // To reuse code as much code as possible we add the wrapper element as part of the JSON.
4336
+ var iteratorResultJSON = (done ? '{"done":true,"value":' : '{"done":false,"value":') + value + '}';
4337
+ resolveModelChunk(chunk, iteratorResultJSON, -1);
4338
+ }
4339
+
3651
4340
  function bindArgs$1(fn, args) {
3652
4341
  return fn.bind.apply(fn, [null].concat(args));
3653
4342
  }
@@ -3676,11 +4365,51 @@ function loadServerReference$1(response, id, bound, parentChunk, parentObject, k
3676
4365
  }
3677
4366
  }
3678
4367
 
3679
- promise.then(createModelResolver(parentChunk, parentObject, key), createModelReject(parentChunk)); // We need a placeholder value that will be replaced later.
4368
+ promise.then(createModelResolver(parentChunk, parentObject, key, false, response, createModel, []), createModelReject(parentChunk)); // We need a placeholder value that will be replaced later.
3680
4369
 
3681
4370
  return null;
3682
4371
  }
3683
4372
 
4373
+ function reviveModel(response, parentObj, parentKey, value, reference) {
4374
+ if (typeof value === 'string') {
4375
+ // We can't use .bind here because we need the "this" value.
4376
+ return parseModelString(response, parentObj, parentKey, value, reference);
4377
+ }
4378
+
4379
+ if (typeof value === 'object' && value !== null) {
4380
+ if (reference !== undefined && response._temporaryReferences !== undefined) {
4381
+ // Store this object's reference in case it's returned later.
4382
+ registerTemporaryReference(response._temporaryReferences, value, reference);
4383
+ }
4384
+
4385
+ if (Array.isArray(value)) {
4386
+ for (var i = 0; i < value.length; i++) {
4387
+ var childRef = reference !== undefined ? reference + ':' + i : undefined; // $FlowFixMe[cannot-write]
4388
+
4389
+ value[i] = reviveModel(response, value, '' + i, value[i], childRef);
4390
+ }
4391
+ } else {
4392
+ for (var key in value) {
4393
+ if (hasOwnProperty.call(value, key)) {
4394
+ var _childRef = reference !== undefined && key.indexOf(':') === -1 ? reference + ':' + key : undefined;
4395
+
4396
+ var newValue = reviveModel(response, value, key, value[key], _childRef);
4397
+
4398
+ if (newValue !== undefined) {
4399
+ // $FlowFixMe[cannot-write]
4400
+ value[key] = newValue;
4401
+ } else {
4402
+ // $FlowFixMe[cannot-write]
4403
+ delete value[key];
4404
+ }
4405
+ }
4406
+ }
4407
+ }
4408
+ }
4409
+
4410
+ return value;
4411
+ }
4412
+
3684
4413
  var initializingChunk = null;
3685
4414
  var initializingChunkBlockedModel = null;
3686
4415
 
@@ -3689,9 +4418,21 @@ function initializeModelChunk(chunk) {
3689
4418
  var prevBlocked = initializingChunkBlockedModel;
3690
4419
  initializingChunk = chunk;
3691
4420
  initializingChunkBlockedModel = null;
4421
+ var rootReference = chunk.reason === -1 ? undefined : chunk.reason.toString(16);
4422
+ var resolvedModel = chunk.value; // We go to the CYCLIC state until we've fully resolved this.
4423
+ // We do this before parsing in case we try to initialize the same chunk
4424
+ // while parsing the model. Such as in a cyclic reference.
4425
+
4426
+ var cyclicChunk = chunk;
4427
+ cyclicChunk.status = CYCLIC;
4428
+ cyclicChunk.value = null;
4429
+ cyclicChunk.reason = null;
3692
4430
 
3693
4431
  try {
3694
- var value = JSON.parse(chunk.value, chunk._response._fromJSON);
4432
+ var rawModel = JSON.parse(resolvedModel);
4433
+ var value = reviveModel(chunk._response, {
4434
+ '': rawModel
4435
+ }, '', rawModel, rootReference);
3695
4436
 
3696
4437
  if (initializingChunkBlockedModel !== null && initializingChunkBlockedModel.deps > 0) {
3697
4438
  initializingChunkBlockedModel.value = value; // We discovered new dependencies on modules that are not yet resolved.
@@ -3702,9 +4443,14 @@ function initializeModelChunk(chunk) {
3702
4443
  blockedChunk.value = null;
3703
4444
  blockedChunk.reason = null;
3704
4445
  } else {
4446
+ var resolveListeners = cyclicChunk.value;
3705
4447
  var initializedChunk = chunk;
3706
4448
  initializedChunk.status = INITIALIZED;
3707
4449
  initializedChunk.value = value;
4450
+
4451
+ if (resolveListeners !== null) {
4452
+ wakeChunk(resolveListeners, value);
4453
+ }
3708
4454
  }
3709
4455
  } catch (error) {
3710
4456
  var erroredChunk = chunk;
@@ -3741,7 +4487,7 @@ function getChunk(response, id) {
3741
4487
 
3742
4488
  if (backingEntry != null) {
3743
4489
  // We assume that this is a string entry for now.
3744
- chunk = createResolvedModelChunk(response, backingEntry);
4490
+ chunk = createResolvedModelChunk(response, backingEntry, id);
3745
4491
  } else {
3746
4492
  // We're still waiting on this entry to stream in.
3747
4493
  chunk = createPendingChunk(response);
@@ -3753,21 +4499,34 @@ function getChunk(response, id) {
3753
4499
  return chunk;
3754
4500
  }
3755
4501
 
3756
- function createModelResolver(chunk, parentObject, key) {
4502
+ function createModelResolver(chunk, parentObject, key, cyclic, response, map, path) {
3757
4503
  var blocked;
3758
4504
 
3759
4505
  if (initializingChunkBlockedModel) {
3760
4506
  blocked = initializingChunkBlockedModel;
3761
- blocked.deps++;
4507
+
4508
+ if (!cyclic) {
4509
+ blocked.deps++;
4510
+ }
3762
4511
  } else {
3763
4512
  blocked = initializingChunkBlockedModel = {
3764
- deps: 1,
4513
+ deps: cyclic ? 0 : 1,
3765
4514
  value: null
3766
4515
  };
3767
4516
  }
3768
4517
 
3769
4518
  return function (value) {
3770
- parentObject[key] = value;
4519
+ for (var i = 1; i < path.length; i++) {
4520
+ value = value[path[i]];
4521
+ }
4522
+
4523
+ parentObject[key] = map(response, value); // If this is the root object for a model reference, where `blocked.value`
4524
+ // is a stale `null`, the resolved value can be used directly.
4525
+
4526
+ if (key === '' && blocked.value === null) {
4527
+ blocked.value = parentObject[key];
4528
+ }
4529
+
3771
4530
  blocked.deps--;
3772
4531
 
3773
4532
  if (blocked.deps === 0) {
@@ -3793,22 +4552,271 @@ function createModelReject(chunk) {
3793
4552
  };
3794
4553
  }
3795
4554
 
3796
- function getOutlinedModel(response, id) {
4555
+ function getOutlinedModel(response, reference, parentObject, key, map) {
4556
+ var path = reference.split(':');
4557
+ var id = parseInt(path[0], 16);
3797
4558
  var chunk = getChunk(response, id);
3798
4559
 
3799
- if (chunk.status === RESOLVED_MODEL) {
3800
- initializeModelChunk(chunk);
4560
+ switch (chunk.status) {
4561
+ case RESOLVED_MODEL:
4562
+ initializeModelChunk(chunk);
4563
+ break;
4564
+ } // The status might have changed after initialization.
4565
+
4566
+
4567
+ switch (chunk.status) {
4568
+ case INITIALIZED:
4569
+ var value = chunk.value;
4570
+
4571
+ for (var i = 1; i < path.length; i++) {
4572
+ value = value[path[i]];
4573
+ }
4574
+
4575
+ return map(response, value);
4576
+
4577
+ case PENDING:
4578
+ case BLOCKED:
4579
+ case CYCLIC:
4580
+ var parentChunk = initializingChunk;
4581
+ chunk.then(createModelResolver(parentChunk, parentObject, key, chunk.status === CYCLIC, response, map, path), createModelReject(parentChunk));
4582
+ return null;
4583
+
4584
+ default:
4585
+ throw chunk.reason;
3801
4586
  }
4587
+ }
4588
+
4589
+ function createMap(response, model) {
4590
+ return new Map(model);
4591
+ }
3802
4592
 
3803
- if (chunk.status !== INITIALIZED) {
3804
- // We know that this is emitted earlier so otherwise it's an error.
3805
- throw chunk.reason;
4593
+ function createSet(response, model) {
4594
+ return new Set(model);
4595
+ }
4596
+
4597
+ function extractIterator(response, model) {
4598
+ // $FlowFixMe[incompatible-use]: This uses raw Symbols because we're extracting from a native array.
4599
+ return model[Symbol.iterator]();
4600
+ }
4601
+
4602
+ function createModel(response, model) {
4603
+ return model;
4604
+ }
4605
+
4606
+ function parseTypedArray(response, reference, constructor, bytesPerElement, parentObject, parentKey) {
4607
+ var id = parseInt(reference.slice(2), 16);
4608
+ var prefix = response._prefix;
4609
+ var key = prefix + id; // We should have this backingEntry in the store already because we emitted
4610
+ // it before referencing it. It should be a Blob.
4611
+
4612
+ var backingEntry = response._formData.get(key);
4613
+
4614
+ var promise = constructor === ArrayBuffer ? backingEntry.arrayBuffer() : backingEntry.arrayBuffer().then(function (buffer) {
4615
+ return new constructor(buffer);
4616
+ }); // Since loading the buffer is an async operation we'll be blocking the parent
4617
+ // chunk.
4618
+
4619
+ var parentChunk = initializingChunk;
4620
+ promise.then(createModelResolver(parentChunk, parentObject, parentKey, false, response, createModel, []), createModelReject(parentChunk));
4621
+ return null;
4622
+ }
4623
+
4624
+ function resolveStream(response, id, stream, controller) {
4625
+ var chunks = response._chunks;
4626
+ var chunk = createInitializedStreamChunk(response, stream, controller);
4627
+ chunks.set(id, chunk);
4628
+ var prefix = response._prefix;
4629
+ var key = prefix + id;
4630
+
4631
+ var existingEntries = response._formData.getAll(key);
4632
+
4633
+ for (var i = 0; i < existingEntries.length; i++) {
4634
+ // We assume that this is a string entry for now.
4635
+ var value = existingEntries[i];
4636
+
4637
+ if (value[0] === 'C') {
4638
+ controller.close(value === 'C' ? '"$undefined"' : value.slice(1));
4639
+ } else {
4640
+ controller.enqueueModel(value);
4641
+ }
3806
4642
  }
4643
+ }
3807
4644
 
3808
- return chunk.value;
4645
+ function parseReadableStream(response, reference, type, parentObject, parentKey) {
4646
+ var id = parseInt(reference.slice(2), 16);
4647
+ var controller = null;
4648
+ var stream = new ReadableStream({
4649
+ type: type,
4650
+ start: function (c) {
4651
+ controller = c;
4652
+ }
4653
+ });
4654
+ var previousBlockedChunk = null;
4655
+ var flightController = {
4656
+ enqueueModel: function (json) {
4657
+ if (previousBlockedChunk === null) {
4658
+ // If we're not blocked on any other chunks, we can try to eagerly initialize
4659
+ // this as a fast-path to avoid awaiting them.
4660
+ var chunk = createResolvedModelChunk(response, json, -1);
4661
+ initializeModelChunk(chunk);
4662
+ var initializedChunk = chunk;
4663
+
4664
+ if (initializedChunk.status === INITIALIZED) {
4665
+ controller.enqueue(initializedChunk.value);
4666
+ } else {
4667
+ chunk.then(function (v) {
4668
+ return controller.enqueue(v);
4669
+ }, function (e) {
4670
+ return controller.error(e);
4671
+ });
4672
+ previousBlockedChunk = chunk;
4673
+ }
4674
+ } else {
4675
+ // We're still waiting on a previous chunk so we can't enqueue quite yet.
4676
+ var blockedChunk = previousBlockedChunk;
4677
+
4678
+ var _chunk = createPendingChunk(response);
4679
+
4680
+ _chunk.then(function (v) {
4681
+ return controller.enqueue(v);
4682
+ }, function (e) {
4683
+ return controller.error(e);
4684
+ });
4685
+
4686
+ previousBlockedChunk = _chunk;
4687
+ blockedChunk.then(function () {
4688
+ if (previousBlockedChunk === _chunk) {
4689
+ // We were still the last chunk so we can now clear the queue and return
4690
+ // to synchronous emitting.
4691
+ previousBlockedChunk = null;
4692
+ }
4693
+
4694
+ resolveModelChunk(_chunk, json, -1);
4695
+ });
4696
+ }
4697
+ },
4698
+ close: function (json) {
4699
+ if (previousBlockedChunk === null) {
4700
+ controller.close();
4701
+ } else {
4702
+ var blockedChunk = previousBlockedChunk; // We shouldn't get any more enqueues after this so we can set it back to null.
4703
+
4704
+ previousBlockedChunk = null;
4705
+ blockedChunk.then(function () {
4706
+ return controller.close();
4707
+ });
4708
+ }
4709
+ },
4710
+ error: function (error) {
4711
+ if (previousBlockedChunk === null) {
4712
+ // $FlowFixMe[incompatible-call]
4713
+ controller.error(error);
4714
+ } else {
4715
+ var blockedChunk = previousBlockedChunk; // We shouldn't get any more enqueues after this so we can set it back to null.
4716
+
4717
+ previousBlockedChunk = null;
4718
+ blockedChunk.then(function () {
4719
+ return controller.error(error);
4720
+ });
4721
+ }
4722
+ }
4723
+ };
4724
+ resolveStream(response, id, stream, flightController);
4725
+ return stream;
4726
+ }
4727
+
4728
+ function asyncIterator() {
4729
+ // Self referencing iterator.
4730
+ return this;
4731
+ }
4732
+
4733
+ function createIterator(next) {
4734
+ var iterator = {
4735
+ next: next // TODO: Add return/throw as options for aborting.
4736
+
4737
+ }; // TODO: The iterator could inherit the AsyncIterator prototype which is not exposed as
4738
+ // a global but exists as a prototype of an AsyncGenerator. However, it's not needed
4739
+ // to satisfy the iterable protocol.
4740
+
4741
+ iterator[ASYNC_ITERATOR] = asyncIterator;
4742
+ return iterator;
3809
4743
  }
3810
4744
 
3811
- function parseModelString(response, obj, key, value) {
4745
+ function parseAsyncIterable(response, reference, iterator, parentObject, parentKey) {
4746
+ var id = parseInt(reference.slice(2), 16);
4747
+ var buffer = [];
4748
+ var closed = false;
4749
+ var nextWriteIndex = 0;
4750
+ var flightController = {
4751
+ enqueueModel: function (value) {
4752
+ if (nextWriteIndex === buffer.length) {
4753
+ buffer[nextWriteIndex] = createResolvedIteratorResultChunk(response, value, false);
4754
+ } else {
4755
+ resolveIteratorResultChunk(buffer[nextWriteIndex], value, false);
4756
+ }
4757
+
4758
+ nextWriteIndex++;
4759
+ },
4760
+ close: function (value) {
4761
+ closed = true;
4762
+
4763
+ if (nextWriteIndex === buffer.length) {
4764
+ buffer[nextWriteIndex] = createResolvedIteratorResultChunk(response, value, true);
4765
+ } else {
4766
+ resolveIteratorResultChunk(buffer[nextWriteIndex], value, true);
4767
+ }
4768
+
4769
+ nextWriteIndex++;
4770
+
4771
+ while (nextWriteIndex < buffer.length) {
4772
+ // In generators, any extra reads from the iterator have the value undefined.
4773
+ resolveIteratorResultChunk(buffer[nextWriteIndex++], '"$undefined"', true);
4774
+ }
4775
+ },
4776
+ error: function (error) {
4777
+ closed = true;
4778
+
4779
+ if (nextWriteIndex === buffer.length) {
4780
+ buffer[nextWriteIndex] = createPendingChunk(response);
4781
+ }
4782
+
4783
+ while (nextWriteIndex < buffer.length) {
4784
+ triggerErrorOnChunk(buffer[nextWriteIndex++], error);
4785
+ }
4786
+ }
4787
+ };
4788
+
4789
+ var iterable = _defineProperty({}, ASYNC_ITERATOR, function () {
4790
+ var nextReadIndex = 0;
4791
+ return createIterator(function (arg) {
4792
+ if (arg !== undefined) {
4793
+ throw new Error('Values cannot be passed to next() of AsyncIterables passed to Client Components.');
4794
+ }
4795
+
4796
+ if (nextReadIndex === buffer.length) {
4797
+ if (closed) {
4798
+ // $FlowFixMe[invalid-constructor] Flow doesn't support functions as constructors
4799
+ return new Chunk(INITIALIZED, {
4800
+ done: true,
4801
+ value: undefined
4802
+ }, null, response);
4803
+ }
4804
+
4805
+ buffer[nextReadIndex] = createPendingChunk(response);
4806
+ }
4807
+
4808
+ return buffer[nextReadIndex++];
4809
+ });
4810
+ }); // TODO: If it's a single shot iterator we can optimize memory by cleaning up the buffer after
4811
+ // reading through the end, but currently we favor code size over this optimization.
4812
+
4813
+
4814
+ var stream = iterator ? iterable[ASYNC_ITERATOR]() : iterable;
4815
+ resolveStream(response, id, stream, flightController);
4816
+ return stream;
4817
+ }
4818
+
4819
+ function parseModelString(response, obj, key, value, reference) {
3812
4820
  if (value[0] === '$') {
3813
4821
  switch (value[1]) {
3814
4822
  case '$':
@@ -3820,46 +4828,45 @@ function parseModelString(response, obj, key, value) {
3820
4828
  case '@':
3821
4829
  {
3822
4830
  // Promise
3823
- var _id = parseInt(value.slice(2), 16);
3824
-
3825
- var _chunk = getChunk(response, _id);
3826
-
3827
- return _chunk;
4831
+ var id = parseInt(value.slice(2), 16);
4832
+ var chunk = getChunk(response, id);
4833
+ return chunk;
3828
4834
  }
3829
4835
 
3830
4836
  case 'F':
3831
4837
  {
3832
4838
  // Server Reference
3833
- var _id2 = parseInt(value.slice(2), 16); // TODO: Just encode this in the reference inline instead of as a model.
4839
+ var _ref2 = value.slice(2); // TODO: Just encode this in the reference inline instead of as a model.
3834
4840
 
3835
4841
 
3836
- var metaData = getOutlinedModel(response, _id2);
4842
+ var metaData = getOutlinedModel(response, _ref2, obj, key, createModel);
3837
4843
  return loadServerReference$1(response, metaData.id, metaData.bound, initializingChunk, obj, key);
3838
4844
  }
3839
4845
 
3840
4846
  case 'T':
3841
4847
  {
3842
4848
  // Temporary Reference
3843
- return createTemporaryReference(value.slice(2));
4849
+ if (reference === undefined || response._temporaryReferences === undefined) {
4850
+ throw new Error('Could not reference an opaque temporary reference. ' + 'This is likely due to misconfiguring the temporaryReferences options ' + 'on the server.');
4851
+ }
4852
+
4853
+ return createTemporaryReference(response._temporaryReferences, reference);
3844
4854
  }
3845
4855
 
3846
4856
  case 'Q':
3847
4857
  {
3848
4858
  // Map
3849
- var _id3 = parseInt(value.slice(2), 16);
4859
+ var _ref3 = value.slice(2);
3850
4860
 
3851
- var data = getOutlinedModel(response, _id3);
3852
- return new Map(data);
4861
+ return getOutlinedModel(response, _ref3, obj, key, createMap);
3853
4862
  }
3854
4863
 
3855
4864
  case 'W':
3856
4865
  {
3857
4866
  // Set
3858
- var _id4 = parseInt(value.slice(2), 16);
3859
-
3860
- var _data = getOutlinedModel(response, _id4);
4867
+ var _ref4 = value.slice(2);
3861
4868
 
3862
- return new Set(_data);
4869
+ return getOutlinedModel(response, _ref4, obj, key, createSet);
3863
4870
  }
3864
4871
 
3865
4872
  case 'K':
@@ -3867,9 +4874,7 @@ function parseModelString(response, obj, key, value) {
3867
4874
  // FormData
3868
4875
  var stringId = value.slice(2);
3869
4876
  var formPrefix = response._prefix + stringId + '_';
3870
-
3871
- var _data2 = new FormData();
3872
-
4877
+ var data = new FormData();
3873
4878
  var backingFormData = response._formData; // We assume that the reference to FormData always comes after each
3874
4879
  // entry that it references so we can assume they all exist in the
3875
4880
  // backing store already.
@@ -3877,20 +4882,18 @@ function parseModelString(response, obj, key, value) {
3877
4882
 
3878
4883
  backingFormData.forEach(function (entry, entryKey) {
3879
4884
  if (entryKey.startsWith(formPrefix)) {
3880
- _data2.append(entryKey.slice(formPrefix.length), entry);
4885
+ data.append(entryKey.slice(formPrefix.length), entry);
3881
4886
  }
3882
4887
  });
3883
- return _data2;
4888
+ return data;
3884
4889
  }
3885
4890
 
3886
4891
  case 'i':
3887
4892
  {
3888
4893
  // Iterator
3889
- var _id5 = parseInt(value.slice(2), 16);
3890
-
3891
- var _data3 = getOutlinedModel(response, _id5);
4894
+ var _ref5 = value.slice(2);
3892
4895
 
3893
- return _data3[Symbol.iterator]();
4896
+ return getOutlinedModel(response, _ref5, obj, key, extractIterator);
3894
4897
  }
3895
4898
 
3896
4899
  case 'I':
@@ -3935,51 +4938,104 @@ function parseModelString(response, obj, key, value) {
3935
4938
  }
3936
4939
  }
3937
4940
 
4941
+ {
4942
+ switch (value[1]) {
4943
+ case 'A':
4944
+ return parseTypedArray(response, value, ArrayBuffer, 1, obj, key);
3938
4945
 
3939
- var id = parseInt(value.slice(1), 16);
3940
- var chunk = getChunk(response, id);
4946
+ case 'O':
4947
+ return parseTypedArray(response, value, Int8Array, 1, obj, key);
3941
4948
 
3942
- switch (chunk.status) {
3943
- case RESOLVED_MODEL:
3944
- initializeModelChunk(chunk);
3945
- break;
3946
- } // The status might have changed after initialization.
4949
+ case 'o':
4950
+ return parseTypedArray(response, value, Uint8Array, 1, obj, key);
4951
+
4952
+ case 'U':
4953
+ return parseTypedArray(response, value, Uint8ClampedArray, 1, obj, key);
4954
+
4955
+ case 'S':
4956
+ return parseTypedArray(response, value, Int16Array, 2, obj, key);
3947
4957
 
4958
+ case 's':
4959
+ return parseTypedArray(response, value, Uint16Array, 2, obj, key);
3948
4960
 
3949
- switch (chunk.status) {
3950
- case INITIALIZED:
3951
- return chunk.value;
4961
+ case 'L':
4962
+ return parseTypedArray(response, value, Int32Array, 4, obj, key);
3952
4963
 
3953
- case PENDING:
3954
- case BLOCKED:
3955
- var parentChunk = initializingChunk;
3956
- chunk.then(createModelResolver(parentChunk, obj, key), createModelReject(parentChunk));
3957
- return null;
4964
+ case 'l':
4965
+ return parseTypedArray(response, value, Uint32Array, 4, obj, key);
3958
4966
 
3959
- default:
3960
- throw chunk.reason;
4967
+ case 'G':
4968
+ return parseTypedArray(response, value, Float32Array, 4, obj, key);
4969
+
4970
+ case 'g':
4971
+ return parseTypedArray(response, value, Float64Array, 8, obj, key);
4972
+
4973
+ case 'M':
4974
+ return parseTypedArray(response, value, BigInt64Array, 8, obj, key);
4975
+
4976
+ case 'm':
4977
+ return parseTypedArray(response, value, BigUint64Array, 8, obj, key);
4978
+
4979
+ case 'V':
4980
+ return parseTypedArray(response, value, DataView, 1, obj, key);
4981
+
4982
+ case 'B':
4983
+ {
4984
+ // Blob
4985
+ var _id = parseInt(value.slice(2), 16);
4986
+
4987
+ var prefix = response._prefix;
4988
+ var blobKey = prefix + _id; // We should have this backingEntry in the store already because we emitted
4989
+ // it before referencing it. It should be a Blob.
4990
+
4991
+ var backingEntry = response._formData.get(blobKey);
4992
+
4993
+ return backingEntry;
4994
+ }
4995
+ }
3961
4996
  }
4997
+
4998
+ {
4999
+ switch (value[1]) {
5000
+ case 'R':
5001
+ {
5002
+ return parseReadableStream(response, value, undefined);
5003
+ }
5004
+
5005
+ case 'r':
5006
+ {
5007
+ return parseReadableStream(response, value, 'bytes');
5008
+ }
5009
+
5010
+ case 'X':
5011
+ {
5012
+ return parseAsyncIterable(response, value, false);
5013
+ }
5014
+
5015
+ case 'x':
5016
+ {
5017
+ return parseAsyncIterable(response, value, true);
5018
+ }
5019
+ }
5020
+ } // We assume that anything else is a reference ID.
5021
+
5022
+
5023
+ var ref = value.slice(1);
5024
+ return getOutlinedModel(response, ref, obj, key, createModel);
3962
5025
  }
3963
5026
 
3964
5027
  return value;
3965
5028
  }
3966
5029
 
3967
- function createResponse(bundlerConfig, formFieldPrefix) {
3968
- var backingFormData = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : new FormData();
5030
+ function createResponse(bundlerConfig, formFieldPrefix, temporaryReferences) {
5031
+ var backingFormData = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : new FormData();
3969
5032
  var chunks = new Map();
3970
5033
  var response = {
3971
5034
  _bundlerConfig: bundlerConfig,
3972
5035
  _prefix: formFieldPrefix,
3973
5036
  _formData: backingFormData,
3974
5037
  _chunks: chunks,
3975
- _fromJSON: function (key, value) {
3976
- if (typeof value === 'string') {
3977
- // We can't use .bind here because we need the "this" value.
3978
- return parseModelString(response, this, key, value);
3979
- }
3980
-
3981
- return value;
3982
- }
5038
+ _temporaryReferences: temporaryReferences
3983
5039
  };
3984
5040
  return response;
3985
5041
  }
@@ -3996,7 +5052,7 @@ function resolveField(response, key, value) {
3996
5052
 
3997
5053
  if (chunk) {
3998
5054
  // We were waiting on this key so now we can resolve it.
3999
- resolveModelChunk(chunk, value);
5055
+ resolveModelChunk(chunk, value, id);
4000
5056
  }
4001
5057
  }
4002
5058
  }
@@ -4057,7 +5113,7 @@ function loadServerReference(bundlerConfig, id, bound) {
4057
5113
 
4058
5114
  function decodeBoundActionMetaData(body, serverManifest, formFieldPrefix) {
4059
5115
  // The data for this reference is encoded in multiple fields under this prefix.
4060
- var actionResponse = createResponse(serverManifest, formFieldPrefix, body);
5116
+ var actionResponse = createResponse(serverManifest, formFieldPrefix, undefined, body);
4061
5117
  close(actionResponse);
4062
5118
  var refPromise = getRoot(actionResponse); // Force it to initialize
4063
5119
  // $FlowFixMe
@@ -4166,7 +5222,7 @@ function createCancelHandler(request, reason) {
4166
5222
  }
4167
5223
 
4168
5224
  function renderToPipeableStream(model, webpackMap, options) {
4169
- var request = createRequest(model, webpackMap, options ? options.onError : undefined, options ? options.identifierPrefix : undefined, options ? options.onPostpone : undefined, options ? options.environmentName : undefined);
5225
+ 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);
4170
5226
  var hasStartedFlowing = false;
4171
5227
  startWork(request);
4172
5228
  return {
@@ -4240,20 +5296,21 @@ function decodeReplyFromBusboy(busboyStream, webpackMap) {
4240
5296
  return getRoot(response);
4241
5297
  }
4242
5298
 
4243
- function decodeReply(body, webpackMap) {
5299
+ function decodeReply(body, webpackMap, options) {
4244
5300
  if (typeof body === 'string') {
4245
5301
  var form = new FormData();
4246
5302
  form.append('0', body);
4247
5303
  body = form;
4248
5304
  }
4249
5305
 
4250
- var response = createResponse(webpackMap, '', body);
5306
+ var response = createResponse(webpackMap, '', options ? options.temporaryReferences : undefined, body);
4251
5307
  var root = getRoot(response);
4252
5308
  close(response);
4253
5309
  return root;
4254
5310
  }
4255
5311
 
4256
5312
  exports.createClientModuleProxy = createClientModuleProxy;
5313
+ exports.createTemporaryReferenceSet = createTemporaryReferenceSet;
4257
5314
  exports.decodeAction = decodeAction;
4258
5315
  exports.decodeFormState = decodeFormState;
4259
5316
  exports.decodeReply = decodeReply;