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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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);
@@ -837,11 +844,14 @@ var componentStorage = new async_hooks.AsyncLocalStorage() ;
837
844
 
838
845
  var TEMPORARY_REFERENCE_TAG = Symbol.for('react.temporary.reference'); // eslint-disable-next-line no-unused-vars
839
846
 
840
- function isTemporaryReference(reference) {
847
+ function createTemporaryReferenceSet() {
848
+ return new WeakMap();
849
+ }
850
+ function isOpaqueTemporaryReference(reference) {
841
851
  return reference.$$typeof === TEMPORARY_REFERENCE_TAG;
842
852
  }
843
- function resolveTemporaryReferenceID(temporaryReference) {
844
- return temporaryReference.$$id;
853
+ function resolveTemporaryReference(temporaryReferences, temporaryReference) {
854
+ return temporaryReferences.get(temporaryReference);
845
855
  }
846
856
  var proxyHandlers = {
847
857
  get: function (target, name, receiver) {
@@ -852,12 +862,6 @@ var proxyHandlers = {
852
862
  // have the Flight runtime extract the inner target instead.
853
863
  return target.$$typeof;
854
864
 
855
- case '$$id':
856
- return target.$$id;
857
-
858
- case '$$async':
859
- return target.$$async;
860
-
861
865
  case 'name':
862
866
  return undefined;
863
867
 
@@ -892,21 +896,28 @@ var proxyHandlers = {
892
896
  throw new Error('Cannot assign to a temporary client reference from a server module.');
893
897
  }
894
898
  };
895
- function createTemporaryReference(id) {
899
+ function createTemporaryReference(temporaryReferences, id) {
896
900
  var reference = Object.defineProperties(function () {
897
901
  throw new Error( // eslint-disable-next-line react-internal/safe-string-coercion
898
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.");
899
903
  }, {
900
904
  $$typeof: {
901
905
  value: TEMPORARY_REFERENCE_TAG
902
- },
903
- $$id: {
904
- value: id
905
906
  }
906
907
  });
907
- return new Proxy(reference, proxyHandlers);
908
+ var wrapper = new Proxy(reference, proxyHandlers);
909
+ registerTemporaryReference(temporaryReferences, wrapper, id);
910
+ return wrapper;
908
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.
909
919
 
920
+ var REACT_LEGACY_ELEMENT_TYPE = Symbol.for('react.element');
910
921
  var REACT_ELEMENT_TYPE = Symbol.for('react.transitional.element') ;
911
922
  var REACT_FRAGMENT_TYPE = Symbol.for('react.fragment');
912
923
  var REACT_CONTEXT_TYPE = Symbol.for('react.context');
@@ -932,6 +943,7 @@ function getIteratorFn(maybeIterable) {
932
943
 
933
944
  return null;
934
945
  }
946
+ var ASYNC_ITERATOR = Symbol.asyncIterator;
935
947
 
936
948
  // Corresponds to ReactFiberWakeable and ReactFizzWakeable modules. Generally,
937
949
  // changes to one module should be reflected in the others.
@@ -1572,10 +1584,7 @@ var stringify = JSON.stringify; // Serializable values
1572
1584
  var PENDING$1 = 0;
1573
1585
  var COMPLETED = 1;
1574
1586
  var ABORTED = 3;
1575
- var ERRORED$1 = 4; // object reference status
1576
-
1577
- var SEEN_BUT_NOT_YET_OUTLINED = -1;
1578
- var NEVER_OUTLINED = -2;
1587
+ var ERRORED$1 = 4;
1579
1588
 
1580
1589
  function defaultErrorHandler(error) {
1581
1590
  console['error'](error); // Don't transform to our wrapper
@@ -1587,7 +1596,7 @@ function defaultPostponeHandler(reason) {// Noop
1587
1596
  var OPEN = 0;
1588
1597
  var CLOSING = 1;
1589
1598
  var CLOSED = 2;
1590
- function createRequest(model, bundlerConfig, onError, identifierPrefix, onPostpone, environmentName) {
1599
+ function createRequest(model, bundlerConfig, onError, identifierPrefix, onPostpone, environmentName, temporaryReferences) {
1591
1600
  if (ReactSharedInternals.A !== null && ReactSharedInternals.A !== DefaultAsyncDispatcher) {
1592
1601
  throw new Error('Currently React only supports one RSC renderer at a time.');
1593
1602
  }
@@ -1619,6 +1628,7 @@ function createRequest(model, bundlerConfig, onError, identifierPrefix, onPostpo
1619
1628
  writtenClientReferences: new Map(),
1620
1629
  writtenServerReferences: new Map(),
1621
1630
  writtenObjects: new WeakMap(),
1631
+ temporaryReferences: temporaryReferences,
1622
1632
  identifierPrefix: identifierPrefix || '',
1623
1633
  identifierCount: 1,
1624
1634
  taintCleanupQueue: cleanupQueue,
@@ -1726,6 +1736,192 @@ function serializeThenable(request, task, thenable) {
1726
1736
  return newTask.id;
1727
1737
  }
1728
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
+
1729
1925
  function emitHint(request, code, model) {
1730
1926
  emitHintChunk(request, code, model);
1731
1927
  enqueueFlush(request);
@@ -1797,16 +1993,43 @@ function createLazyWrapperAroundWakeable(wakeable) {
1797
1993
  }
1798
1994
 
1799
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);
1800
2023
  }
1801
2024
 
1802
- function renderFunctionComponent(request, task, key, Component, props, owner) {
2025
+ function renderFunctionComponent(request, task, key, Component, props, owner, // DEV-only
2026
+ stack) // DEV-only
2027
+ {
1803
2028
  // Reset the task's thenable state before continuing, so that if a later
1804
2029
  // component suspends we can reuse the same task object. If the same
1805
2030
  // component suspends again, the thenable state will be restored.
1806
2031
  var prevThenableState = task.thenableState;
1807
- task.thenableState = null; // The secondArg is always undefined in Server Components since refs error early.
1808
-
1809
- var secondArg = undefined;
2032
+ task.thenableState = null;
1810
2033
  var result;
1811
2034
  var componentDebugInfo;
1812
2035
 
@@ -1829,25 +2052,17 @@ function renderFunctionComponent(request, task, key, Component, props, owner) {
1829
2052
  name: componentName,
1830
2053
  env: request.environmentName,
1831
2054
  owner: owner
1832
- }; // We outline this model eagerly so that we can refer to by reference as an owner.
2055
+ };
1833
2056
  // If we had a smarter way to dedupe we might not have to do this if there ends up
1834
2057
  // being no references to this as an owner.
1835
2058
 
2059
+
1836
2060
  outlineModel(request, componentDebugInfo);
1837
2061
  emitDebugChunk(request, componentDebugID, componentDebugInfo);
1838
2062
  }
1839
2063
 
1840
2064
  prepareToUseHooksForComponent(prevThenableState, componentDebugInfo);
1841
- setCurrentOwner(componentDebugInfo);
1842
-
1843
- try {
1844
- if (supportsComponentStorage) {
1845
- // Run the component in an Async Context that tracks the current owner.
1846
- result = componentStorage.run(componentDebugInfo, Component, props, secondArg);
1847
- }
1848
- } finally {
1849
- setCurrentOwner(null);
1850
- }
2065
+ result = callComponentInDEV(Component, props, componentDebugInfo);
1851
2066
  }
1852
2067
 
1853
2068
  if (typeof result === 'object' && result !== null) {
@@ -1899,6 +2114,33 @@ function renderFunctionComponent(request, task, key, Component, props, owner) {
1899
2114
  {
1900
2115
  result._debugInfo = iterableChild._debugInfo;
1901
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
+ }
1902
2144
  }
1903
2145
  } // Track this element's key on the Server Component on the keyPath context..
1904
2146
 
@@ -1981,7 +2223,44 @@ function renderFragment(request, task, children) {
1981
2223
  return children;
1982
2224
  }
1983
2225
 
1984
- function renderClientElement(task, type, key, props, owner) // DEV-only
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
+
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
+ }
2261
+
2262
+ function renderClientElement(task, type, key, props, owner, // DEV-only
2263
+ stack) // DEV-only
1985
2264
  {
1986
2265
  // We prepend the terminal client element that actually gets serialized with
1987
2266
  // the keys of any Server Components which are not serialized.
@@ -2031,7 +2310,8 @@ function outlineTask(request, task) {
2031
2310
  return serializeLazyID(newTask.id);
2032
2311
  }
2033
2312
 
2034
- 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
2035
2315
  {
2036
2316
  if (ref !== null && ref !== undefined) {
2037
2317
  // When the ref moves to the regular props object this will implicitly
@@ -2051,7 +2331,7 @@ function renderElement(request, task, type, key, ref, props, owner) // DEV only
2051
2331
  }
2052
2332
 
2053
2333
  if (typeof type === 'function') {
2054
- if (isClientReference(type) || isTemporaryReference(type)) {
2334
+ if (isClientReference(type) || isOpaqueTemporaryReference(type)) {
2055
2335
  // This is a reference to a Client Component.
2056
2336
  return renderClientElement(task, type, key, props, owner);
2057
2337
  } // This is a Server Component.
@@ -2088,9 +2368,12 @@ function renderElement(request, task, type, key, ref, props, owner) // DEV only
2088
2368
  switch (type.$$typeof) {
2089
2369
  case REACT_LAZY_TYPE:
2090
2370
  {
2091
- var payload = type._payload;
2092
- var init = type._init;
2093
- var wrappedType = init(payload);
2371
+ var wrappedType;
2372
+
2373
+ {
2374
+ wrappedType = callLazyInitInDEV(type);
2375
+ }
2376
+
2094
2377
  return renderElement(request, task, wrappedType, key, ref, props, owner);
2095
2378
  }
2096
2379
 
@@ -2129,7 +2412,7 @@ function createTask(request, model, keyPath, implicitSlot, abortSet) {
2129
2412
  // If we're about to write this into a new task we can assign it an ID early so that
2130
2413
  // any other references can refer to the value we're about to write.
2131
2414
  if (keyPath !== null || implicitSlot) ; else {
2132
- request.writtenObjects.set(model, id);
2415
+ request.writtenObjects.set(model, serializeByValueID(id));
2133
2416
  }
2134
2417
  }
2135
2418
 
@@ -2192,10 +2475,6 @@ function serializeServerReferenceID(id) {
2192
2475
  return '$F' + id.toString(16);
2193
2476
  }
2194
2477
 
2195
- function serializeTemporaryReferenceID(id) {
2196
- return '$T' + id;
2197
- }
2198
-
2199
2478
  function serializeSymbolReference(name) {
2200
2479
  return '$S' + name;
2201
2480
  }
@@ -2312,9 +2591,8 @@ function serializeServerReference(request, serverReference) {
2312
2591
  return serializeServerReferenceID(metadataId);
2313
2592
  }
2314
2593
 
2315
- function serializeTemporaryReference(request, temporaryReference) {
2316
- var id = resolveTemporaryReferenceID(temporaryReference);
2317
- return serializeTemporaryReferenceID(id);
2594
+ function serializeTemporaryReference(request, reference) {
2595
+ return '$T' + reference;
2318
2596
  }
2319
2597
 
2320
2598
  function serializeLargeTextString(request, text) {
@@ -2326,20 +2604,6 @@ function serializeLargeTextString(request, text) {
2326
2604
 
2327
2605
  function serializeMap(request, map) {
2328
2606
  var entries = Array.from(map);
2329
-
2330
- for (var i = 0; i < entries.length; i++) {
2331
- var key = entries[i][0];
2332
-
2333
- if (typeof key === 'object' && key !== null) {
2334
- var writtenObjects = request.writtenObjects;
2335
- var existingId = writtenObjects.get(key);
2336
-
2337
- if (existingId === undefined) {
2338
- writtenObjects.set(key, SEEN_BUT_NOT_YET_OUTLINED);
2339
- }
2340
- }
2341
- }
2342
-
2343
2607
  var id = outlineModel(request, entries);
2344
2608
  return '$Q' + id.toString(16);
2345
2609
  }
@@ -2352,20 +2616,6 @@ function serializeFormData(request, formData) {
2352
2616
 
2353
2617
  function serializeSet(request, set) {
2354
2618
  var entries = Array.from(set);
2355
-
2356
- for (var i = 0; i < entries.length; i++) {
2357
- var key = entries[i];
2358
-
2359
- if (typeof key === 'object' && key !== null) {
2360
- var writtenObjects = request.writtenObjects;
2361
- var existingId = writtenObjects.get(key);
2362
-
2363
- if (existingId === undefined) {
2364
- writtenObjects.set(key, SEEN_BUT_NOT_YET_OUTLINED);
2365
- }
2366
- }
2367
- }
2368
-
2369
2619
  var id = outlineModel(request, entries);
2370
2620
  return '$W' + id.toString(16);
2371
2621
  }
@@ -2375,6 +2625,58 @@ function serializeIterator(request, iterator) {
2375
2625
  return '$i' + id.toString(16);
2376
2626
  }
2377
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
+
2378
2680
  function escapeStringValue(value) {
2379
2681
  if (value[0] === '$') {
2380
2682
  // We need to escape $ prefixed strings since we use those to encode
@@ -2467,37 +2769,34 @@ function renderModelDestructive(request, task, parent, parentPropertyName, value
2467
2769
  {
2468
2770
  var _writtenObjects = request.writtenObjects;
2469
2771
 
2470
- var _existingId = _writtenObjects.get(value);
2471
-
2472
- if (_existingId !== undefined) {
2473
- if (task.keyPath !== null || task.implicitSlot) ; else if (modelRoot === value) {
2474
- // This is the ID we're currently emitting so we need to write it
2475
- // once but if we discover it again, we refer to it by id.
2476
- modelRoot = null;
2477
- } else if (_existingId === SEEN_BUT_NOT_YET_OUTLINED) {
2478
- // TODO: If we throw here we can treat this as suspending which causes an outline
2479
- // but that is able to reuse the same task if we're already in one but then that
2480
- // will be a lazy future value rather than guaranteed to exist but maybe that's good.
2481
- var newId = outlineModel(request, value);
2482
- return serializeByValueID(newId);
2483
- } else {
2484
- // We've already emitted this as an outlined object, so we can refer to that by its
2485
- // existing ID. TODO: We should use a lazy reference since, unlike plain objects,
2486
- // elements might suspend so it might not have emitted yet even if we have the ID for
2487
- // it. However, this creates an extra wrapper when it's not needed. We should really
2488
- // detect whether this already was emitted and synchronously available. In that
2489
- // case we can refer to it synchronously and only make it lazy otherwise.
2490
- // We currently don't have a data structure that lets us see that though.
2491
- return serializeByValueID(_existingId);
2492
- }
2493
- } else {
2494
- // This is the first time we've seen this object. We may never see it again
2495
- // so we'll inline it. Mark it as seen. If we see it again, we'll outline.
2496
- _writtenObjects.set(value, SEEN_BUT_NOT_YET_OUTLINED); // The element's props are marked as "never outlined" so that they are inlined into
2497
- // the same row as the element itself.
2498
-
2772
+ if (task.keyPath !== null || task.implicitSlot) ; else {
2773
+ var _existingReference = _writtenObjects.get(value);
2499
2774
 
2500
- _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
+ }
2501
2800
  }
2502
2801
 
2503
2802
  var element = value;
@@ -2540,9 +2839,11 @@ function renderModelDestructive(request, task, parent, parentPropertyName, value
2540
2839
  // from suspending the lazy before.
2541
2840
  task.thenableState = null;
2542
2841
  var lazy = value;
2543
- var payload = lazy._payload;
2544
- var init = lazy._init;
2545
- var resolvedModel = init(payload);
2842
+ var resolvedModel;
2843
+
2844
+ {
2845
+ resolvedModel = callLazyInitInDEV(lazy);
2846
+ }
2546
2847
 
2547
2848
  {
2548
2849
  var _debugInfo = lazy._debugInfo;
@@ -2564,17 +2865,30 @@ function renderModelDestructive(request, task, parent, parentPropertyName, value
2564
2865
 
2565
2866
  return renderModelDestructive(request, task, emptyRoot, '', resolvedModel);
2566
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
+ }
2567
2873
  }
2568
2874
 
2569
2875
  if (isClientReference(value)) {
2570
2876
  return serializeClientReference(request, parent, parentPropertyName, value);
2571
2877
  }
2572
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
+
2573
2887
  var writtenObjects = request.writtenObjects;
2574
- var existingId = writtenObjects.get(value); // $FlowFixMe[method-unbinding]
2888
+ var existingReference = writtenObjects.get(value); // $FlowFixMe[method-unbinding]
2575
2889
 
2576
2890
  if (typeof value.then === 'function') {
2577
- if (existingId !== undefined) {
2891
+ if (existingReference !== undefined) {
2578
2892
  if (task.keyPath !== null || task.implicitSlot) {
2579
2893
  // If we're in some kind of context we can't reuse the result of this render or
2580
2894
  // previous renders of this element. We only reuse Promises if they're not wrapped
@@ -2588,35 +2902,58 @@ function renderModelDestructive(request, task, parent, parentPropertyName, value
2588
2902
  modelRoot = null;
2589
2903
  } else {
2590
2904
  // We've seen this promise before, so we can just refer to the same result.
2591
- return serializePromiseID(existingId);
2905
+ return existingReference;
2592
2906
  }
2593
2907
  } // We assume that any object with a .then property is a "Thenable" type,
2594
2908
  // or a Promise type. Either of which can be represented by a Promise.
2595
2909
 
2596
2910
 
2597
2911
  var promiseId = serializeThenable(request, task, value);
2598
- writtenObjects.set(value, promiseId);
2599
- return serializePromiseID(promiseId);
2912
+ var promiseReference = serializePromiseID(promiseId);
2913
+ writtenObjects.set(value, promiseReference);
2914
+ return promiseReference;
2600
2915
  }
2601
2916
 
2602
- if (existingId !== undefined) {
2917
+ if (existingReference !== undefined) {
2603
2918
  if (modelRoot === value) {
2604
2919
  // This is the ID we're currently emitting so we need to write it
2605
2920
  // once but if we discover it again, we refer to it by id.
2606
2921
  modelRoot = null;
2607
- } else if (existingId === SEEN_BUT_NOT_YET_OUTLINED) {
2608
- var _newId = outlineModel(request, value);
2609
-
2610
- return serializeByValueID(_newId);
2611
- } else if (existingId !== NEVER_OUTLINED) {
2922
+ } else {
2612
2923
  // We've already emitted this as an outlined object, so we can
2613
2924
  // just refer to that by its existing ID.
2614
- 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);
2615
2956
  }
2616
- } else {
2617
- // This is the first time we've seen this object. We may never see it again
2618
- // so we'll inline it. Mark it as seen. If we see it again, we'll outline.
2619
- writtenObjects.set(value, SEEN_BUT_NOT_YET_OUTLINED);
2620
2957
  }
2621
2958
 
2622
2959
  if (isArray(value)) {
@@ -2636,33 +2973,118 @@ function renderModelDestructive(request, task, parent, parentPropertyName, value
2636
2973
  return serializeFormData(request, value);
2637
2974
  }
2638
2975
 
2639
- var iteratorFn = getIteratorFn(value);
2976
+ {
2977
+ if (value instanceof ArrayBuffer) {
2978
+ return serializeTypedArray(request, 'A', new Uint8Array(value));
2979
+ }
2640
2980
 
2641
- if (iteratorFn) {
2642
- // TODO: Should we serialize the return value as well like we do for AsyncIterables?
2643
- var iterator = iteratorFn.call(value);
2981
+ if (value instanceof Int8Array) {
2982
+ // char
2983
+ return serializeTypedArray(request, 'O', value);
2984
+ }
2644
2985
 
2645
- if (iterator === value) {
2646
- // Iterator, not Iterable
2647
- return serializeIterator(request, iterator);
2986
+ if (value instanceof Uint8Array) {
2987
+ // unsigned char
2988
+ return serializeTypedArray(request, 'o', value);
2648
2989
  }
2649
2990
 
2650
- return renderFragment(request, task, Array.from(iterator));
2651
- }
2991
+ if (value instanceof Uint8ClampedArray) {
2992
+ // unsigned clamped char
2993
+ return serializeTypedArray(request, 'U', value);
2994
+ }
2652
2995
 
2996
+ if (value instanceof Int16Array) {
2997
+ // sort
2998
+ return serializeTypedArray(request, 'S', value);
2999
+ }
2653
3000
 
2654
- var proto = getPrototypeOf(value);
3001
+ if (value instanceof Uint16Array) {
3002
+ // unsigned short
3003
+ return serializeTypedArray(request, 's', value);
3004
+ }
2655
3005
 
2656
- if (proto !== ObjectPrototype && (proto === null || getPrototypeOf(proto) !== null)) {
2657
- throw new Error('Only plain objects, and a few built-ins, can be passed to Client Components ' + 'from Server Components. Classes or null prototypes are not supported.');
2658
- }
3006
+ if (value instanceof Int32Array) {
3007
+ // long
3008
+ return serializeTypedArray(request, 'L', value);
3009
+ }
2659
3010
 
2660
- {
2661
- if (objectName(value) !== 'Object') {
2662
- error('Only plain objects can be passed to Client Components from Server Components. ' + '%s objects are not supported.%s', objectName(value), describeObjectForErrorMessage(parent, parentPropertyName));
2663
- } else if (!isSimpleObject(value)) {
2664
- error('Only plain objects can be passed to Client Components from Server Components. ' + 'Classes or other objects with methods are not supported.%s', describeObjectForErrorMessage(parent, parentPropertyName));
2665
- } else if (Object.getOwnPropertySymbols) {
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
3055
+ return serializeIterator(request, iterator);
3056
+ }
3057
+
3058
+ return renderFragment(request, task, Array.from(iterator));
3059
+ }
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
+
3075
+
3076
+ var proto = getPrototypeOf(value);
3077
+
3078
+ if (proto !== ObjectPrototype && (proto === null || getPrototypeOf(proto) !== null)) {
3079
+ throw new Error('Only plain objects, and a few built-ins, can be passed to Client Components ' + 'from Server Components. Classes or null prototypes are not supported.');
3080
+ }
3081
+
3082
+ {
3083
+ if (objectName(value) !== 'Object') {
3084
+ error('Only plain objects can be passed to Client Components from Server Components. ' + '%s objects are not supported.%s', objectName(value), describeObjectForErrorMessage(parent, parentPropertyName));
3085
+ } else if (!isSimpleObject(value)) {
3086
+ error('Only plain objects can be passed to Client Components from Server Components. ' + 'Classes or other objects with methods are not supported.%s', describeObjectForErrorMessage(parent, parentPropertyName));
3087
+ } else if (Object.getOwnPropertySymbols) {
2666
3088
  var symbols = Object.getOwnPropertySymbols(value);
2667
3089
 
2668
3090
  if (symbols.length > 0) {
@@ -2719,11 +3141,17 @@ function renderModelDestructive(request, task, parent, parentPropertyName, value
2719
3141
  return serializeServerReference(request, value);
2720
3142
  }
2721
3143
 
2722
- if (isTemporaryReference(value)) {
2723
- 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
+ }
2724
3150
  }
2725
3151
 
2726
- 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)) {
2727
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.');
2728
3156
  } else if ((jsxChildrenParents.has(parent) || jsxPropsParents.has(parent) && parentPropertyName === 'children')) {
2729
3157
  var componentName = value.displayName || value.name || 'Component';
@@ -2735,11 +3163,10 @@ function renderModelDestructive(request, task, parent, parentPropertyName, value
2735
3163
 
2736
3164
  if (typeof value === 'symbol') {
2737
3165
  var writtenSymbols = request.writtenSymbols;
3166
+ var existingId = writtenSymbols.get(value);
2738
3167
 
2739
- var _existingId2 = writtenSymbols.get(value);
2740
-
2741
- if (_existingId2 !== undefined) {
2742
- return serializeByValueID(_existingId2);
3168
+ if (existingId !== undefined) {
3169
+ return serializeByValueID(existingId);
2743
3170
  } // $FlowFixMe[incompatible-type] `description` might be undefined
2744
3171
 
2745
3172
 
@@ -2923,6 +3350,18 @@ function emitDebugChunk(request, id, debugInfo) {
2923
3350
  request.completedRegularChunks.push(processedChunk);
2924
3351
  }
2925
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
+
2926
3365
  function emitTextChunk(request, id, text) {
2927
3366
  request.pendingChunks++; // Extra chunk for the header.
2928
3367
 
@@ -2958,6 +3397,14 @@ function renderConsoleValue(request, counter, parent, parentPropertyName, value)
2958
3397
  return serializeClientReference(request, parent, parentPropertyName, value);
2959
3398
  }
2960
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
+
2961
3408
  if (counter.objectCount > 20) {
2962
3409
  // We've reached our max number of objects to serialize across the wire so we serialize this
2963
3410
  // object but no properties inside of it, as a place holder.
@@ -2966,12 +3413,12 @@ function renderConsoleValue(request, counter, parent, parentPropertyName, value)
2966
3413
 
2967
3414
  counter.objectCount++;
2968
3415
  var writtenObjects = request.writtenObjects;
2969
- var existingId = writtenObjects.get(value); // $FlowFixMe[method-unbinding]
3416
+ var existingReference = writtenObjects.get(value); // $FlowFixMe[method-unbinding]
2970
3417
 
2971
3418
  if (typeof value.then === 'function') {
2972
- if (existingId !== undefined) {
3419
+ if (existingReference !== undefined) {
2973
3420
  // We've seen this promise before, so we can just refer to the same result.
2974
- return serializePromiseID(existingId);
3421
+ return existingReference;
2975
3422
  }
2976
3423
 
2977
3424
  var thenable = value;
@@ -3003,10 +3450,10 @@ function renderConsoleValue(request, counter, parent, parentPropertyName, value)
3003
3450
  return serializeInfinitePromise();
3004
3451
  }
3005
3452
 
3006
- if (existingId !== undefined && existingId >= 0) {
3453
+ if (existingReference !== undefined) {
3007
3454
  // We've already emitted this as a real object, so we can
3008
- // just refer to that by its existing ID.
3009
- return serializeByValueID(existingId);
3455
+ // just refer to that by its existing reference.
3456
+ return existingReference;
3010
3457
  }
3011
3458
 
3012
3459
  if (isArray(value)) {
@@ -3026,6 +3473,77 @@ function renderConsoleValue(request, counter, parent, parentPropertyName, value)
3026
3473
  return serializeFormData(request, value);
3027
3474
  }
3028
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
+
3029
3547
  var iteratorFn = getIteratorFn(value);
3030
3548
 
3031
3549
  if (iteratorFn) {
@@ -3071,8 +3589,12 @@ function renderConsoleValue(request, counter, parent, parentPropertyName, value)
3071
3589
  return serializeClientReference(request, parent, parentPropertyName, value);
3072
3590
  }
3073
3591
 
3074
- if (isTemporaryReference(value)) {
3075
- 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
+ }
3076
3598
  } // Serialize the body of the function as an eval so it can be printed.
3077
3599
  // $FlowFixMe[method-unbinding]
3078
3600
 
@@ -3082,11 +3604,10 @@ function renderConsoleValue(request, counter, parent, parentPropertyName, value)
3082
3604
 
3083
3605
  if (typeof value === 'symbol') {
3084
3606
  var writtenSymbols = request.writtenSymbols;
3607
+ var existingId = writtenSymbols.get(value);
3085
3608
 
3086
- var _existingId3 = writtenSymbols.get(value);
3087
-
3088
- if (_existingId3 !== undefined) {
3089
- return serializeByValueID(_existingId3);
3609
+ if (existingId !== undefined) {
3610
+ return serializeByValueID(existingId);
3090
3611
  } // $FlowFixMe[incompatible-type] `description` might be undefined
3091
3612
 
3092
3613
 
@@ -3141,6 +3662,85 @@ function emitChunk(request, task, value) {
3141
3662
  emitTextChunk(request, id, value);
3142
3663
  return;
3143
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.
3144
3744
  // $FlowFixMe[incompatible-type] stringify can return null for undefined but we never do
3145
3745
 
3146
3746
 
@@ -3186,8 +3786,11 @@ function retryTask(request, task) {
3186
3786
  task.implicitSlot = false;
3187
3787
 
3188
3788
  if (typeof resolvedModel === 'object' && resolvedModel !== null) {
3189
- // 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.
3190
3792
  // This is simulating what the JSON loop would do if this was part of it.
3793
+
3191
3794
  emitChunk(request, task, resolvedModel);
3192
3795
  } else {
3193
3796
  // If the value is a string, it means it's a terminal value and we already escaped it
@@ -3229,6 +3832,26 @@ function retryTask(request, task) {
3229
3832
  }
3230
3833
  }
3231
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
+
3232
3855
  function performWork(request) {
3233
3856
  var prevDispatcher = ReactSharedInternals.H;
3234
3857
  ReactSharedInternals.H = HooksDispatcher;
@@ -3528,8 +4151,12 @@ function requireModule(metadata) {
3528
4151
  return moduleExports[metadata.name];
3529
4152
  }
3530
4153
 
4154
+ // $FlowFixMe[method-unbinding]
4155
+ var hasOwnProperty = Object.prototype.hasOwnProperty;
4156
+
3531
4157
  var PENDING = 'pending';
3532
4158
  var BLOCKED = 'blocked';
4159
+ var CYCLIC = 'cyclic';
3533
4160
  var RESOLVED_MODEL = 'resolved_model';
3534
4161
  var INITIALIZED = 'fulfilled';
3535
4162
  var ERRORED = 'rejected'; // $FlowFixMe[missing-this-annot]
@@ -3562,6 +4189,7 @@ Chunk.prototype.then = function (resolve, reject) {
3562
4189
 
3563
4190
  case PENDING:
3564
4191
  case BLOCKED:
4192
+ case CYCLIC:
3565
4193
  if (resolve) {
3566
4194
  if (chunk.value === null) {
3567
4195
  chunk.value = [];
@@ -3611,6 +4239,7 @@ function wakeChunkIfInitialized(chunk, resolveListeners, rejectListeners) {
3611
4239
 
3612
4240
  case PENDING:
3613
4241
  case BLOCKED:
4242
+ case CYCLIC:
3614
4243
  chunk.value = resolveListeners;
3615
4244
  chunk.reason = rejectListeners;
3616
4245
  break;
@@ -3626,6 +4255,14 @@ function wakeChunkIfInitialized(chunk, resolveListeners, rejectListeners) {
3626
4255
 
3627
4256
  function triggerErrorOnChunk(chunk, error) {
3628
4257
  if (chunk.status !== PENDING && chunk.status !== BLOCKED) {
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
+ }
3629
4266
 
3630
4267
  return;
3631
4268
  }
@@ -3640,13 +4277,25 @@ function triggerErrorOnChunk(chunk, error) {
3640
4277
  }
3641
4278
  }
3642
4279
 
3643
- function createResolvedModelChunk(response, value) {
4280
+ function createResolvedModelChunk(response, value, id) {
3644
4281
  // $FlowFixMe[invalid-constructor] Flow doesn't support functions as constructors
3645
- return new Chunk(RESOLVED_MODEL, value, null, response);
4282
+ return new Chunk(RESOLVED_MODEL, value, id, response);
3646
4283
  }
3647
4284
 
3648
- function resolveModelChunk(chunk, value) {
4285
+ function resolveModelChunk(chunk, value, id) {
3649
4286
  if (chunk.status !== PENDING) {
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
+ }
3650
4299
 
3651
4300
  return;
3652
4301
  }
@@ -3656,6 +4305,7 @@ function resolveModelChunk(chunk, value) {
3656
4305
  var resolvedChunk = chunk;
3657
4306
  resolvedChunk.status = RESOLVED_MODEL;
3658
4307
  resolvedChunk.value = value;
4308
+ resolvedChunk.reason = id;
3659
4309
 
3660
4310
  if (resolveListeners !== null) {
3661
4311
  // This is unfortunate that we're reading this eagerly if
@@ -3667,6 +4317,26 @@ function resolveModelChunk(chunk, value) {
3667
4317
  }
3668
4318
  }
3669
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
+
3670
4340
  function bindArgs$1(fn, args) {
3671
4341
  return fn.bind.apply(fn, [null].concat(args));
3672
4342
  }
@@ -3695,11 +4365,51 @@ function loadServerReference$1(response, id, bound, parentChunk, parentObject, k
3695
4365
  }
3696
4366
  }
3697
4367
 
3698
- promise.then(createModelResolver(parentChunk, parentObject, key, false, response, createModel), 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.
3699
4369
 
3700
4370
  return null;
3701
4371
  }
3702
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
+
3703
4413
  var initializingChunk = null;
3704
4414
  var initializingChunkBlockedModel = null;
3705
4415
 
@@ -3708,9 +4418,21 @@ function initializeModelChunk(chunk) {
3708
4418
  var prevBlocked = initializingChunkBlockedModel;
3709
4419
  initializingChunk = chunk;
3710
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;
3711
4430
 
3712
4431
  try {
3713
- 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);
3714
4436
 
3715
4437
  if (initializingChunkBlockedModel !== null && initializingChunkBlockedModel.deps > 0) {
3716
4438
  initializingChunkBlockedModel.value = value; // We discovered new dependencies on modules that are not yet resolved.
@@ -3721,9 +4443,14 @@ function initializeModelChunk(chunk) {
3721
4443
  blockedChunk.value = null;
3722
4444
  blockedChunk.reason = null;
3723
4445
  } else {
4446
+ var resolveListeners = cyclicChunk.value;
3724
4447
  var initializedChunk = chunk;
3725
4448
  initializedChunk.status = INITIALIZED;
3726
4449
  initializedChunk.value = value;
4450
+
4451
+ if (resolveListeners !== null) {
4452
+ wakeChunk(resolveListeners, value);
4453
+ }
3727
4454
  }
3728
4455
  } catch (error) {
3729
4456
  var erroredChunk = chunk;
@@ -3760,7 +4487,7 @@ function getChunk(response, id) {
3760
4487
 
3761
4488
  if (backingEntry != null) {
3762
4489
  // We assume that this is a string entry for now.
3763
- chunk = createResolvedModelChunk(response, backingEntry);
4490
+ chunk = createResolvedModelChunk(response, backingEntry, id);
3764
4491
  } else {
3765
4492
  // We're still waiting on this entry to stream in.
3766
4493
  chunk = createPendingChunk(response);
@@ -3772,7 +4499,7 @@ function getChunk(response, id) {
3772
4499
  return chunk;
3773
4500
  }
3774
4501
 
3775
- function createModelResolver(chunk, parentObject, key, cyclic, response, map) {
4502
+ function createModelResolver(chunk, parentObject, key, cyclic, response, map, path) {
3776
4503
  var blocked;
3777
4504
 
3778
4505
  if (initializingChunkBlockedModel) {
@@ -3789,6 +4516,10 @@ function createModelResolver(chunk, parentObject, key, cyclic, response, map) {
3789
4516
  }
3790
4517
 
3791
4518
  return function (value) {
4519
+ for (var i = 1; i < path.length; i++) {
4520
+ value = value[path[i]];
4521
+ }
4522
+
3792
4523
  parentObject[key] = map(response, value); // If this is the root object for a model reference, where `blocked.value`
3793
4524
  // is a stale `null`, the resolved value can be used directly.
3794
4525
 
@@ -3821,7 +4552,9 @@ function createModelReject(chunk) {
3821
4552
  };
3822
4553
  }
3823
4554
 
3824
- function getOutlinedModel(response, id, parentObject, key, map) {
4555
+ function getOutlinedModel(response, reference, parentObject, key, map) {
4556
+ var path = reference.split(':');
4557
+ var id = parseInt(path[0], 16);
3825
4558
  var chunk = getChunk(response, id);
3826
4559
 
3827
4560
  switch (chunk.status) {
@@ -3833,12 +4566,19 @@ function getOutlinedModel(response, id, parentObject, key, map) {
3833
4566
 
3834
4567
  switch (chunk.status) {
3835
4568
  case INITIALIZED:
3836
- return map(response, chunk.value);
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);
3837
4576
 
3838
4577
  case PENDING:
3839
4578
  case BLOCKED:
4579
+ case CYCLIC:
3840
4580
  var parentChunk = initializingChunk;
3841
- chunk.then(createModelResolver(parentChunk, parentObject, key, false, response, map), createModelReject(parentChunk));
4581
+ chunk.then(createModelResolver(parentChunk, parentObject, key, chunk.status === CYCLIC, response, map, path), createModelReject(parentChunk));
3842
4582
  return null;
3843
4583
 
3844
4584
  default:
@@ -3863,7 +4603,220 @@ function createModel(response, model) {
3863
4603
  return model;
3864
4604
  }
3865
4605
 
3866
- function parseModelString(response, obj, key, value) {
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
+ }
4642
+ }
4643
+ }
4644
+
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;
4743
+ }
4744
+
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) {
3867
4820
  if (value[0] === '$') {
3868
4821
  switch (value[1]) {
3869
4822
  case '$':
@@ -3875,42 +4828,45 @@ function parseModelString(response, obj, key, value) {
3875
4828
  case '@':
3876
4829
  {
3877
4830
  // Promise
3878
- var _id = parseInt(value.slice(2), 16);
3879
-
3880
- var chunk = getChunk(response, _id);
4831
+ var id = parseInt(value.slice(2), 16);
4832
+ var chunk = getChunk(response, id);
3881
4833
  return chunk;
3882
4834
  }
3883
4835
 
3884
4836
  case 'F':
3885
4837
  {
3886
4838
  // Server Reference
3887
- 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.
3888
4840
 
3889
4841
 
3890
- var metaData = getOutlinedModel(response, _id2, obj, key, createModel);
4842
+ var metaData = getOutlinedModel(response, _ref2, obj, key, createModel);
3891
4843
  return loadServerReference$1(response, metaData.id, metaData.bound, initializingChunk, obj, key);
3892
4844
  }
3893
4845
 
3894
4846
  case 'T':
3895
4847
  {
3896
4848
  // Temporary Reference
3897
- 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);
3898
4854
  }
3899
4855
 
3900
4856
  case 'Q':
3901
4857
  {
3902
4858
  // Map
3903
- var _id3 = parseInt(value.slice(2), 16);
4859
+ var _ref3 = value.slice(2);
3904
4860
 
3905
- return getOutlinedModel(response, _id3, obj, key, createMap);
4861
+ return getOutlinedModel(response, _ref3, obj, key, createMap);
3906
4862
  }
3907
4863
 
3908
4864
  case 'W':
3909
4865
  {
3910
4866
  // Set
3911
- var _id4 = parseInt(value.slice(2), 16);
4867
+ var _ref4 = value.slice(2);
3912
4868
 
3913
- return getOutlinedModel(response, _id4, obj, key, createSet);
4869
+ return getOutlinedModel(response, _ref4, obj, key, createSet);
3914
4870
  }
3915
4871
 
3916
4872
  case 'K':
@@ -3935,9 +4891,9 @@ function parseModelString(response, obj, key, value) {
3935
4891
  case 'i':
3936
4892
  {
3937
4893
  // Iterator
3938
- var _id5 = parseInt(value.slice(2), 16);
4894
+ var _ref5 = value.slice(2);
3939
4895
 
3940
- return getOutlinedModel(response, _id5, obj, key, extractIterator);
4896
+ return getOutlinedModel(response, _ref5, obj, key, extractIterator);
3941
4897
  }
3942
4898
 
3943
4899
  case 'I':
@@ -3982,30 +4938,104 @@ function parseModelString(response, obj, key, value) {
3982
4938
  }
3983
4939
  }
3984
4940
 
4941
+ {
4942
+ switch (value[1]) {
4943
+ case 'A':
4944
+ return parseTypedArray(response, value, ArrayBuffer, 1, obj, key);
4945
+
4946
+ case 'O':
4947
+ return parseTypedArray(response, value, Int8Array, 1, obj, key);
4948
+
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);
4957
+
4958
+ case 's':
4959
+ return parseTypedArray(response, value, Uint16Array, 2, obj, key);
4960
+
4961
+ case 'L':
4962
+ return parseTypedArray(response, value, Int32Array, 4, obj, key);
4963
+
4964
+ case 'l':
4965
+ return parseTypedArray(response, value, Uint32Array, 4, obj, key);
4966
+
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
+ }
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.
3985
5021
 
3986
- var id = parseInt(value.slice(1), 16);
3987
- return getOutlinedModel(response, id, obj, key, createModel);
5022
+
5023
+ var ref = value.slice(1);
5024
+ return getOutlinedModel(response, ref, obj, key, createModel);
3988
5025
  }
3989
5026
 
3990
5027
  return value;
3991
5028
  }
3992
5029
 
3993
- function createResponse(bundlerConfig, formFieldPrefix) {
3994
- 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();
3995
5032
  var chunks = new Map();
3996
5033
  var response = {
3997
5034
  _bundlerConfig: bundlerConfig,
3998
5035
  _prefix: formFieldPrefix,
3999
5036
  _formData: backingFormData,
4000
5037
  _chunks: chunks,
4001
- _fromJSON: function (key, value) {
4002
- if (typeof value === 'string') {
4003
- // We can't use .bind here because we need the "this" value.
4004
- return parseModelString(response, this, key, value);
4005
- }
4006
-
4007
- return value;
4008
- }
5038
+ _temporaryReferences: temporaryReferences
4009
5039
  };
4010
5040
  return response;
4011
5041
  }
@@ -4022,7 +5052,7 @@ function resolveField(response, key, value) {
4022
5052
 
4023
5053
  if (chunk) {
4024
5054
  // We were waiting on this key so now we can resolve it.
4025
- resolveModelChunk(chunk, value);
5055
+ resolveModelChunk(chunk, value, id);
4026
5056
  }
4027
5057
  }
4028
5058
  }
@@ -4083,7 +5113,7 @@ function loadServerReference(bundlerConfig, id, bound) {
4083
5113
 
4084
5114
  function decodeBoundActionMetaData(body, serverManifest, formFieldPrefix) {
4085
5115
  // The data for this reference is encoded in multiple fields under this prefix.
4086
- var actionResponse = createResponse(serverManifest, formFieldPrefix, body);
5116
+ var actionResponse = createResponse(serverManifest, formFieldPrefix, undefined, body);
4087
5117
  close(actionResponse);
4088
5118
  var refPromise = getRoot(actionResponse); // Force it to initialize
4089
5119
  // $FlowFixMe
@@ -4192,7 +5222,7 @@ function createCancelHandler(request, reason) {
4192
5222
  }
4193
5223
 
4194
5224
  function renderToPipeableStream(model, webpackMap, options) {
4195
- 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);
4196
5226
  var hasStartedFlowing = false;
4197
5227
  startWork(request);
4198
5228
  return {
@@ -4266,20 +5296,21 @@ function decodeReplyFromBusboy(busboyStream, webpackMap) {
4266
5296
  return getRoot(response);
4267
5297
  }
4268
5298
 
4269
- function decodeReply(body, webpackMap) {
5299
+ function decodeReply(body, webpackMap, options) {
4270
5300
  if (typeof body === 'string') {
4271
5301
  var form = new FormData();
4272
5302
  form.append('0', body);
4273
5303
  body = form;
4274
5304
  }
4275
5305
 
4276
- var response = createResponse(webpackMap, '', body);
5306
+ var response = createResponse(webpackMap, '', options ? options.temporaryReferences : undefined, body);
4277
5307
  var root = getRoot(response);
4278
5308
  close(response);
4279
5309
  return root;
4280
5310
  }
4281
5311
 
4282
5312
  exports.createClientModuleProxy = createClientModuleProxy;
5313
+ exports.createTemporaryReferenceSet = createTemporaryReferenceSet;
4283
5314
  exports.decodeAction = decodeAction;
4284
5315
  exports.decodeFormState = decodeFormState;
4285
5316
  exports.decodeReply = decodeReply;