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;
@@ -3581,9 +4224,12 @@ function loadChunk(chunkId, filename) {
3581
4224
  return __webpack_chunk_load__(chunkId);
3582
4225
  }
3583
4226
 
3584
- // The server acts as a Client of itself when resolving Server References.
4227
+ // $FlowFixMe[method-unbinding]
4228
+ var hasOwnProperty = Object.prototype.hasOwnProperty;
4229
+
3585
4230
  var PENDING = 'pending';
3586
4231
  var BLOCKED = 'blocked';
4232
+ var CYCLIC = 'cyclic';
3587
4233
  var RESOLVED_MODEL = 'resolved_model';
3588
4234
  var INITIALIZED = 'fulfilled';
3589
4235
  var ERRORED = 'rejected'; // $FlowFixMe[missing-this-annot]
@@ -3616,6 +4262,7 @@ Chunk.prototype.then = function (resolve, reject) {
3616
4262
 
3617
4263
  case PENDING:
3618
4264
  case BLOCKED:
4265
+ case CYCLIC:
3619
4266
  if (resolve) {
3620
4267
  if (chunk.value === null) {
3621
4268
  chunk.value = [];
@@ -3665,6 +4312,7 @@ function wakeChunkIfInitialized(chunk, resolveListeners, rejectListeners) {
3665
4312
 
3666
4313
  case PENDING:
3667
4314
  case BLOCKED:
4315
+ case CYCLIC:
3668
4316
  chunk.value = resolveListeners;
3669
4317
  chunk.reason = rejectListeners;
3670
4318
  break;
@@ -3680,7 +4328,15 @@ function wakeChunkIfInitialized(chunk, resolveListeners, rejectListeners) {
3680
4328
 
3681
4329
  function triggerErrorOnChunk(chunk, error) {
3682
4330
  if (chunk.status !== PENDING && chunk.status !== BLOCKED) {
3683
- // We already resolved. We didn't expect to see this.
4331
+ {
4332
+ // If we get more data to an already resolved ID, we assume that it's
4333
+ // a stream chunk since any other row shouldn't have more than one entry.
4334
+ var streamChunk = chunk;
4335
+ var controller = streamChunk.reason; // $FlowFixMe[incompatible-call]: The error method should accept mixed.
4336
+
4337
+ controller.error(error);
4338
+ }
4339
+
3684
4340
  return;
3685
4341
  }
3686
4342
 
@@ -3694,14 +4350,26 @@ function triggerErrorOnChunk(chunk, error) {
3694
4350
  }
3695
4351
  }
3696
4352
 
3697
- function createResolvedModelChunk(response, value) {
4353
+ function createResolvedModelChunk(response, value, id) {
3698
4354
  // $FlowFixMe[invalid-constructor] Flow doesn't support functions as constructors
3699
- return new Chunk(RESOLVED_MODEL, value, null, response);
4355
+ return new Chunk(RESOLVED_MODEL, value, id, response);
3700
4356
  }
3701
4357
 
3702
- function resolveModelChunk(chunk, value) {
4358
+ function resolveModelChunk(chunk, value, id) {
3703
4359
  if (chunk.status !== PENDING) {
3704
- // We already resolved. We didn't expect to see this.
4360
+ {
4361
+ // If we get more data to an already resolved ID, we assume that it's
4362
+ // a stream chunk since any other row shouldn't have more than one entry.
4363
+ var streamChunk = chunk;
4364
+ var controller = streamChunk.reason;
4365
+
4366
+ if (value[0] === 'C') {
4367
+ controller.close(value === 'C' ? '"$undefined"' : value.slice(1));
4368
+ } else {
4369
+ controller.enqueueModel(value);
4370
+ }
4371
+ }
4372
+
3705
4373
  return;
3706
4374
  }
3707
4375
 
@@ -3710,6 +4378,7 @@ function resolveModelChunk(chunk, value) {
3710
4378
  var resolvedChunk = chunk;
3711
4379
  resolvedChunk.status = RESOLVED_MODEL;
3712
4380
  resolvedChunk.value = value;
4381
+ resolvedChunk.reason = id;
3713
4382
 
3714
4383
  if (resolveListeners !== null) {
3715
4384
  // This is unfortunate that we're reading this eagerly if
@@ -3721,6 +4390,26 @@ function resolveModelChunk(chunk, value) {
3721
4390
  }
3722
4391
  }
3723
4392
 
4393
+ function createInitializedStreamChunk(response, value, controller) {
4394
+ // We use the reason field to stash the controller since we already have that
4395
+ // field. It's a bit of a hack but efficient.
4396
+ // $FlowFixMe[invalid-constructor] Flow doesn't support functions as constructors
4397
+ return new Chunk(INITIALIZED, value, controller, response);
4398
+ }
4399
+
4400
+ function createResolvedIteratorResultChunk(response, value, done) {
4401
+ // To reuse code as much code as possible we add the wrapper element as part of the JSON.
4402
+ var iteratorResultJSON = (done ? '{"done":true,"value":' : '{"done":false,"value":') + value + '}'; // $FlowFixMe[invalid-constructor] Flow doesn't support functions as constructors
4403
+
4404
+ return new Chunk(RESOLVED_MODEL, iteratorResultJSON, -1, response);
4405
+ }
4406
+
4407
+ function resolveIteratorResultChunk(chunk, value, done) {
4408
+ // To reuse code as much code as possible we add the wrapper element as part of the JSON.
4409
+ var iteratorResultJSON = (done ? '{"done":true,"value":' : '{"done":false,"value":') + value + '}';
4410
+ resolveModelChunk(chunk, iteratorResultJSON, -1);
4411
+ }
4412
+
3724
4413
  function bindArgs$1(fn, args) {
3725
4414
  return fn.bind.apply(fn, [null].concat(args));
3726
4415
  }
@@ -3749,11 +4438,51 @@ function loadServerReference$1(response, id, bound, parentChunk, parentObject, k
3749
4438
  }
3750
4439
  }
3751
4440
 
3752
- promise.then(createModelResolver(parentChunk, parentObject, key), createModelReject(parentChunk)); // We need a placeholder value that will be replaced later.
4441
+ promise.then(createModelResolver(parentChunk, parentObject, key, false, response, createModel, []), createModelReject(parentChunk)); // We need a placeholder value that will be replaced later.
3753
4442
 
3754
4443
  return null;
3755
4444
  }
3756
4445
 
4446
+ function reviveModel(response, parentObj, parentKey, value, reference) {
4447
+ if (typeof value === 'string') {
4448
+ // We can't use .bind here because we need the "this" value.
4449
+ return parseModelString(response, parentObj, parentKey, value, reference);
4450
+ }
4451
+
4452
+ if (typeof value === 'object' && value !== null) {
4453
+ if (reference !== undefined && response._temporaryReferences !== undefined) {
4454
+ // Store this object's reference in case it's returned later.
4455
+ registerTemporaryReference(response._temporaryReferences, value, reference);
4456
+ }
4457
+
4458
+ if (Array.isArray(value)) {
4459
+ for (var i = 0; i < value.length; i++) {
4460
+ var childRef = reference !== undefined ? reference + ':' + i : undefined; // $FlowFixMe[cannot-write]
4461
+
4462
+ value[i] = reviveModel(response, value, '' + i, value[i], childRef);
4463
+ }
4464
+ } else {
4465
+ for (var key in value) {
4466
+ if (hasOwnProperty.call(value, key)) {
4467
+ var _childRef = reference !== undefined && key.indexOf(':') === -1 ? reference + ':' + key : undefined;
4468
+
4469
+ var newValue = reviveModel(response, value, key, value[key], _childRef);
4470
+
4471
+ if (newValue !== undefined) {
4472
+ // $FlowFixMe[cannot-write]
4473
+ value[key] = newValue;
4474
+ } else {
4475
+ // $FlowFixMe[cannot-write]
4476
+ delete value[key];
4477
+ }
4478
+ }
4479
+ }
4480
+ }
4481
+ }
4482
+
4483
+ return value;
4484
+ }
4485
+
3757
4486
  var initializingChunk = null;
3758
4487
  var initializingChunkBlockedModel = null;
3759
4488
 
@@ -3762,9 +4491,21 @@ function initializeModelChunk(chunk) {
3762
4491
  var prevBlocked = initializingChunkBlockedModel;
3763
4492
  initializingChunk = chunk;
3764
4493
  initializingChunkBlockedModel = null;
4494
+ var rootReference = chunk.reason === -1 ? undefined : chunk.reason.toString(16);
4495
+ var resolvedModel = chunk.value; // We go to the CYCLIC state until we've fully resolved this.
4496
+ // We do this before parsing in case we try to initialize the same chunk
4497
+ // while parsing the model. Such as in a cyclic reference.
4498
+
4499
+ var cyclicChunk = chunk;
4500
+ cyclicChunk.status = CYCLIC;
4501
+ cyclicChunk.value = null;
4502
+ cyclicChunk.reason = null;
3765
4503
 
3766
4504
  try {
3767
- var value = JSON.parse(chunk.value, chunk._response._fromJSON);
4505
+ var rawModel = JSON.parse(resolvedModel);
4506
+ var value = reviveModel(chunk._response, {
4507
+ '': rawModel
4508
+ }, '', rawModel, rootReference);
3768
4509
 
3769
4510
  if (initializingChunkBlockedModel !== null && initializingChunkBlockedModel.deps > 0) {
3770
4511
  initializingChunkBlockedModel.value = value; // We discovered new dependencies on modules that are not yet resolved.
@@ -3775,9 +4516,14 @@ function initializeModelChunk(chunk) {
3775
4516
  blockedChunk.value = null;
3776
4517
  blockedChunk.reason = null;
3777
4518
  } else {
4519
+ var resolveListeners = cyclicChunk.value;
3778
4520
  var initializedChunk = chunk;
3779
4521
  initializedChunk.status = INITIALIZED;
3780
4522
  initializedChunk.value = value;
4523
+
4524
+ if (resolveListeners !== null) {
4525
+ wakeChunk(resolveListeners, value);
4526
+ }
3781
4527
  }
3782
4528
  } catch (error) {
3783
4529
  var erroredChunk = chunk;
@@ -3814,7 +4560,7 @@ function getChunk(response, id) {
3814
4560
 
3815
4561
  if (backingEntry != null) {
3816
4562
  // We assume that this is a string entry for now.
3817
- chunk = createResolvedModelChunk(response, backingEntry);
4563
+ chunk = createResolvedModelChunk(response, backingEntry, id);
3818
4564
  } else {
3819
4565
  // We're still waiting on this entry to stream in.
3820
4566
  chunk = createPendingChunk(response);
@@ -3826,21 +4572,34 @@ function getChunk(response, id) {
3826
4572
  return chunk;
3827
4573
  }
3828
4574
 
3829
- function createModelResolver(chunk, parentObject, key) {
4575
+ function createModelResolver(chunk, parentObject, key, cyclic, response, map, path) {
3830
4576
  var blocked;
3831
4577
 
3832
4578
  if (initializingChunkBlockedModel) {
3833
4579
  blocked = initializingChunkBlockedModel;
3834
- blocked.deps++;
4580
+
4581
+ if (!cyclic) {
4582
+ blocked.deps++;
4583
+ }
3835
4584
  } else {
3836
4585
  blocked = initializingChunkBlockedModel = {
3837
- deps: 1,
4586
+ deps: cyclic ? 0 : 1,
3838
4587
  value: null
3839
4588
  };
3840
4589
  }
3841
4590
 
3842
4591
  return function (value) {
3843
- parentObject[key] = value;
4592
+ for (var i = 1; i < path.length; i++) {
4593
+ value = value[path[i]];
4594
+ }
4595
+
4596
+ parentObject[key] = map(response, value); // If this is the root object for a model reference, where `blocked.value`
4597
+ // is a stale `null`, the resolved value can be used directly.
4598
+
4599
+ if (key === '' && blocked.value === null) {
4600
+ blocked.value = parentObject[key];
4601
+ }
4602
+
3844
4603
  blocked.deps--;
3845
4604
 
3846
4605
  if (blocked.deps === 0) {
@@ -3866,22 +4625,271 @@ function createModelReject(chunk) {
3866
4625
  };
3867
4626
  }
3868
4627
 
3869
- function getOutlinedModel(response, id) {
4628
+ function getOutlinedModel(response, reference, parentObject, key, map) {
4629
+ var path = reference.split(':');
4630
+ var id = parseInt(path[0], 16);
3870
4631
  var chunk = getChunk(response, id);
3871
4632
 
3872
- if (chunk.status === RESOLVED_MODEL) {
3873
- initializeModelChunk(chunk);
4633
+ switch (chunk.status) {
4634
+ case RESOLVED_MODEL:
4635
+ initializeModelChunk(chunk);
4636
+ break;
4637
+ } // The status might have changed after initialization.
4638
+
4639
+
4640
+ switch (chunk.status) {
4641
+ case INITIALIZED:
4642
+ var value = chunk.value;
4643
+
4644
+ for (var i = 1; i < path.length; i++) {
4645
+ value = value[path[i]];
4646
+ }
4647
+
4648
+ return map(response, value);
4649
+
4650
+ case PENDING:
4651
+ case BLOCKED:
4652
+ case CYCLIC:
4653
+ var parentChunk = initializingChunk;
4654
+ chunk.then(createModelResolver(parentChunk, parentObject, key, chunk.status === CYCLIC, response, map, path), createModelReject(parentChunk));
4655
+ return null;
4656
+
4657
+ default:
4658
+ throw chunk.reason;
3874
4659
  }
4660
+ }
4661
+
4662
+ function createMap(response, model) {
4663
+ return new Map(model);
4664
+ }
3875
4665
 
3876
- if (chunk.status !== INITIALIZED) {
3877
- // We know that this is emitted earlier so otherwise it's an error.
3878
- throw chunk.reason;
4666
+ function createSet(response, model) {
4667
+ return new Set(model);
4668
+ }
4669
+
4670
+ function extractIterator(response, model) {
4671
+ // $FlowFixMe[incompatible-use]: This uses raw Symbols because we're extracting from a native array.
4672
+ return model[Symbol.iterator]();
4673
+ }
4674
+
4675
+ function createModel(response, model) {
4676
+ return model;
4677
+ }
4678
+
4679
+ function parseTypedArray(response, reference, constructor, bytesPerElement, parentObject, parentKey) {
4680
+ var id = parseInt(reference.slice(2), 16);
4681
+ var prefix = response._prefix;
4682
+ var key = prefix + id; // We should have this backingEntry in the store already because we emitted
4683
+ // it before referencing it. It should be a Blob.
4684
+
4685
+ var backingEntry = response._formData.get(key);
4686
+
4687
+ var promise = constructor === ArrayBuffer ? backingEntry.arrayBuffer() : backingEntry.arrayBuffer().then(function (buffer) {
4688
+ return new constructor(buffer);
4689
+ }); // Since loading the buffer is an async operation we'll be blocking the parent
4690
+ // chunk.
4691
+
4692
+ var parentChunk = initializingChunk;
4693
+ promise.then(createModelResolver(parentChunk, parentObject, parentKey, false, response, createModel, []), createModelReject(parentChunk));
4694
+ return null;
4695
+ }
4696
+
4697
+ function resolveStream(response, id, stream, controller) {
4698
+ var chunks = response._chunks;
4699
+ var chunk = createInitializedStreamChunk(response, stream, controller);
4700
+ chunks.set(id, chunk);
4701
+ var prefix = response._prefix;
4702
+ var key = prefix + id;
4703
+
4704
+ var existingEntries = response._formData.getAll(key);
4705
+
4706
+ for (var i = 0; i < existingEntries.length; i++) {
4707
+ // We assume that this is a string entry for now.
4708
+ var value = existingEntries[i];
4709
+
4710
+ if (value[0] === 'C') {
4711
+ controller.close(value === 'C' ? '"$undefined"' : value.slice(1));
4712
+ } else {
4713
+ controller.enqueueModel(value);
4714
+ }
3879
4715
  }
4716
+ }
3880
4717
 
3881
- return chunk.value;
4718
+ function parseReadableStream(response, reference, type, parentObject, parentKey) {
4719
+ var id = parseInt(reference.slice(2), 16);
4720
+ var controller = null;
4721
+ var stream = new ReadableStream({
4722
+ type: type,
4723
+ start: function (c) {
4724
+ controller = c;
4725
+ }
4726
+ });
4727
+ var previousBlockedChunk = null;
4728
+ var flightController = {
4729
+ enqueueModel: function (json) {
4730
+ if (previousBlockedChunk === null) {
4731
+ // If we're not blocked on any other chunks, we can try to eagerly initialize
4732
+ // this as a fast-path to avoid awaiting them.
4733
+ var chunk = createResolvedModelChunk(response, json, -1);
4734
+ initializeModelChunk(chunk);
4735
+ var initializedChunk = chunk;
4736
+
4737
+ if (initializedChunk.status === INITIALIZED) {
4738
+ controller.enqueue(initializedChunk.value);
4739
+ } else {
4740
+ chunk.then(function (v) {
4741
+ return controller.enqueue(v);
4742
+ }, function (e) {
4743
+ return controller.error(e);
4744
+ });
4745
+ previousBlockedChunk = chunk;
4746
+ }
4747
+ } else {
4748
+ // We're still waiting on a previous chunk so we can't enqueue quite yet.
4749
+ var blockedChunk = previousBlockedChunk;
4750
+
4751
+ var _chunk = createPendingChunk(response);
4752
+
4753
+ _chunk.then(function (v) {
4754
+ return controller.enqueue(v);
4755
+ }, function (e) {
4756
+ return controller.error(e);
4757
+ });
4758
+
4759
+ previousBlockedChunk = _chunk;
4760
+ blockedChunk.then(function () {
4761
+ if (previousBlockedChunk === _chunk) {
4762
+ // We were still the last chunk so we can now clear the queue and return
4763
+ // to synchronous emitting.
4764
+ previousBlockedChunk = null;
4765
+ }
4766
+
4767
+ resolveModelChunk(_chunk, json, -1);
4768
+ });
4769
+ }
4770
+ },
4771
+ close: function (json) {
4772
+ if (previousBlockedChunk === null) {
4773
+ controller.close();
4774
+ } else {
4775
+ var blockedChunk = previousBlockedChunk; // We shouldn't get any more enqueues after this so we can set it back to null.
4776
+
4777
+ previousBlockedChunk = null;
4778
+ blockedChunk.then(function () {
4779
+ return controller.close();
4780
+ });
4781
+ }
4782
+ },
4783
+ error: function (error) {
4784
+ if (previousBlockedChunk === null) {
4785
+ // $FlowFixMe[incompatible-call]
4786
+ controller.error(error);
4787
+ } else {
4788
+ var blockedChunk = previousBlockedChunk; // We shouldn't get any more enqueues after this so we can set it back to null.
4789
+
4790
+ previousBlockedChunk = null;
4791
+ blockedChunk.then(function () {
4792
+ return controller.error(error);
4793
+ });
4794
+ }
4795
+ }
4796
+ };
4797
+ resolveStream(response, id, stream, flightController);
4798
+ return stream;
4799
+ }
4800
+
4801
+ function asyncIterator() {
4802
+ // Self referencing iterator.
4803
+ return this;
4804
+ }
4805
+
4806
+ function createIterator(next) {
4807
+ var iterator = {
4808
+ next: next // TODO: Add return/throw as options for aborting.
4809
+
4810
+ }; // TODO: The iterator could inherit the AsyncIterator prototype which is not exposed as
4811
+ // a global but exists as a prototype of an AsyncGenerator. However, it's not needed
4812
+ // to satisfy the iterable protocol.
4813
+
4814
+ iterator[ASYNC_ITERATOR] = asyncIterator;
4815
+ return iterator;
3882
4816
  }
3883
4817
 
3884
- function parseModelString(response, obj, key, value) {
4818
+ function parseAsyncIterable(response, reference, iterator, parentObject, parentKey) {
4819
+ var id = parseInt(reference.slice(2), 16);
4820
+ var buffer = [];
4821
+ var closed = false;
4822
+ var nextWriteIndex = 0;
4823
+ var flightController = {
4824
+ enqueueModel: function (value) {
4825
+ if (nextWriteIndex === buffer.length) {
4826
+ buffer[nextWriteIndex] = createResolvedIteratorResultChunk(response, value, false);
4827
+ } else {
4828
+ resolveIteratorResultChunk(buffer[nextWriteIndex], value, false);
4829
+ }
4830
+
4831
+ nextWriteIndex++;
4832
+ },
4833
+ close: function (value) {
4834
+ closed = true;
4835
+
4836
+ if (nextWriteIndex === buffer.length) {
4837
+ buffer[nextWriteIndex] = createResolvedIteratorResultChunk(response, value, true);
4838
+ } else {
4839
+ resolveIteratorResultChunk(buffer[nextWriteIndex], value, true);
4840
+ }
4841
+
4842
+ nextWriteIndex++;
4843
+
4844
+ while (nextWriteIndex < buffer.length) {
4845
+ // In generators, any extra reads from the iterator have the value undefined.
4846
+ resolveIteratorResultChunk(buffer[nextWriteIndex++], '"$undefined"', true);
4847
+ }
4848
+ },
4849
+ error: function (error) {
4850
+ closed = true;
4851
+
4852
+ if (nextWriteIndex === buffer.length) {
4853
+ buffer[nextWriteIndex] = createPendingChunk(response);
4854
+ }
4855
+
4856
+ while (nextWriteIndex < buffer.length) {
4857
+ triggerErrorOnChunk(buffer[nextWriteIndex++], error);
4858
+ }
4859
+ }
4860
+ };
4861
+
4862
+ var iterable = _defineProperty({}, ASYNC_ITERATOR, function () {
4863
+ var nextReadIndex = 0;
4864
+ return createIterator(function (arg) {
4865
+ if (arg !== undefined) {
4866
+ throw new Error('Values cannot be passed to next() of AsyncIterables passed to Client Components.');
4867
+ }
4868
+
4869
+ if (nextReadIndex === buffer.length) {
4870
+ if (closed) {
4871
+ // $FlowFixMe[invalid-constructor] Flow doesn't support functions as constructors
4872
+ return new Chunk(INITIALIZED, {
4873
+ done: true,
4874
+ value: undefined
4875
+ }, null, response);
4876
+ }
4877
+
4878
+ buffer[nextReadIndex] = createPendingChunk(response);
4879
+ }
4880
+
4881
+ return buffer[nextReadIndex++];
4882
+ });
4883
+ }); // TODO: If it's a single shot iterator we can optimize memory by cleaning up the buffer after
4884
+ // reading through the end, but currently we favor code size over this optimization.
4885
+
4886
+
4887
+ var stream = iterator ? iterable[ASYNC_ITERATOR]() : iterable;
4888
+ resolveStream(response, id, stream, flightController);
4889
+ return stream;
4890
+ }
4891
+
4892
+ function parseModelString(response, obj, key, value, reference) {
3885
4893
  if (value[0] === '$') {
3886
4894
  switch (value[1]) {
3887
4895
  case '$':
@@ -3893,46 +4901,45 @@ function parseModelString(response, obj, key, value) {
3893
4901
  case '@':
3894
4902
  {
3895
4903
  // Promise
3896
- var _id = parseInt(value.slice(2), 16);
3897
-
3898
- var _chunk = getChunk(response, _id);
3899
-
3900
- return _chunk;
4904
+ var id = parseInt(value.slice(2), 16);
4905
+ var chunk = getChunk(response, id);
4906
+ return chunk;
3901
4907
  }
3902
4908
 
3903
4909
  case 'F':
3904
4910
  {
3905
4911
  // Server Reference
3906
- var _id2 = parseInt(value.slice(2), 16); // TODO: Just encode this in the reference inline instead of as a model.
4912
+ var _ref2 = value.slice(2); // TODO: Just encode this in the reference inline instead of as a model.
3907
4913
 
3908
4914
 
3909
- var metaData = getOutlinedModel(response, _id2);
4915
+ var metaData = getOutlinedModel(response, _ref2, obj, key, createModel);
3910
4916
  return loadServerReference$1(response, metaData.id, metaData.bound, initializingChunk, obj, key);
3911
4917
  }
3912
4918
 
3913
4919
  case 'T':
3914
4920
  {
3915
4921
  // Temporary Reference
3916
- return createTemporaryReference(value.slice(2));
4922
+ if (reference === undefined || response._temporaryReferences === undefined) {
4923
+ throw new Error('Could not reference an opaque temporary reference. ' + 'This is likely due to misconfiguring the temporaryReferences options ' + 'on the server.');
4924
+ }
4925
+
4926
+ return createTemporaryReference(response._temporaryReferences, reference);
3917
4927
  }
3918
4928
 
3919
4929
  case 'Q':
3920
4930
  {
3921
4931
  // Map
3922
- var _id3 = parseInt(value.slice(2), 16);
4932
+ var _ref3 = value.slice(2);
3923
4933
 
3924
- var data = getOutlinedModel(response, _id3);
3925
- return new Map(data);
4934
+ return getOutlinedModel(response, _ref3, obj, key, createMap);
3926
4935
  }
3927
4936
 
3928
4937
  case 'W':
3929
4938
  {
3930
4939
  // Set
3931
- var _id4 = parseInt(value.slice(2), 16);
3932
-
3933
- var _data = getOutlinedModel(response, _id4);
4940
+ var _ref4 = value.slice(2);
3934
4941
 
3935
- return new Set(_data);
4942
+ return getOutlinedModel(response, _ref4, obj, key, createSet);
3936
4943
  }
3937
4944
 
3938
4945
  case 'K':
@@ -3940,9 +4947,7 @@ function parseModelString(response, obj, key, value) {
3940
4947
  // FormData
3941
4948
  var stringId = value.slice(2);
3942
4949
  var formPrefix = response._prefix + stringId + '_';
3943
-
3944
- var _data2 = new FormData();
3945
-
4950
+ var data = new FormData();
3946
4951
  var backingFormData = response._formData; // We assume that the reference to FormData always comes after each
3947
4952
  // entry that it references so we can assume they all exist in the
3948
4953
  // backing store already.
@@ -3950,20 +4955,18 @@ function parseModelString(response, obj, key, value) {
3950
4955
 
3951
4956
  backingFormData.forEach(function (entry, entryKey) {
3952
4957
  if (entryKey.startsWith(formPrefix)) {
3953
- _data2.append(entryKey.slice(formPrefix.length), entry);
4958
+ data.append(entryKey.slice(formPrefix.length), entry);
3954
4959
  }
3955
4960
  });
3956
- return _data2;
4961
+ return data;
3957
4962
  }
3958
4963
 
3959
4964
  case 'i':
3960
4965
  {
3961
4966
  // Iterator
3962
- var _id5 = parseInt(value.slice(2), 16);
3963
-
3964
- var _data3 = getOutlinedModel(response, _id5);
4967
+ var _ref5 = value.slice(2);
3965
4968
 
3966
- return _data3[Symbol.iterator]();
4969
+ return getOutlinedModel(response, _ref5, obj, key, extractIterator);
3967
4970
  }
3968
4971
 
3969
4972
  case 'I':
@@ -4008,51 +5011,104 @@ function parseModelString(response, obj, key, value) {
4008
5011
  }
4009
5012
  }
4010
5013
 
5014
+ {
5015
+ switch (value[1]) {
5016
+ case 'A':
5017
+ return parseTypedArray(response, value, ArrayBuffer, 1, obj, key);
4011
5018
 
4012
- var id = parseInt(value.slice(1), 16);
4013
- var chunk = getChunk(response, id);
5019
+ case 'O':
5020
+ return parseTypedArray(response, value, Int8Array, 1, obj, key);
4014
5021
 
4015
- switch (chunk.status) {
4016
- case RESOLVED_MODEL:
4017
- initializeModelChunk(chunk);
4018
- break;
4019
- } // The status might have changed after initialization.
5022
+ case 'o':
5023
+ return parseTypedArray(response, value, Uint8Array, 1, obj, key);
5024
+
5025
+ case 'U':
5026
+ return parseTypedArray(response, value, Uint8ClampedArray, 1, obj, key);
5027
+
5028
+ case 'S':
5029
+ return parseTypedArray(response, value, Int16Array, 2, obj, key);
4020
5030
 
5031
+ case 's':
5032
+ return parseTypedArray(response, value, Uint16Array, 2, obj, key);
4021
5033
 
4022
- switch (chunk.status) {
4023
- case INITIALIZED:
4024
- return chunk.value;
5034
+ case 'L':
5035
+ return parseTypedArray(response, value, Int32Array, 4, obj, key);
4025
5036
 
4026
- case PENDING:
4027
- case BLOCKED:
4028
- var parentChunk = initializingChunk;
4029
- chunk.then(createModelResolver(parentChunk, obj, key), createModelReject(parentChunk));
4030
- return null;
5037
+ case 'l':
5038
+ return parseTypedArray(response, value, Uint32Array, 4, obj, key);
4031
5039
 
4032
- default:
4033
- throw chunk.reason;
5040
+ case 'G':
5041
+ return parseTypedArray(response, value, Float32Array, 4, obj, key);
5042
+
5043
+ case 'g':
5044
+ return parseTypedArray(response, value, Float64Array, 8, obj, key);
5045
+
5046
+ case 'M':
5047
+ return parseTypedArray(response, value, BigInt64Array, 8, obj, key);
5048
+
5049
+ case 'm':
5050
+ return parseTypedArray(response, value, BigUint64Array, 8, obj, key);
5051
+
5052
+ case 'V':
5053
+ return parseTypedArray(response, value, DataView, 1, obj, key);
5054
+
5055
+ case 'B':
5056
+ {
5057
+ // Blob
5058
+ var _id = parseInt(value.slice(2), 16);
5059
+
5060
+ var prefix = response._prefix;
5061
+ var blobKey = prefix + _id; // We should have this backingEntry in the store already because we emitted
5062
+ // it before referencing it. It should be a Blob.
5063
+
5064
+ var backingEntry = response._formData.get(blobKey);
5065
+
5066
+ return backingEntry;
5067
+ }
5068
+ }
4034
5069
  }
5070
+
5071
+ {
5072
+ switch (value[1]) {
5073
+ case 'R':
5074
+ {
5075
+ return parseReadableStream(response, value, undefined);
5076
+ }
5077
+
5078
+ case 'r':
5079
+ {
5080
+ return parseReadableStream(response, value, 'bytes');
5081
+ }
5082
+
5083
+ case 'X':
5084
+ {
5085
+ return parseAsyncIterable(response, value, false);
5086
+ }
5087
+
5088
+ case 'x':
5089
+ {
5090
+ return parseAsyncIterable(response, value, true);
5091
+ }
5092
+ }
5093
+ } // We assume that anything else is a reference ID.
5094
+
5095
+
5096
+ var ref = value.slice(1);
5097
+ return getOutlinedModel(response, ref, obj, key, createModel);
4035
5098
  }
4036
5099
 
4037
5100
  return value;
4038
5101
  }
4039
5102
 
4040
- function createResponse(bundlerConfig, formFieldPrefix) {
4041
- var backingFormData = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : new FormData();
5103
+ function createResponse(bundlerConfig, formFieldPrefix, temporaryReferences) {
5104
+ var backingFormData = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : new FormData();
4042
5105
  var chunks = new Map();
4043
5106
  var response = {
4044
5107
  _bundlerConfig: bundlerConfig,
4045
5108
  _prefix: formFieldPrefix,
4046
5109
  _formData: backingFormData,
4047
5110
  _chunks: chunks,
4048
- _fromJSON: function (key, value) {
4049
- if (typeof value === 'string') {
4050
- // We can't use .bind here because we need the "this" value.
4051
- return parseModelString(response, this, key, value);
4052
- }
4053
-
4054
- return value;
4055
- }
5111
+ _temporaryReferences: temporaryReferences
4056
5112
  };
4057
5113
  return response;
4058
5114
  }
@@ -4069,7 +5125,7 @@ function resolveField(response, key, value) {
4069
5125
 
4070
5126
  if (chunk) {
4071
5127
  // We were waiting on this key so now we can resolve it.
4072
- resolveModelChunk(chunk, value);
5128
+ resolveModelChunk(chunk, value, id);
4073
5129
  }
4074
5130
  }
4075
5131
  }
@@ -4130,7 +5186,7 @@ function loadServerReference(bundlerConfig, id, bound) {
4130
5186
 
4131
5187
  function decodeBoundActionMetaData(body, serverManifest, formFieldPrefix) {
4132
5188
  // The data for this reference is encoded in multiple fields under this prefix.
4133
- var actionResponse = createResponse(serverManifest, formFieldPrefix, body);
5189
+ var actionResponse = createResponse(serverManifest, formFieldPrefix, undefined, body);
4134
5190
  close(actionResponse);
4135
5191
  var refPromise = getRoot(actionResponse); // Force it to initialize
4136
5192
  // $FlowFixMe
@@ -4239,7 +5295,7 @@ function createCancelHandler(request, reason) {
4239
5295
  }
4240
5296
 
4241
5297
  function renderToPipeableStream(model, webpackMap, options) {
4242
- var request = createRequest(model, webpackMap, options ? options.onError : undefined, options ? options.identifierPrefix : undefined, options ? options.onPostpone : undefined, options ? options.environmentName : undefined);
5298
+ 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);
4243
5299
  var hasStartedFlowing = false;
4244
5300
  startWork(request);
4245
5301
  return {
@@ -4313,20 +5369,21 @@ function decodeReplyFromBusboy(busboyStream, webpackMap) {
4313
5369
  return getRoot(response);
4314
5370
  }
4315
5371
 
4316
- function decodeReply(body, webpackMap) {
5372
+ function decodeReply(body, webpackMap, options) {
4317
5373
  if (typeof body === 'string') {
4318
5374
  var form = new FormData();
4319
5375
  form.append('0', body);
4320
5376
  body = form;
4321
5377
  }
4322
5378
 
4323
- var response = createResponse(webpackMap, '', body);
5379
+ var response = createResponse(webpackMap, '', options ? options.temporaryReferences : undefined, body);
4324
5380
  var root = getRoot(response);
4325
5381
  close(response);
4326
5382
  return root;
4327
5383
  }
4328
5384
 
4329
5385
  exports.createClientModuleProxy = createClientModuleProxy;
5386
+ exports.createTemporaryReferenceSet = createTemporaryReferenceSet;
4330
5387
  exports.decodeAction = decodeAction;
4331
5388
  exports.decodeFormState = decodeFormState;
4332
5389
  exports.decodeReply = decodeReply;