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.
- package/cjs/react-server-dom-webpack-client.browser.development.js +933 -63
- package/cjs/react-server-dom-webpack-client.browser.production.js +715 -217
- package/cjs/react-server-dom-webpack-client.edge.development.js +933 -63
- package/cjs/react-server-dom-webpack-client.edge.production.js +715 -217
- package/cjs/react-server-dom-webpack-client.node.development.js +932 -62
- package/cjs/react-server-dom-webpack-client.node.production.js +700 -207
- package/cjs/react-server-dom-webpack-client.node.unbundled.development.js +932 -62
- package/cjs/react-server-dom-webpack-client.node.unbundled.production.js +700 -207
- package/cjs/react-server-dom-webpack-server.browser.development.js +1279 -199
- package/cjs/react-server-dom-webpack-server.browser.production.js +808 -162
- package/cjs/react-server-dom-webpack-server.edge.development.js +1280 -200
- package/cjs/react-server-dom-webpack-server.edge.production.js +808 -162
- package/cjs/react-server-dom-webpack-server.node.development.js +1235 -204
- package/cjs/react-server-dom-webpack-server.node.production.js +803 -183
- package/cjs/react-server-dom-webpack-server.node.unbundled.development.js +1235 -204
- package/cjs/react-server-dom-webpack-server.node.unbundled.production.js +803 -183
- package/package.json +3 -3
@@ -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
|
847
|
+
function createTemporaryReferenceSet() {
|
848
|
+
return new WeakMap();
|
849
|
+
}
|
850
|
+
function isOpaqueTemporaryReference(reference) {
|
841
851
|
return reference.$$typeof === TEMPORARY_REFERENCE_TAG;
|
842
852
|
}
|
843
|
-
function
|
844
|
-
return temporaryReference
|
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
|
-
|
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;
|
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;
|
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
|
-
};
|
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
|
-
|
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
|
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
|
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) ||
|
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
|
2092
|
-
|
2093
|
-
|
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,
|
2316
|
-
|
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
|
-
|
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
|
-
|
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
|
2544
|
-
|
2545
|
-
|
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
|
2888
|
+
var existingReference = writtenObjects.get(value); // $FlowFixMe[method-unbinding]
|
2575
2889
|
|
2576
2890
|
if (typeof value.then === 'function') {
|
2577
|
-
if (
|
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
|
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
|
-
|
2599
|
-
|
2912
|
+
var promiseReference = serializePromiseID(promiseId);
|
2913
|
+
writtenObjects.set(value, promiseReference);
|
2914
|
+
return promiseReference;
|
2600
2915
|
}
|
2601
2916
|
|
2602
|
-
if (
|
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
|
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
|
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
|
-
|
2976
|
+
{
|
2977
|
+
if (value instanceof ArrayBuffer) {
|
2978
|
+
return serializeTypedArray(request, 'A', new Uint8Array(value));
|
2979
|
+
}
|
2640
2980
|
|
2641
|
-
|
2642
|
-
|
2643
|
-
|
2981
|
+
if (value instanceof Int8Array) {
|
2982
|
+
// char
|
2983
|
+
return serializeTypedArray(request, 'O', value);
|
2984
|
+
}
|
2644
2985
|
|
2645
|
-
if (
|
2646
|
-
//
|
2647
|
-
return
|
2986
|
+
if (value instanceof Uint8Array) {
|
2987
|
+
// unsigned char
|
2988
|
+
return serializeTypedArray(request, 'o', value);
|
2648
2989
|
}
|
2649
2990
|
|
2650
|
-
|
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
|
-
|
3001
|
+
if (value instanceof Uint16Array) {
|
3002
|
+
// unsigned short
|
3003
|
+
return serializeTypedArray(request, 's', value);
|
3004
|
+
}
|
2655
3005
|
|
2656
|
-
|
2657
|
-
|
2658
|
-
|
3006
|
+
if (value instanceof Int32Array) {
|
3007
|
+
// long
|
3008
|
+
return serializeTypedArray(request, 'L', value);
|
3009
|
+
}
|
2659
3010
|
|
2660
|
-
|
2661
|
-
|
2662
|
-
|
2663
|
-
}
|
2664
|
-
|
2665
|
-
|
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 (
|
2723
|
-
|
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 (
|
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
|
-
|
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
|
3416
|
+
var existingReference = writtenObjects.get(value); // $FlowFixMe[method-unbinding]
|
2970
3417
|
|
2971
3418
|
if (typeof value.then === 'function') {
|
2972
|
-
if (
|
3419
|
+
if (existingReference !== undefined) {
|
2973
3420
|
// We've seen this promise before, so we can just refer to the same result.
|
2974
|
-
return
|
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 (
|
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
|
3009
|
-
return
|
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 (
|
3075
|
-
|
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
|
-
|
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
|
-
//
|
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,
|
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
|
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,
|
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
|
-
|
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,
|
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
|
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
|
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
|
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,
|
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
|
-
|
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
|
4859
|
+
var _ref3 = value.slice(2);
|
3904
4860
|
|
3905
|
-
return getOutlinedModel(response,
|
4861
|
+
return getOutlinedModel(response, _ref3, obj, key, createMap);
|
3906
4862
|
}
|
3907
4863
|
|
3908
4864
|
case 'W':
|
3909
4865
|
{
|
3910
4866
|
// Set
|
3911
|
-
var
|
4867
|
+
var _ref4 = value.slice(2);
|
3912
4868
|
|
3913
|
-
return getOutlinedModel(response,
|
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
|
4894
|
+
var _ref5 = value.slice(2);
|
3939
4895
|
|
3940
|
-
return getOutlinedModel(response,
|
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
|
-
|
3987
|
-
|
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 >
|
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
|
-
|
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;
|