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
@@ -151,9 +151,22 @@ var textEncoder = new TextEncoder();
|
|
151
151
|
function stringToChunk(content) {
|
152
152
|
return textEncoder.encode(content);
|
153
153
|
}
|
154
|
+
function typedArrayToBinaryChunk(content) {
|
155
|
+
// Convert any non-Uint8Array array to Uint8Array. We could avoid this for Uint8Arrays.
|
156
|
+
// If we passed through this straight to enqueue we wouldn't have to convert it but since
|
157
|
+
// we need to copy the buffer in that case, we need to convert it to copy it.
|
158
|
+
// When we copy it into another array using set() it needs to be a Uint8Array.
|
159
|
+
var buffer = new Uint8Array(content.buffer, content.byteOffset, content.byteLength); // We clone large chunks so that we can transfer them when we write them.
|
160
|
+
// Others get copied into the target buffer.
|
161
|
+
|
162
|
+
return content.byteLength > VIEW_SIZE ? buffer.slice() : buffer;
|
163
|
+
}
|
154
164
|
function byteLengthOfChunk(chunk) {
|
155
165
|
return chunk.byteLength;
|
156
166
|
}
|
167
|
+
function byteLengthOfBinaryChunk(chunk) {
|
168
|
+
return chunk.byteLength;
|
169
|
+
}
|
157
170
|
function closeWithError(destination, error) {
|
158
171
|
// $FlowFixMe[method-unbinding]
|
159
172
|
if (typeof destination.error === 'function') {
|
@@ -778,11 +791,14 @@ typeof async_hooks === 'object' ? async_hooks.executionAsyncId : null;
|
|
778
791
|
|
779
792
|
var TEMPORARY_REFERENCE_TAG = Symbol.for('react.temporary.reference'); // eslint-disable-next-line no-unused-vars
|
780
793
|
|
781
|
-
function
|
794
|
+
function createTemporaryReferenceSet() {
|
795
|
+
return new WeakMap();
|
796
|
+
}
|
797
|
+
function isOpaqueTemporaryReference(reference) {
|
782
798
|
return reference.$$typeof === TEMPORARY_REFERENCE_TAG;
|
783
799
|
}
|
784
|
-
function
|
785
|
-
return temporaryReference
|
800
|
+
function resolveTemporaryReference(temporaryReferences, temporaryReference) {
|
801
|
+
return temporaryReferences.get(temporaryReference);
|
786
802
|
}
|
787
803
|
var proxyHandlers = {
|
788
804
|
get: function (target, name, receiver) {
|
@@ -793,12 +809,6 @@ var proxyHandlers = {
|
|
793
809
|
// have the Flight runtime extract the inner target instead.
|
794
810
|
return target.$$typeof;
|
795
811
|
|
796
|
-
case '$$id':
|
797
|
-
return target.$$id;
|
798
|
-
|
799
|
-
case '$$async':
|
800
|
-
return target.$$async;
|
801
|
-
|
802
812
|
case 'name':
|
803
813
|
return undefined;
|
804
814
|
|
@@ -833,21 +843,28 @@ var proxyHandlers = {
|
|
833
843
|
throw new Error('Cannot assign to a temporary client reference from a server module.');
|
834
844
|
}
|
835
845
|
};
|
836
|
-
function createTemporaryReference(id) {
|
846
|
+
function createTemporaryReference(temporaryReferences, id) {
|
837
847
|
var reference = Object.defineProperties(function () {
|
838
848
|
throw new Error( // eslint-disable-next-line react-internal/safe-string-coercion
|
839
849
|
"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.");
|
840
850
|
}, {
|
841
851
|
$$typeof: {
|
842
852
|
value: TEMPORARY_REFERENCE_TAG
|
843
|
-
},
|
844
|
-
$$id: {
|
845
|
-
value: id
|
846
853
|
}
|
847
854
|
});
|
848
|
-
|
855
|
+
var wrapper = new Proxy(reference, proxyHandlers);
|
856
|
+
registerTemporaryReference(temporaryReferences, wrapper, id);
|
857
|
+
return wrapper;
|
849
858
|
}
|
859
|
+
function registerTemporaryReference(temporaryReferences, object, id) {
|
860
|
+
temporaryReferences.set(object, id);
|
861
|
+
}
|
862
|
+
|
863
|
+
// When adding new symbols to this file,
|
864
|
+
// Please consider also adding to 'react-devtools-shared/src/backend/ReactSymbols'
|
865
|
+
// The Symbol used to tag the ReactElement-like types.
|
850
866
|
|
867
|
+
var REACT_LEGACY_ELEMENT_TYPE = Symbol.for('react.element');
|
851
868
|
var REACT_ELEMENT_TYPE = Symbol.for('react.transitional.element') ;
|
852
869
|
var REACT_FRAGMENT_TYPE = Symbol.for('react.fragment');
|
853
870
|
var REACT_CONTEXT_TYPE = Symbol.for('react.context');
|
@@ -873,6 +890,7 @@ function getIteratorFn(maybeIterable) {
|
|
873
890
|
|
874
891
|
return null;
|
875
892
|
}
|
893
|
+
var ASYNC_ITERATOR = Symbol.asyncIterator;
|
876
894
|
|
877
895
|
// Corresponds to ReactFiberWakeable and ReactFizzWakeable modules. Generally,
|
878
896
|
// changes to one module should be reflected in the others.
|
@@ -1513,10 +1531,7 @@ var stringify = JSON.stringify; // Serializable values
|
|
1513
1531
|
var PENDING$1 = 0;
|
1514
1532
|
var COMPLETED = 1;
|
1515
1533
|
var ABORTED = 3;
|
1516
|
-
var ERRORED$1 = 4;
|
1517
|
-
|
1518
|
-
var SEEN_BUT_NOT_YET_OUTLINED = -1;
|
1519
|
-
var NEVER_OUTLINED = -2;
|
1534
|
+
var ERRORED$1 = 4;
|
1520
1535
|
|
1521
1536
|
function defaultErrorHandler(error) {
|
1522
1537
|
console['error'](error); // Don't transform to our wrapper
|
@@ -1528,7 +1543,7 @@ function defaultPostponeHandler(reason) {// Noop
|
|
1528
1543
|
var OPEN = 0;
|
1529
1544
|
var CLOSING = 1;
|
1530
1545
|
var CLOSED = 2;
|
1531
|
-
function createRequest(model, bundlerConfig, onError, identifierPrefix, onPostpone, environmentName) {
|
1546
|
+
function createRequest(model, bundlerConfig, onError, identifierPrefix, onPostpone, environmentName, temporaryReferences) {
|
1532
1547
|
if (ReactSharedInternals.A !== null && ReactSharedInternals.A !== DefaultAsyncDispatcher) {
|
1533
1548
|
throw new Error('Currently React only supports one RSC renderer at a time.');
|
1534
1549
|
}
|
@@ -1560,6 +1575,7 @@ function createRequest(model, bundlerConfig, onError, identifierPrefix, onPostpo
|
|
1560
1575
|
writtenClientReferences: new Map(),
|
1561
1576
|
writtenServerReferences: new Map(),
|
1562
1577
|
writtenObjects: new WeakMap(),
|
1578
|
+
temporaryReferences: temporaryReferences,
|
1563
1579
|
identifierPrefix: identifierPrefix || '',
|
1564
1580
|
identifierCount: 1,
|
1565
1581
|
taintCleanupQueue: cleanupQueue,
|
@@ -1667,6 +1683,192 @@ function serializeThenable(request, task, thenable) {
|
|
1667
1683
|
return newTask.id;
|
1668
1684
|
}
|
1669
1685
|
|
1686
|
+
function serializeReadableStream(request, task, stream) {
|
1687
|
+
// Detect if this is a BYOB stream. BYOB streams should be able to be read as bytes on the
|
1688
|
+
// receiving side. It also implies that different chunks can be split up or merged as opposed
|
1689
|
+
// to a readable stream that happens to have Uint8Array as the type which might expect it to be
|
1690
|
+
// received in the same slices.
|
1691
|
+
// $FlowFixMe: This is a Node.js extension.
|
1692
|
+
var supportsBYOB = stream.supportsBYOB;
|
1693
|
+
|
1694
|
+
if (supportsBYOB === undefined) {
|
1695
|
+
try {
|
1696
|
+
// $FlowFixMe[extra-arg]: This argument is accepted.
|
1697
|
+
stream.getReader({
|
1698
|
+
mode: 'byob'
|
1699
|
+
}).releaseLock();
|
1700
|
+
supportsBYOB = true;
|
1701
|
+
} catch (x) {
|
1702
|
+
supportsBYOB = false;
|
1703
|
+
}
|
1704
|
+
}
|
1705
|
+
|
1706
|
+
var reader = stream.getReader(); // This task won't actually be retried. We just use it to attempt synchronous renders.
|
1707
|
+
|
1708
|
+
var streamTask = createTask(request, task.model, task.keyPath, task.implicitSlot, request.abortableTasks);
|
1709
|
+
request.abortableTasks.delete(streamTask);
|
1710
|
+
request.pendingChunks++; // The task represents the Start row. This adds a Stop row.
|
1711
|
+
|
1712
|
+
var startStreamRow = streamTask.id.toString(16) + ':' + (supportsBYOB ? 'r' : 'R') + '\n';
|
1713
|
+
request.completedRegularChunks.push(stringToChunk(startStreamRow)); // There's a race condition between when the stream is aborted and when the promise
|
1714
|
+
// resolves so we track whether we already aborted it to avoid writing twice.
|
1715
|
+
|
1716
|
+
var aborted = false;
|
1717
|
+
|
1718
|
+
function progress(entry) {
|
1719
|
+
if (aborted) {
|
1720
|
+
return;
|
1721
|
+
}
|
1722
|
+
|
1723
|
+
if (entry.done) {
|
1724
|
+
request.abortListeners.delete(error);
|
1725
|
+
var endStreamRow = streamTask.id.toString(16) + ':C\n';
|
1726
|
+
request.completedRegularChunks.push(stringToChunk(endStreamRow));
|
1727
|
+
enqueueFlush(request);
|
1728
|
+
aborted = true;
|
1729
|
+
} else {
|
1730
|
+
try {
|
1731
|
+
streamTask.model = entry.value;
|
1732
|
+
request.pendingChunks++;
|
1733
|
+
tryStreamTask(request, streamTask);
|
1734
|
+
enqueueFlush(request);
|
1735
|
+
reader.read().then(progress, error);
|
1736
|
+
} catch (x) {
|
1737
|
+
error(x);
|
1738
|
+
}
|
1739
|
+
}
|
1740
|
+
}
|
1741
|
+
|
1742
|
+
function error(reason) {
|
1743
|
+
if (aborted) {
|
1744
|
+
return;
|
1745
|
+
}
|
1746
|
+
|
1747
|
+
aborted = true;
|
1748
|
+
request.abortListeners.delete(error);
|
1749
|
+
|
1750
|
+
{
|
1751
|
+
var digest = logRecoverableError(request, reason);
|
1752
|
+
emitErrorChunk(request, streamTask.id, digest, reason);
|
1753
|
+
}
|
1754
|
+
|
1755
|
+
enqueueFlush(request); // $FlowFixMe should be able to pass mixed
|
1756
|
+
|
1757
|
+
reader.cancel(reason).then(error, error);
|
1758
|
+
}
|
1759
|
+
|
1760
|
+
request.abortListeners.add(error);
|
1761
|
+
reader.read().then(progress, error);
|
1762
|
+
return serializeByValueID(streamTask.id);
|
1763
|
+
} // This indirect exists so we can exclude its stack frame in DEV (and anything below it).
|
1764
|
+
|
1765
|
+
/** @noinline */
|
1766
|
+
|
1767
|
+
|
1768
|
+
function callIteratorInDEV(iterator, progress, error) {
|
1769
|
+
iterator.next().then(progress, error);
|
1770
|
+
}
|
1771
|
+
|
1772
|
+
function serializeAsyncIterable(request, task, iterable, iterator) {
|
1773
|
+
// Generators/Iterators are Iterables but they're also their own iterator
|
1774
|
+
// functions. If that's the case, we treat them as single-shot. Otherwise,
|
1775
|
+
// we assume that this iterable might be a multi-shot and allow it to be
|
1776
|
+
// iterated more than once on the client.
|
1777
|
+
var isIterator = iterable === iterator; // This task won't actually be retried. We just use it to attempt synchronous renders.
|
1778
|
+
|
1779
|
+
var streamTask = createTask(request, task.model, task.keyPath, task.implicitSlot, request.abortableTasks);
|
1780
|
+
request.abortableTasks.delete(streamTask);
|
1781
|
+
request.pendingChunks++; // The task represents the Start row. This adds a Stop row.
|
1782
|
+
|
1783
|
+
var startStreamRow = streamTask.id.toString(16) + ':' + (isIterator ? 'x' : 'X') + '\n';
|
1784
|
+
request.completedRegularChunks.push(stringToChunk(startStreamRow));
|
1785
|
+
|
1786
|
+
{
|
1787
|
+
var debugInfo = iterable._debugInfo;
|
1788
|
+
|
1789
|
+
if (debugInfo) {
|
1790
|
+
forwardDebugInfo(request, streamTask.id, debugInfo);
|
1791
|
+
}
|
1792
|
+
} // There's a race condition between when the stream is aborted and when the promise
|
1793
|
+
// resolves so we track whether we already aborted it to avoid writing twice.
|
1794
|
+
|
1795
|
+
|
1796
|
+
var aborted = false;
|
1797
|
+
|
1798
|
+
function progress(entry) {
|
1799
|
+
if (aborted) {
|
1800
|
+
return;
|
1801
|
+
}
|
1802
|
+
|
1803
|
+
if (entry.done) {
|
1804
|
+
request.abortListeners.delete(error);
|
1805
|
+
var endStreamRow;
|
1806
|
+
|
1807
|
+
if (entry.value === undefined) {
|
1808
|
+
endStreamRow = streamTask.id.toString(16) + ':C\n';
|
1809
|
+
} else {
|
1810
|
+
// Unlike streams, the last value may not be undefined. If it's not
|
1811
|
+
// we outline it and encode a reference to it in the closing instruction.
|
1812
|
+
try {
|
1813
|
+
var chunkId = outlineModel(request, entry.value);
|
1814
|
+
endStreamRow = streamTask.id.toString(16) + ':C' + stringify(serializeByValueID(chunkId)) + '\n';
|
1815
|
+
} catch (x) {
|
1816
|
+
error(x);
|
1817
|
+
return;
|
1818
|
+
}
|
1819
|
+
}
|
1820
|
+
|
1821
|
+
request.completedRegularChunks.push(stringToChunk(endStreamRow));
|
1822
|
+
enqueueFlush(request);
|
1823
|
+
aborted = true;
|
1824
|
+
} else {
|
1825
|
+
try {
|
1826
|
+
streamTask.model = entry.value;
|
1827
|
+
request.pendingChunks++;
|
1828
|
+
tryStreamTask(request, streamTask);
|
1829
|
+
enqueueFlush(request);
|
1830
|
+
|
1831
|
+
if (true) {
|
1832
|
+
callIteratorInDEV(iterator, progress, error);
|
1833
|
+
}
|
1834
|
+
} catch (x) {
|
1835
|
+
error(x);
|
1836
|
+
return;
|
1837
|
+
}
|
1838
|
+
}
|
1839
|
+
}
|
1840
|
+
|
1841
|
+
function error(reason) {
|
1842
|
+
if (aborted) {
|
1843
|
+
return;
|
1844
|
+
}
|
1845
|
+
|
1846
|
+
aborted = true;
|
1847
|
+
request.abortListeners.delete(error);
|
1848
|
+
|
1849
|
+
{
|
1850
|
+
var digest = logRecoverableError(request, reason);
|
1851
|
+
emitErrorChunk(request, streamTask.id, digest, reason);
|
1852
|
+
}
|
1853
|
+
|
1854
|
+
enqueueFlush(request);
|
1855
|
+
|
1856
|
+
if (typeof iterator.throw === 'function') {
|
1857
|
+
// The iterator protocol doesn't necessarily include this but a generator do.
|
1858
|
+
// $FlowFixMe should be able to pass mixed
|
1859
|
+
iterator.throw(reason).then(error, error);
|
1860
|
+
}
|
1861
|
+
}
|
1862
|
+
|
1863
|
+
request.abortListeners.add(error);
|
1864
|
+
|
1865
|
+
{
|
1866
|
+
callIteratorInDEV(iterator, progress, error);
|
1867
|
+
}
|
1868
|
+
|
1869
|
+
return serializeByValueID(streamTask.id);
|
1870
|
+
}
|
1871
|
+
|
1670
1872
|
function emitHint(request, code, model) {
|
1671
1873
|
emitHintChunk(request, code, model);
|
1672
1874
|
enqueueFlush(request);
|
@@ -1738,16 +1940,45 @@ function createLazyWrapperAroundWakeable(wakeable) {
|
|
1738
1940
|
}
|
1739
1941
|
|
1740
1942
|
return lazyType;
|
1943
|
+
} // This indirect exists so we can exclude its stack frame in DEV (and anything below it).
|
1944
|
+
|
1945
|
+
/** @noinline */
|
1946
|
+
|
1947
|
+
|
1948
|
+
function callComponentInDEV(Component, props, componentDebugInfo) {
|
1949
|
+
// The secondArg is always undefined in Server Components since refs error early.
|
1950
|
+
var secondArg = undefined;
|
1951
|
+
setCurrentOwner(componentDebugInfo);
|
1952
|
+
|
1953
|
+
try {
|
1954
|
+
if (supportsComponentStorage) {
|
1955
|
+
// Run the component in an Async Context that tracks the current owner.
|
1956
|
+
return componentStorage.run(componentDebugInfo, Component, props, secondArg);
|
1957
|
+
} else {
|
1958
|
+
return Component(props, secondArg);
|
1959
|
+
}
|
1960
|
+
} finally {
|
1961
|
+
setCurrentOwner(null);
|
1962
|
+
}
|
1963
|
+
} // This indirect exists so we can exclude its stack frame in DEV (and anything below it).
|
1964
|
+
|
1965
|
+
/** @noinline */
|
1966
|
+
|
1967
|
+
|
1968
|
+
function callLazyInitInDEV(lazy) {
|
1969
|
+
var payload = lazy._payload;
|
1970
|
+
var init = lazy._init;
|
1971
|
+
return init(payload);
|
1741
1972
|
}
|
1742
1973
|
|
1743
|
-
function renderFunctionComponent(request, task, key, Component, props, owner
|
1974
|
+
function renderFunctionComponent(request, task, key, Component, props, owner, // DEV-only
|
1975
|
+
stack) // DEV-only
|
1976
|
+
{
|
1744
1977
|
// Reset the task's thenable state before continuing, so that if a later
|
1745
1978
|
// component suspends we can reuse the same task object. If the same
|
1746
1979
|
// component suspends again, the thenable state will be restored.
|
1747
1980
|
var prevThenableState = task.thenableState;
|
1748
|
-
task.thenableState = null;
|
1749
|
-
|
1750
|
-
var secondArg = undefined;
|
1981
|
+
task.thenableState = null;
|
1751
1982
|
var result;
|
1752
1983
|
var componentDebugInfo;
|
1753
1984
|
|
@@ -1770,27 +2001,17 @@ function renderFunctionComponent(request, task, key, Component, props, owner) {
|
|
1770
2001
|
name: componentName,
|
1771
2002
|
env: request.environmentName,
|
1772
2003
|
owner: owner
|
1773
|
-
};
|
2004
|
+
};
|
1774
2005
|
// If we had a smarter way to dedupe we might not have to do this if there ends up
|
1775
2006
|
// being no references to this as an owner.
|
1776
2007
|
|
2008
|
+
|
1777
2009
|
outlineModel(request, componentDebugInfo);
|
1778
2010
|
emitDebugChunk(request, componentDebugID, componentDebugInfo);
|
1779
2011
|
}
|
1780
2012
|
|
1781
2013
|
prepareToUseHooksForComponent(prevThenableState, componentDebugInfo);
|
1782
|
-
|
1783
|
-
|
1784
|
-
try {
|
1785
|
-
if (supportsComponentStorage) {
|
1786
|
-
// Run the component in an Async Context that tracks the current owner.
|
1787
|
-
result = componentStorage.run(componentDebugInfo, Component, props, secondArg);
|
1788
|
-
} else {
|
1789
|
-
result = Component(props, secondArg);
|
1790
|
-
}
|
1791
|
-
} finally {
|
1792
|
-
setCurrentOwner(null);
|
1793
|
-
}
|
2014
|
+
result = callComponentInDEV(Component, props, componentDebugInfo);
|
1794
2015
|
}
|
1795
2016
|
|
1796
2017
|
if (typeof result === 'object' && result !== null) {
|
@@ -1842,6 +2063,33 @@ function renderFunctionComponent(request, task, key, Component, props, owner) {
|
|
1842
2063
|
{
|
1843
2064
|
result._debugInfo = iterableChild._debugInfo;
|
1844
2065
|
}
|
2066
|
+
} else if (typeof result[ASYNC_ITERATOR] === 'function' && (typeof ReadableStream !== 'function' || !(result instanceof ReadableStream))) {
|
2067
|
+
var _iterableChild = result;
|
2068
|
+
result = _defineProperty({}, ASYNC_ITERATOR, function () {
|
2069
|
+
var iterator = _iterableChild[ASYNC_ITERATOR]();
|
2070
|
+
|
2071
|
+
{
|
2072
|
+
// If this was an AsyncIterator but not an AsyncGeneratorFunction we warn because
|
2073
|
+
// it might have been a mistake. Technically you can make this mistake with
|
2074
|
+
// AsyncGeneratorFunctions and even single-shot AsyncIterables too but it's extra
|
2075
|
+
// tempting to try to return the value from a generator.
|
2076
|
+
if (iterator === _iterableChild) {
|
2077
|
+
var isGeneratorComponent = // $FlowIgnore[method-unbinding]
|
2078
|
+
Object.prototype.toString.call(Component) === '[object AsyncGeneratorFunction]' && // $FlowIgnore[method-unbinding]
|
2079
|
+
Object.prototype.toString.call(_iterableChild) === '[object AsyncGenerator]';
|
2080
|
+
|
2081
|
+
if (!isGeneratorComponent) {
|
2082
|
+
error('Returning an AsyncIterator from a Server Component is not supported ' + 'since it cannot be looped over more than once. ');
|
2083
|
+
}
|
2084
|
+
}
|
2085
|
+
}
|
2086
|
+
|
2087
|
+
return iterator;
|
2088
|
+
});
|
2089
|
+
|
2090
|
+
{
|
2091
|
+
result._debugInfo = _iterableChild._debugInfo;
|
2092
|
+
}
|
1845
2093
|
}
|
1846
2094
|
} // Track this element's key on the Server Component on the keyPath context..
|
1847
2095
|
|
@@ -1924,7 +2172,44 @@ function renderFragment(request, task, children) {
|
|
1924
2172
|
return children;
|
1925
2173
|
}
|
1926
2174
|
|
1927
|
-
function
|
2175
|
+
function renderAsyncFragment(request, task, children, getAsyncIterator) {
|
2176
|
+
if (task.keyPath !== null) {
|
2177
|
+
// We have a Server Component that specifies a key but we're now splitting
|
2178
|
+
// the tree using a fragment.
|
2179
|
+
var fragment = [REACT_ELEMENT_TYPE, REACT_FRAGMENT_TYPE, task.keyPath, {
|
2180
|
+
children: children
|
2181
|
+
}];
|
2182
|
+
|
2183
|
+
if (!task.implicitSlot) {
|
2184
|
+
// If this was keyed inside a set. I.e. the outer Server Component was keyed
|
2185
|
+
// then we need to handle reorders of the whole set. To do this we need to wrap
|
2186
|
+
// this array in a keyed Fragment.
|
2187
|
+
return fragment;
|
2188
|
+
} // If the outer Server Component was implicit but then an inner one had a key
|
2189
|
+
// we don't actually need to be able to move the whole set around. It'll always be
|
2190
|
+
// in an implicit slot. The key only exists to be able to reset the state of the
|
2191
|
+
// children. We could achieve the same effect by passing on the keyPath to the next
|
2192
|
+
// set of components inside the fragment. This would also allow a keyless fragment
|
2193
|
+
// reconcile against a single child.
|
2194
|
+
// Unfortunately because of JSON.stringify, we can't call the recursive loop for
|
2195
|
+
// each child within this context because we can't return a set with already resolved
|
2196
|
+
// values. E.g. a string would get double encoded. Returning would pop the context.
|
2197
|
+
// So instead, we wrap it with an unkeyed fragment and inner keyed fragment.
|
2198
|
+
|
2199
|
+
|
2200
|
+
return [fragment];
|
2201
|
+
} // Since we're yielding here, that implicitly resets the keyPath context on the
|
2202
|
+
// way up. Which is what we want since we've consumed it. If this changes to
|
2203
|
+
// be recursive serialization, we need to reset the keyPath and implicitSlot,
|
2204
|
+
// before recursing here.
|
2205
|
+
|
2206
|
+
|
2207
|
+
var asyncIterator = getAsyncIterator.call(children);
|
2208
|
+
return serializeAsyncIterable(request, task, children, asyncIterator);
|
2209
|
+
}
|
2210
|
+
|
2211
|
+
function renderClientElement(task, type, key, props, owner, // DEV-only
|
2212
|
+
stack) // DEV-only
|
1928
2213
|
{
|
1929
2214
|
// We prepend the terminal client element that actually gets serialized with
|
1930
2215
|
// the keys of any Server Components which are not serialized.
|
@@ -1974,7 +2259,8 @@ function outlineTask(request, task) {
|
|
1974
2259
|
return serializeLazyID(newTask.id);
|
1975
2260
|
}
|
1976
2261
|
|
1977
|
-
function renderElement(request, task, type, key, ref, props, owner
|
2262
|
+
function renderElement(request, task, type, key, ref, props, owner, // DEV only
|
2263
|
+
stack) // DEV only
|
1978
2264
|
{
|
1979
2265
|
if (ref !== null && ref !== undefined) {
|
1980
2266
|
// When the ref moves to the regular props object this will implicitly
|
@@ -1994,7 +2280,7 @@ function renderElement(request, task, type, key, ref, props, owner) // DEV only
|
|
1994
2280
|
}
|
1995
2281
|
|
1996
2282
|
if (typeof type === 'function') {
|
1997
|
-
if (isClientReference(type) ||
|
2283
|
+
if (isClientReference(type) || isOpaqueTemporaryReference(type)) {
|
1998
2284
|
// This is a reference to a Client Component.
|
1999
2285
|
return renderClientElement(task, type, key, props, owner);
|
2000
2286
|
} // This is a Server Component.
|
@@ -2031,9 +2317,12 @@ function renderElement(request, task, type, key, ref, props, owner) // DEV only
|
|
2031
2317
|
switch (type.$$typeof) {
|
2032
2318
|
case REACT_LAZY_TYPE:
|
2033
2319
|
{
|
2034
|
-
var
|
2035
|
-
|
2036
|
-
|
2320
|
+
var wrappedType;
|
2321
|
+
|
2322
|
+
{
|
2323
|
+
wrappedType = callLazyInitInDEV(type);
|
2324
|
+
}
|
2325
|
+
|
2037
2326
|
return renderElement(request, task, wrappedType, key, ref, props, owner);
|
2038
2327
|
}
|
2039
2328
|
|
@@ -2072,7 +2361,7 @@ function createTask(request, model, keyPath, implicitSlot, abortSet) {
|
|
2072
2361
|
// If we're about to write this into a new task we can assign it an ID early so that
|
2073
2362
|
// any other references can refer to the value we're about to write.
|
2074
2363
|
if (keyPath !== null || implicitSlot) ; else {
|
2075
|
-
request.writtenObjects.set(model, id);
|
2364
|
+
request.writtenObjects.set(model, serializeByValueID(id));
|
2076
2365
|
}
|
2077
2366
|
}
|
2078
2367
|
|
@@ -2135,10 +2424,6 @@ function serializeServerReferenceID(id) {
|
|
2135
2424
|
return '$F' + id.toString(16);
|
2136
2425
|
}
|
2137
2426
|
|
2138
|
-
function serializeTemporaryReferenceID(id) {
|
2139
|
-
return '$T' + id;
|
2140
|
-
}
|
2141
|
-
|
2142
2427
|
function serializeSymbolReference(name) {
|
2143
2428
|
return '$S' + name;
|
2144
2429
|
}
|
@@ -2255,9 +2540,8 @@ function serializeServerReference(request, serverReference) {
|
|
2255
2540
|
return serializeServerReferenceID(metadataId);
|
2256
2541
|
}
|
2257
2542
|
|
2258
|
-
function serializeTemporaryReference(request,
|
2259
|
-
|
2260
|
-
return serializeTemporaryReferenceID(id);
|
2543
|
+
function serializeTemporaryReference(request, reference) {
|
2544
|
+
return '$T' + reference;
|
2261
2545
|
}
|
2262
2546
|
|
2263
2547
|
function serializeLargeTextString(request, text) {
|
@@ -2269,20 +2553,6 @@ function serializeLargeTextString(request, text) {
|
|
2269
2553
|
|
2270
2554
|
function serializeMap(request, map) {
|
2271
2555
|
var entries = Array.from(map);
|
2272
|
-
|
2273
|
-
for (var i = 0; i < entries.length; i++) {
|
2274
|
-
var key = entries[i][0];
|
2275
|
-
|
2276
|
-
if (typeof key === 'object' && key !== null) {
|
2277
|
-
var writtenObjects = request.writtenObjects;
|
2278
|
-
var existingId = writtenObjects.get(key);
|
2279
|
-
|
2280
|
-
if (existingId === undefined) {
|
2281
|
-
writtenObjects.set(key, SEEN_BUT_NOT_YET_OUTLINED);
|
2282
|
-
}
|
2283
|
-
}
|
2284
|
-
}
|
2285
|
-
|
2286
2556
|
var id = outlineModel(request, entries);
|
2287
2557
|
return '$Q' + id.toString(16);
|
2288
2558
|
}
|
@@ -2295,20 +2565,6 @@ function serializeFormData(request, formData) {
|
|
2295
2565
|
|
2296
2566
|
function serializeSet(request, set) {
|
2297
2567
|
var entries = Array.from(set);
|
2298
|
-
|
2299
|
-
for (var i = 0; i < entries.length; i++) {
|
2300
|
-
var key = entries[i];
|
2301
|
-
|
2302
|
-
if (typeof key === 'object' && key !== null) {
|
2303
|
-
var writtenObjects = request.writtenObjects;
|
2304
|
-
var existingId = writtenObjects.get(key);
|
2305
|
-
|
2306
|
-
if (existingId === undefined) {
|
2307
|
-
writtenObjects.set(key, SEEN_BUT_NOT_YET_OUTLINED);
|
2308
|
-
}
|
2309
|
-
}
|
2310
|
-
}
|
2311
|
-
|
2312
2568
|
var id = outlineModel(request, entries);
|
2313
2569
|
return '$W' + id.toString(16);
|
2314
2570
|
}
|
@@ -2318,6 +2574,58 @@ function serializeIterator(request, iterator) {
|
|
2318
2574
|
return '$i' + id.toString(16);
|
2319
2575
|
}
|
2320
2576
|
|
2577
|
+
function serializeTypedArray(request, tag, typedArray) {
|
2578
|
+
request.pendingChunks++;
|
2579
|
+
var bufferId = request.nextChunkId++;
|
2580
|
+
emitTypedArrayChunk(request, bufferId, tag, typedArray);
|
2581
|
+
return serializeByValueID(bufferId);
|
2582
|
+
}
|
2583
|
+
|
2584
|
+
function serializeBlob(request, blob) {
|
2585
|
+
var model = [blob.type];
|
2586
|
+
var newTask = createTask(request, model, null, false, request.abortableTasks);
|
2587
|
+
var reader = blob.stream().getReader();
|
2588
|
+
var aborted = false;
|
2589
|
+
|
2590
|
+
function progress(entry) {
|
2591
|
+
if (aborted) {
|
2592
|
+
return;
|
2593
|
+
}
|
2594
|
+
|
2595
|
+
if (entry.done) {
|
2596
|
+
request.abortListeners.delete(error);
|
2597
|
+
aborted = true;
|
2598
|
+
pingTask(request, newTask);
|
2599
|
+
return;
|
2600
|
+
} // TODO: Emit the chunk early and refer to it later by dedupe.
|
2601
|
+
|
2602
|
+
|
2603
|
+
model.push(entry.value); // $FlowFixMe[incompatible-call]
|
2604
|
+
|
2605
|
+
return reader.read().then(progress).catch(error);
|
2606
|
+
}
|
2607
|
+
|
2608
|
+
function error(reason) {
|
2609
|
+
if (aborted) {
|
2610
|
+
return;
|
2611
|
+
}
|
2612
|
+
|
2613
|
+
aborted = true;
|
2614
|
+
request.abortListeners.delete(error);
|
2615
|
+
var digest = logRecoverableError(request, reason);
|
2616
|
+
emitErrorChunk(request, newTask.id, digest, reason);
|
2617
|
+
request.abortableTasks.delete(newTask);
|
2618
|
+
enqueueFlush(request); // $FlowFixMe should be able to pass mixed
|
2619
|
+
|
2620
|
+
reader.cancel(reason).then(error, error);
|
2621
|
+
}
|
2622
|
+
|
2623
|
+
request.abortListeners.add(error); // $FlowFixMe[incompatible-call]
|
2624
|
+
|
2625
|
+
reader.read().then(progress).catch(error);
|
2626
|
+
return '$B' + newTask.id.toString(16);
|
2627
|
+
}
|
2628
|
+
|
2321
2629
|
function escapeStringValue(value) {
|
2322
2630
|
if (value[0] === '$') {
|
2323
2631
|
// We need to escape $ prefixed strings since we use those to encode
|
@@ -2410,37 +2718,34 @@ function renderModelDestructive(request, task, parent, parentPropertyName, value
|
|
2410
2718
|
{
|
2411
2719
|
var _writtenObjects = request.writtenObjects;
|
2412
2720
|
|
2413
|
-
|
2414
|
-
|
2415
|
-
if (_existingId !== undefined) {
|
2416
|
-
if (task.keyPath !== null || task.implicitSlot) ; else if (modelRoot === value) {
|
2417
|
-
// This is the ID we're currently emitting so we need to write it
|
2418
|
-
// once but if we discover it again, we refer to it by id.
|
2419
|
-
modelRoot = null;
|
2420
|
-
} else if (_existingId === SEEN_BUT_NOT_YET_OUTLINED) {
|
2421
|
-
// TODO: If we throw here we can treat this as suspending which causes an outline
|
2422
|
-
// but that is able to reuse the same task if we're already in one but then that
|
2423
|
-
// will be a lazy future value rather than guaranteed to exist but maybe that's good.
|
2424
|
-
var newId = outlineModel(request, value);
|
2425
|
-
return serializeByValueID(newId);
|
2426
|
-
} else {
|
2427
|
-
// We've already emitted this as an outlined object, so we can refer to that by its
|
2428
|
-
// existing ID. TODO: We should use a lazy reference since, unlike plain objects,
|
2429
|
-
// elements might suspend so it might not have emitted yet even if we have the ID for
|
2430
|
-
// it. However, this creates an extra wrapper when it's not needed. We should really
|
2431
|
-
// detect whether this already was emitted and synchronously available. In that
|
2432
|
-
// case we can refer to it synchronously and only make it lazy otherwise.
|
2433
|
-
// We currently don't have a data structure that lets us see that though.
|
2434
|
-
return serializeByValueID(_existingId);
|
2435
|
-
}
|
2436
|
-
} else {
|
2437
|
-
// This is the first time we've seen this object. We may never see it again
|
2438
|
-
// so we'll inline it. Mark it as seen. If we see it again, we'll outline.
|
2439
|
-
_writtenObjects.set(value, SEEN_BUT_NOT_YET_OUTLINED); // The element's props are marked as "never outlined" so that they are inlined into
|
2440
|
-
// the same row as the element itself.
|
2441
|
-
|
2721
|
+
if (task.keyPath !== null || task.implicitSlot) ; else {
|
2722
|
+
var _existingReference = _writtenObjects.get(value);
|
2442
2723
|
|
2443
|
-
|
2724
|
+
if (_existingReference !== undefined) {
|
2725
|
+
if (modelRoot === value) {
|
2726
|
+
// This is the ID we're currently emitting so we need to write it
|
2727
|
+
// once but if we discover it again, we refer to it by id.
|
2728
|
+
modelRoot = null;
|
2729
|
+
} else {
|
2730
|
+
// We've already emitted this as an outlined object, so we can refer to that by its
|
2731
|
+
// existing ID. TODO: We should use a lazy reference since, unlike plain objects,
|
2732
|
+
// elements might suspend so it might not have emitted yet even if we have the ID for
|
2733
|
+
// it. However, this creates an extra wrapper when it's not needed. We should really
|
2734
|
+
// detect whether this already was emitted and synchronously available. In that
|
2735
|
+
// case we can refer to it synchronously and only make it lazy otherwise.
|
2736
|
+
// We currently don't have a data structure that lets us see that though.
|
2737
|
+
return _existingReference;
|
2738
|
+
}
|
2739
|
+
} else if (parentPropertyName.indexOf(':') === -1) {
|
2740
|
+
// TODO: If the property name contains a colon, we don't dedupe. Escape instead.
|
2741
|
+
var parentReference = _writtenObjects.get(parent);
|
2742
|
+
|
2743
|
+
if (parentReference !== undefined) {
|
2744
|
+
// If the parent has a reference, we can refer to this object indirectly
|
2745
|
+
// through the property name inside that parent.
|
2746
|
+
_writtenObjects.set(value, parentReference + ':' + parentPropertyName);
|
2747
|
+
}
|
2748
|
+
}
|
2444
2749
|
}
|
2445
2750
|
|
2446
2751
|
var element = value;
|
@@ -2483,9 +2788,11 @@ function renderModelDestructive(request, task, parent, parentPropertyName, value
|
|
2483
2788
|
// from suspending the lazy before.
|
2484
2789
|
task.thenableState = null;
|
2485
2790
|
var lazy = value;
|
2486
|
-
var
|
2487
|
-
|
2488
|
-
|
2791
|
+
var resolvedModel;
|
2792
|
+
|
2793
|
+
{
|
2794
|
+
resolvedModel = callLazyInitInDEV(lazy);
|
2795
|
+
}
|
2489
2796
|
|
2490
2797
|
{
|
2491
2798
|
var _debugInfo = lazy._debugInfo;
|
@@ -2507,17 +2814,30 @@ function renderModelDestructive(request, task, parent, parentPropertyName, value
|
|
2507
2814
|
|
2508
2815
|
return renderModelDestructive(request, task, emptyRoot, '', resolvedModel);
|
2509
2816
|
}
|
2817
|
+
|
2818
|
+
case REACT_LEGACY_ELEMENT_TYPE:
|
2819
|
+
{
|
2820
|
+
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.');
|
2821
|
+
}
|
2510
2822
|
}
|
2511
2823
|
|
2512
2824
|
if (isClientReference(value)) {
|
2513
2825
|
return serializeClientReference(request, parent, parentPropertyName, value);
|
2514
2826
|
}
|
2515
2827
|
|
2828
|
+
if (request.temporaryReferences !== undefined) {
|
2829
|
+
var tempRef = resolveTemporaryReference(request.temporaryReferences, value);
|
2830
|
+
|
2831
|
+
if (tempRef !== undefined) {
|
2832
|
+
return serializeTemporaryReference(request, tempRef);
|
2833
|
+
}
|
2834
|
+
}
|
2835
|
+
|
2516
2836
|
var writtenObjects = request.writtenObjects;
|
2517
|
-
var
|
2837
|
+
var existingReference = writtenObjects.get(value); // $FlowFixMe[method-unbinding]
|
2518
2838
|
|
2519
2839
|
if (typeof value.then === 'function') {
|
2520
|
-
if (
|
2840
|
+
if (existingReference !== undefined) {
|
2521
2841
|
if (task.keyPath !== null || task.implicitSlot) {
|
2522
2842
|
// If we're in some kind of context we can't reuse the result of this render or
|
2523
2843
|
// previous renders of this element. We only reuse Promises if they're not wrapped
|
@@ -2531,35 +2851,58 @@ function renderModelDestructive(request, task, parent, parentPropertyName, value
|
|
2531
2851
|
modelRoot = null;
|
2532
2852
|
} else {
|
2533
2853
|
// We've seen this promise before, so we can just refer to the same result.
|
2534
|
-
return
|
2854
|
+
return existingReference;
|
2535
2855
|
}
|
2536
2856
|
} // We assume that any object with a .then property is a "Thenable" type,
|
2537
2857
|
// or a Promise type. Either of which can be represented by a Promise.
|
2538
2858
|
|
2539
2859
|
|
2540
2860
|
var promiseId = serializeThenable(request, task, value);
|
2541
|
-
|
2542
|
-
|
2861
|
+
var promiseReference = serializePromiseID(promiseId);
|
2862
|
+
writtenObjects.set(value, promiseReference);
|
2863
|
+
return promiseReference;
|
2543
2864
|
}
|
2544
2865
|
|
2545
|
-
if (
|
2866
|
+
if (existingReference !== undefined) {
|
2546
2867
|
if (modelRoot === value) {
|
2547
2868
|
// This is the ID we're currently emitting so we need to write it
|
2548
2869
|
// once but if we discover it again, we refer to it by id.
|
2549
2870
|
modelRoot = null;
|
2550
|
-
} else
|
2551
|
-
var _newId = outlineModel(request, value);
|
2552
|
-
|
2553
|
-
return serializeByValueID(_newId);
|
2554
|
-
} else if (existingId !== NEVER_OUTLINED) {
|
2871
|
+
} else {
|
2555
2872
|
// We've already emitted this as an outlined object, so we can
|
2556
2873
|
// just refer to that by its existing ID.
|
2557
|
-
return
|
2874
|
+
return existingReference;
|
2875
|
+
}
|
2876
|
+
} else if (parentPropertyName.indexOf(':') === -1) {
|
2877
|
+
// TODO: If the property name contains a colon, we don't dedupe. Escape instead.
|
2878
|
+
var _parentReference = writtenObjects.get(parent);
|
2879
|
+
|
2880
|
+
if (_parentReference !== undefined) {
|
2881
|
+
// If the parent has a reference, we can refer to this object indirectly
|
2882
|
+
// through the property name inside that parent.
|
2883
|
+
var propertyName = parentPropertyName;
|
2884
|
+
|
2885
|
+
if (isArray(parent) && parent[0] === REACT_ELEMENT_TYPE) {
|
2886
|
+
// For elements, we've converted it to an array but we'll have converted
|
2887
|
+
// it back to an element before we read the references so the property
|
2888
|
+
// needs to be aliased.
|
2889
|
+
switch (parentPropertyName) {
|
2890
|
+
case '1':
|
2891
|
+
propertyName = 'type';
|
2892
|
+
break;
|
2893
|
+
|
2894
|
+
case '2':
|
2895
|
+
propertyName = 'key';
|
2896
|
+
break;
|
2897
|
+
|
2898
|
+
case '3':
|
2899
|
+
propertyName = 'props';
|
2900
|
+
break;
|
2901
|
+
}
|
2902
|
+
}
|
2903
|
+
|
2904
|
+
writtenObjects.set(value, _parentReference + ':' + propertyName);
|
2558
2905
|
}
|
2559
|
-
} else {
|
2560
|
-
// This is the first time we've seen this object. We may never see it again
|
2561
|
-
// so we'll inline it. Mark it as seen. If we see it again, we'll outline.
|
2562
|
-
writtenObjects.set(value, SEEN_BUT_NOT_YET_OUTLINED);
|
2563
2906
|
}
|
2564
2907
|
|
2565
2908
|
if (isArray(value)) {
|
@@ -2579,29 +2922,114 @@ function renderModelDestructive(request, task, parent, parentPropertyName, value
|
|
2579
2922
|
return serializeFormData(request, value);
|
2580
2923
|
}
|
2581
2924
|
|
2582
|
-
|
2925
|
+
{
|
2926
|
+
if (value instanceof ArrayBuffer) {
|
2927
|
+
return serializeTypedArray(request, 'A', new Uint8Array(value));
|
2928
|
+
}
|
2583
2929
|
|
2584
|
-
|
2585
|
-
|
2586
|
-
|
2930
|
+
if (value instanceof Int8Array) {
|
2931
|
+
// char
|
2932
|
+
return serializeTypedArray(request, 'O', value);
|
2933
|
+
}
|
2587
2934
|
|
2588
|
-
if (
|
2589
|
-
//
|
2590
|
-
return
|
2935
|
+
if (value instanceof Uint8Array) {
|
2936
|
+
// unsigned char
|
2937
|
+
return serializeTypedArray(request, 'o', value);
|
2591
2938
|
}
|
2592
2939
|
|
2593
|
-
|
2594
|
-
|
2940
|
+
if (value instanceof Uint8ClampedArray) {
|
2941
|
+
// unsigned clamped char
|
2942
|
+
return serializeTypedArray(request, 'U', value);
|
2943
|
+
}
|
2595
2944
|
|
2945
|
+
if (value instanceof Int16Array) {
|
2946
|
+
// sort
|
2947
|
+
return serializeTypedArray(request, 'S', value);
|
2948
|
+
}
|
2596
2949
|
|
2597
|
-
|
2950
|
+
if (value instanceof Uint16Array) {
|
2951
|
+
// unsigned short
|
2952
|
+
return serializeTypedArray(request, 's', value);
|
2953
|
+
}
|
2598
2954
|
|
2599
|
-
|
2600
|
-
|
2601
|
-
|
2955
|
+
if (value instanceof Int32Array) {
|
2956
|
+
// long
|
2957
|
+
return serializeTypedArray(request, 'L', value);
|
2958
|
+
}
|
2602
2959
|
|
2603
|
-
|
2604
|
-
|
2960
|
+
if (value instanceof Uint32Array) {
|
2961
|
+
// unsigned long
|
2962
|
+
return serializeTypedArray(request, 'l', value);
|
2963
|
+
}
|
2964
|
+
|
2965
|
+
if (value instanceof Float32Array) {
|
2966
|
+
// float
|
2967
|
+
return serializeTypedArray(request, 'G', value);
|
2968
|
+
}
|
2969
|
+
|
2970
|
+
if (value instanceof Float64Array) {
|
2971
|
+
// double
|
2972
|
+
return serializeTypedArray(request, 'g', value);
|
2973
|
+
}
|
2974
|
+
|
2975
|
+
if (value instanceof BigInt64Array) {
|
2976
|
+
// number
|
2977
|
+
return serializeTypedArray(request, 'M', value);
|
2978
|
+
}
|
2979
|
+
|
2980
|
+
if (value instanceof BigUint64Array) {
|
2981
|
+
// unsigned number
|
2982
|
+
// We use "m" instead of "n" since JSON can start with "null"
|
2983
|
+
return serializeTypedArray(request, 'm', value);
|
2984
|
+
}
|
2985
|
+
|
2986
|
+
if (value instanceof DataView) {
|
2987
|
+
return serializeTypedArray(request, 'V', value);
|
2988
|
+
} // TODO: Blob is not available in old Node. Remove the typeof check later.
|
2989
|
+
|
2990
|
+
|
2991
|
+
if (typeof Blob === 'function' && value instanceof Blob) {
|
2992
|
+
return serializeBlob(request, value);
|
2993
|
+
}
|
2994
|
+
}
|
2995
|
+
|
2996
|
+
var iteratorFn = getIteratorFn(value);
|
2997
|
+
|
2998
|
+
if (iteratorFn) {
|
2999
|
+
// TODO: Should we serialize the return value as well like we do for AsyncIterables?
|
3000
|
+
var iterator = iteratorFn.call(value);
|
3001
|
+
|
3002
|
+
if (iterator === value) {
|
3003
|
+
// Iterator, not Iterable
|
3004
|
+
return serializeIterator(request, iterator);
|
3005
|
+
}
|
3006
|
+
|
3007
|
+
return renderFragment(request, task, Array.from(iterator));
|
3008
|
+
}
|
3009
|
+
|
3010
|
+
{
|
3011
|
+
// TODO: Blob is not available in old Node. Remove the typeof check later.
|
3012
|
+
if (typeof ReadableStream === 'function' && value instanceof ReadableStream) {
|
3013
|
+
return serializeReadableStream(request, task, value);
|
3014
|
+
}
|
3015
|
+
|
3016
|
+
var getAsyncIterator = value[ASYNC_ITERATOR];
|
3017
|
+
|
3018
|
+
if (typeof getAsyncIterator === 'function') {
|
3019
|
+
// We treat AsyncIterables as a Fragment and as such we might need to key them.
|
3020
|
+
return renderAsyncFragment(request, task, value, getAsyncIterator);
|
3021
|
+
}
|
3022
|
+
} // Verify that this is a simple plain object.
|
3023
|
+
|
3024
|
+
|
3025
|
+
var proto = getPrototypeOf(value);
|
3026
|
+
|
3027
|
+
if (proto !== ObjectPrototype && (proto === null || getPrototypeOf(proto) !== null)) {
|
3028
|
+
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.');
|
3029
|
+
}
|
3030
|
+
|
3031
|
+
{
|
3032
|
+
if (objectName(value) !== 'Object') {
|
2605
3033
|
error('Only plain objects can be passed to Client Components from Server Components. ' + '%s objects are not supported.%s', objectName(value), describeObjectForErrorMessage(parent, parentPropertyName));
|
2606
3034
|
} else if (!isSimpleObject(value)) {
|
2607
3035
|
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));
|
@@ -2662,11 +3090,17 @@ function renderModelDestructive(request, task, parent, parentPropertyName, value
|
|
2662
3090
|
return serializeServerReference(request, value);
|
2663
3091
|
}
|
2664
3092
|
|
2665
|
-
if (
|
2666
|
-
|
3093
|
+
if (request.temporaryReferences !== undefined) {
|
3094
|
+
var _tempRef = resolveTemporaryReference(request.temporaryReferences, value);
|
3095
|
+
|
3096
|
+
if (_tempRef !== undefined) {
|
3097
|
+
return serializeTemporaryReference(request, _tempRef);
|
3098
|
+
}
|
2667
3099
|
}
|
2668
3100
|
|
2669
|
-
if (
|
3101
|
+
if (isOpaqueTemporaryReference(value)) {
|
3102
|
+
throw new Error('Could not reference an opaque temporary reference. ' + 'This is likely due to misconfiguring the temporaryReferences options ' + 'on the server.');
|
3103
|
+
} else if (/^on[A-Z]/.test(parentPropertyName)) {
|
2670
3104
|
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.');
|
2671
3105
|
} else if ((jsxChildrenParents.has(parent) || jsxPropsParents.has(parent) && parentPropertyName === 'children')) {
|
2672
3106
|
var componentName = value.displayName || value.name || 'Component';
|
@@ -2678,11 +3112,10 @@ function renderModelDestructive(request, task, parent, parentPropertyName, value
|
|
2678
3112
|
|
2679
3113
|
if (typeof value === 'symbol') {
|
2680
3114
|
var writtenSymbols = request.writtenSymbols;
|
3115
|
+
var existingId = writtenSymbols.get(value);
|
2681
3116
|
|
2682
|
-
|
2683
|
-
|
2684
|
-
if (_existingId2 !== undefined) {
|
2685
|
-
return serializeByValueID(_existingId2);
|
3117
|
+
if (existingId !== undefined) {
|
3118
|
+
return serializeByValueID(existingId);
|
2686
3119
|
} // $FlowFixMe[incompatible-type] `description` might be undefined
|
2687
3120
|
|
2688
3121
|
|
@@ -2870,6 +3303,18 @@ function emitDebugChunk(request, id, debugInfo) {
|
|
2870
3303
|
request.completedRegularChunks.push(processedChunk);
|
2871
3304
|
}
|
2872
3305
|
|
3306
|
+
function emitTypedArrayChunk(request, id, tag, typedArray) {
|
3307
|
+
|
3308
|
+
request.pendingChunks++; // Extra chunk for the header.
|
3309
|
+
// TODO: Convert to little endian if that's not the server default.
|
3310
|
+
|
3311
|
+
var binaryChunk = typedArrayToBinaryChunk(typedArray);
|
3312
|
+
var binaryLength = byteLengthOfBinaryChunk(binaryChunk);
|
3313
|
+
var row = id.toString(16) + ':' + tag + binaryLength.toString(16) + ',';
|
3314
|
+
var headerChunk = stringToChunk(row);
|
3315
|
+
request.completedRegularChunks.push(headerChunk, binaryChunk);
|
3316
|
+
}
|
3317
|
+
|
2873
3318
|
function emitTextChunk(request, id, text) {
|
2874
3319
|
request.pendingChunks++; // Extra chunk for the header.
|
2875
3320
|
|
@@ -2905,6 +3350,14 @@ function renderConsoleValue(request, counter, parent, parentPropertyName, value)
|
|
2905
3350
|
return serializeClientReference(request, parent, parentPropertyName, value);
|
2906
3351
|
}
|
2907
3352
|
|
3353
|
+
if (request.temporaryReferences !== undefined) {
|
3354
|
+
var tempRef = resolveTemporaryReference(request.temporaryReferences, value);
|
3355
|
+
|
3356
|
+
if (tempRef !== undefined) {
|
3357
|
+
return serializeTemporaryReference(request, tempRef);
|
3358
|
+
}
|
3359
|
+
}
|
3360
|
+
|
2908
3361
|
if (counter.objectCount > 20) {
|
2909
3362
|
// We've reached our max number of objects to serialize across the wire so we serialize this
|
2910
3363
|
// object but no properties inside of it, as a place holder.
|
@@ -2913,12 +3366,12 @@ function renderConsoleValue(request, counter, parent, parentPropertyName, value)
|
|
2913
3366
|
|
2914
3367
|
counter.objectCount++;
|
2915
3368
|
var writtenObjects = request.writtenObjects;
|
2916
|
-
var
|
3369
|
+
var existingReference = writtenObjects.get(value); // $FlowFixMe[method-unbinding]
|
2917
3370
|
|
2918
3371
|
if (typeof value.then === 'function') {
|
2919
|
-
if (
|
3372
|
+
if (existingReference !== undefined) {
|
2920
3373
|
// We've seen this promise before, so we can just refer to the same result.
|
2921
|
-
return
|
3374
|
+
return existingReference;
|
2922
3375
|
}
|
2923
3376
|
|
2924
3377
|
var thenable = value;
|
@@ -2950,10 +3403,10 @@ function renderConsoleValue(request, counter, parent, parentPropertyName, value)
|
|
2950
3403
|
return serializeInfinitePromise();
|
2951
3404
|
}
|
2952
3405
|
|
2953
|
-
if (
|
3406
|
+
if (existingReference !== undefined) {
|
2954
3407
|
// We've already emitted this as a real object, so we can
|
2955
|
-
// just refer to that by its existing
|
2956
|
-
return
|
3408
|
+
// just refer to that by its existing reference.
|
3409
|
+
return existingReference;
|
2957
3410
|
}
|
2958
3411
|
|
2959
3412
|
if (isArray(value)) {
|
@@ -2973,6 +3426,77 @@ function renderConsoleValue(request, counter, parent, parentPropertyName, value)
|
|
2973
3426
|
return serializeFormData(request, value);
|
2974
3427
|
}
|
2975
3428
|
|
3429
|
+
{
|
3430
|
+
if (value instanceof ArrayBuffer) {
|
3431
|
+
return serializeTypedArray(request, 'A', new Uint8Array(value));
|
3432
|
+
}
|
3433
|
+
|
3434
|
+
if (value instanceof Int8Array) {
|
3435
|
+
// char
|
3436
|
+
return serializeTypedArray(request, 'O', value);
|
3437
|
+
}
|
3438
|
+
|
3439
|
+
if (value instanceof Uint8Array) {
|
3440
|
+
// unsigned char
|
3441
|
+
return serializeTypedArray(request, 'o', value);
|
3442
|
+
}
|
3443
|
+
|
3444
|
+
if (value instanceof Uint8ClampedArray) {
|
3445
|
+
// unsigned clamped char
|
3446
|
+
return serializeTypedArray(request, 'U', value);
|
3447
|
+
}
|
3448
|
+
|
3449
|
+
if (value instanceof Int16Array) {
|
3450
|
+
// sort
|
3451
|
+
return serializeTypedArray(request, 'S', value);
|
3452
|
+
}
|
3453
|
+
|
3454
|
+
if (value instanceof Uint16Array) {
|
3455
|
+
// unsigned short
|
3456
|
+
return serializeTypedArray(request, 's', value);
|
3457
|
+
}
|
3458
|
+
|
3459
|
+
if (value instanceof Int32Array) {
|
3460
|
+
// long
|
3461
|
+
return serializeTypedArray(request, 'L', value);
|
3462
|
+
}
|
3463
|
+
|
3464
|
+
if (value instanceof Uint32Array) {
|
3465
|
+
// unsigned long
|
3466
|
+
return serializeTypedArray(request, 'l', value);
|
3467
|
+
}
|
3468
|
+
|
3469
|
+
if (value instanceof Float32Array) {
|
3470
|
+
// float
|
3471
|
+
return serializeTypedArray(request, 'G', value);
|
3472
|
+
}
|
3473
|
+
|
3474
|
+
if (value instanceof Float64Array) {
|
3475
|
+
// double
|
3476
|
+
return serializeTypedArray(request, 'g', value);
|
3477
|
+
}
|
3478
|
+
|
3479
|
+
if (value instanceof BigInt64Array) {
|
3480
|
+
// number
|
3481
|
+
return serializeTypedArray(request, 'M', value);
|
3482
|
+
}
|
3483
|
+
|
3484
|
+
if (value instanceof BigUint64Array) {
|
3485
|
+
// unsigned number
|
3486
|
+
// We use "m" instead of "n" since JSON can start with "null"
|
3487
|
+
return serializeTypedArray(request, 'm', value);
|
3488
|
+
}
|
3489
|
+
|
3490
|
+
if (value instanceof DataView) {
|
3491
|
+
return serializeTypedArray(request, 'V', value);
|
3492
|
+
} // TODO: Blob is not available in old Node. Remove the typeof check later.
|
3493
|
+
|
3494
|
+
|
3495
|
+
if (typeof Blob === 'function' && value instanceof Blob) {
|
3496
|
+
return serializeBlob(request, value);
|
3497
|
+
}
|
3498
|
+
}
|
3499
|
+
|
2976
3500
|
var iteratorFn = getIteratorFn(value);
|
2977
3501
|
|
2978
3502
|
if (iteratorFn) {
|
@@ -3018,8 +3542,12 @@ function renderConsoleValue(request, counter, parent, parentPropertyName, value)
|
|
3018
3542
|
return serializeClientReference(request, parent, parentPropertyName, value);
|
3019
3543
|
}
|
3020
3544
|
|
3021
|
-
if (
|
3022
|
-
|
3545
|
+
if (request.temporaryReferences !== undefined) {
|
3546
|
+
var _tempRef2 = resolveTemporaryReference(request.temporaryReferences, value);
|
3547
|
+
|
3548
|
+
if (_tempRef2 !== undefined) {
|
3549
|
+
return serializeTemporaryReference(request, _tempRef2);
|
3550
|
+
}
|
3023
3551
|
} // Serialize the body of the function as an eval so it can be printed.
|
3024
3552
|
// $FlowFixMe[method-unbinding]
|
3025
3553
|
|
@@ -3029,11 +3557,10 @@ function renderConsoleValue(request, counter, parent, parentPropertyName, value)
|
|
3029
3557
|
|
3030
3558
|
if (typeof value === 'symbol') {
|
3031
3559
|
var writtenSymbols = request.writtenSymbols;
|
3560
|
+
var existingId = writtenSymbols.get(value);
|
3032
3561
|
|
3033
|
-
|
3034
|
-
|
3035
|
-
if (_existingId3 !== undefined) {
|
3036
|
-
return serializeByValueID(_existingId3);
|
3562
|
+
if (existingId !== undefined) {
|
3563
|
+
return serializeByValueID(existingId);
|
3037
3564
|
} // $FlowFixMe[incompatible-type] `description` might be undefined
|
3038
3565
|
|
3039
3566
|
|
@@ -3088,6 +3615,85 @@ function emitChunk(request, task, value) {
|
|
3088
3615
|
emitTextChunk(request, id, value);
|
3089
3616
|
return;
|
3090
3617
|
}
|
3618
|
+
|
3619
|
+
{
|
3620
|
+
if (value instanceof ArrayBuffer) {
|
3621
|
+
emitTypedArrayChunk(request, id, 'A', new Uint8Array(value));
|
3622
|
+
return;
|
3623
|
+
}
|
3624
|
+
|
3625
|
+
if (value instanceof Int8Array) {
|
3626
|
+
// char
|
3627
|
+
emitTypedArrayChunk(request, id, 'O', value);
|
3628
|
+
return;
|
3629
|
+
}
|
3630
|
+
|
3631
|
+
if (value instanceof Uint8Array) {
|
3632
|
+
// unsigned char
|
3633
|
+
emitTypedArrayChunk(request, id, 'o', value);
|
3634
|
+
return;
|
3635
|
+
}
|
3636
|
+
|
3637
|
+
if (value instanceof Uint8ClampedArray) {
|
3638
|
+
// unsigned clamped char
|
3639
|
+
emitTypedArrayChunk(request, id, 'U', value);
|
3640
|
+
return;
|
3641
|
+
}
|
3642
|
+
|
3643
|
+
if (value instanceof Int16Array) {
|
3644
|
+
// sort
|
3645
|
+
emitTypedArrayChunk(request, id, 'S', value);
|
3646
|
+
return;
|
3647
|
+
}
|
3648
|
+
|
3649
|
+
if (value instanceof Uint16Array) {
|
3650
|
+
// unsigned short
|
3651
|
+
emitTypedArrayChunk(request, id, 's', value);
|
3652
|
+
return;
|
3653
|
+
}
|
3654
|
+
|
3655
|
+
if (value instanceof Int32Array) {
|
3656
|
+
// long
|
3657
|
+
emitTypedArrayChunk(request, id, 'L', value);
|
3658
|
+
return;
|
3659
|
+
}
|
3660
|
+
|
3661
|
+
if (value instanceof Uint32Array) {
|
3662
|
+
// unsigned long
|
3663
|
+
emitTypedArrayChunk(request, id, 'l', value);
|
3664
|
+
return;
|
3665
|
+
}
|
3666
|
+
|
3667
|
+
if (value instanceof Float32Array) {
|
3668
|
+
// float
|
3669
|
+
emitTypedArrayChunk(request, id, 'G', value);
|
3670
|
+
return;
|
3671
|
+
}
|
3672
|
+
|
3673
|
+
if (value instanceof Float64Array) {
|
3674
|
+
// double
|
3675
|
+
emitTypedArrayChunk(request, id, 'g', value);
|
3676
|
+
return;
|
3677
|
+
}
|
3678
|
+
|
3679
|
+
if (value instanceof BigInt64Array) {
|
3680
|
+
// number
|
3681
|
+
emitTypedArrayChunk(request, id, 'M', value);
|
3682
|
+
return;
|
3683
|
+
}
|
3684
|
+
|
3685
|
+
if (value instanceof BigUint64Array) {
|
3686
|
+
// unsigned number
|
3687
|
+
// We use "m" instead of "n" since JSON can start with "null"
|
3688
|
+
emitTypedArrayChunk(request, id, 'm', value);
|
3689
|
+
return;
|
3690
|
+
}
|
3691
|
+
|
3692
|
+
if (value instanceof DataView) {
|
3693
|
+
emitTypedArrayChunk(request, id, 'V', value);
|
3694
|
+
return;
|
3695
|
+
}
|
3696
|
+
} // For anything else we need to try to serialize it using JSON.
|
3091
3697
|
// $FlowFixMe[incompatible-type] stringify can return null for undefined but we never do
|
3092
3698
|
|
3093
3699
|
|
@@ -3133,8 +3739,11 @@ function retryTask(request, task) {
|
|
3133
3739
|
task.implicitSlot = false;
|
3134
3740
|
|
3135
3741
|
if (typeof resolvedModel === 'object' && resolvedModel !== null) {
|
3136
|
-
//
|
3742
|
+
// We're not in a contextual place here so we can refer to this object by this ID for
|
3743
|
+
// any future references.
|
3744
|
+
request.writtenObjects.set(resolvedModel, serializeByValueID(task.id)); // Object might contain unresolved values like additional elements.
|
3137
3745
|
// This is simulating what the JSON loop would do if this was part of it.
|
3746
|
+
|
3138
3747
|
emitChunk(request, task, resolvedModel);
|
3139
3748
|
} else {
|
3140
3749
|
// If the value is a string, it means it's a terminal value and we already escaped it
|
@@ -3176,6 +3785,26 @@ function retryTask(request, task) {
|
|
3176
3785
|
}
|
3177
3786
|
}
|
3178
3787
|
|
3788
|
+
function tryStreamTask(request, task) {
|
3789
|
+
// This is used to try to emit something synchronously but if it suspends,
|
3790
|
+
// we emit a reference to a new outlined task immediately instead.
|
3791
|
+
var prevDebugID = debugID;
|
3792
|
+
|
3793
|
+
{
|
3794
|
+
// We don't use the id of the stream task for debugID. Instead we leave it null
|
3795
|
+
// so that we instead outline the row to get a new debugID if needed.
|
3796
|
+
debugID = null;
|
3797
|
+
}
|
3798
|
+
|
3799
|
+
try {
|
3800
|
+
emitChunk(request, task, task.model);
|
3801
|
+
} finally {
|
3802
|
+
{
|
3803
|
+
debugID = prevDebugID;
|
3804
|
+
}
|
3805
|
+
}
|
3806
|
+
}
|
3807
|
+
|
3179
3808
|
function performWork(request) {
|
3180
3809
|
var prevDispatcher = ReactSharedInternals.H;
|
3181
3810
|
ReactSharedInternals.H = HooksDispatcher;
|
@@ -3550,8 +4179,12 @@ function loadChunk(chunkId, filename) {
|
|
3550
4179
|
return __webpack_chunk_load__(chunkId);
|
3551
4180
|
}
|
3552
4181
|
|
4182
|
+
// $FlowFixMe[method-unbinding]
|
4183
|
+
var hasOwnProperty = Object.prototype.hasOwnProperty;
|
4184
|
+
|
3553
4185
|
var PENDING = 'pending';
|
3554
4186
|
var BLOCKED = 'blocked';
|
4187
|
+
var CYCLIC = 'cyclic';
|
3555
4188
|
var RESOLVED_MODEL = 'resolved_model';
|
3556
4189
|
var INITIALIZED = 'fulfilled';
|
3557
4190
|
var ERRORED = 'rejected'; // $FlowFixMe[missing-this-annot]
|
@@ -3584,6 +4217,7 @@ Chunk.prototype.then = function (resolve, reject) {
|
|
3584
4217
|
|
3585
4218
|
case PENDING:
|
3586
4219
|
case BLOCKED:
|
4220
|
+
case CYCLIC:
|
3587
4221
|
if (resolve) {
|
3588
4222
|
if (chunk.value === null) {
|
3589
4223
|
chunk.value = [];
|
@@ -3625,8 +4259,38 @@ function wakeChunk(listeners, value) {
|
|
3625
4259
|
}
|
3626
4260
|
}
|
3627
4261
|
|
4262
|
+
function wakeChunkIfInitialized(chunk, resolveListeners, rejectListeners) {
|
4263
|
+
switch (chunk.status) {
|
4264
|
+
case INITIALIZED:
|
4265
|
+
wakeChunk(resolveListeners, chunk.value);
|
4266
|
+
break;
|
4267
|
+
|
4268
|
+
case PENDING:
|
4269
|
+
case BLOCKED:
|
4270
|
+
case CYCLIC:
|
4271
|
+
chunk.value = resolveListeners;
|
4272
|
+
chunk.reason = rejectListeners;
|
4273
|
+
break;
|
4274
|
+
|
4275
|
+
case ERRORED:
|
4276
|
+
if (rejectListeners) {
|
4277
|
+
wakeChunk(rejectListeners, chunk.reason);
|
4278
|
+
}
|
4279
|
+
|
4280
|
+
break;
|
4281
|
+
}
|
4282
|
+
}
|
4283
|
+
|
3628
4284
|
function triggerErrorOnChunk(chunk, error) {
|
3629
4285
|
if (chunk.status !== PENDING && chunk.status !== BLOCKED) {
|
4286
|
+
{
|
4287
|
+
// If we get more data to an already resolved ID, we assume that it's
|
4288
|
+
// a stream chunk since any other row shouldn't have more than one entry.
|
4289
|
+
var streamChunk = chunk;
|
4290
|
+
var controller = streamChunk.reason; // $FlowFixMe[incompatible-call]: The error method should accept mixed.
|
4291
|
+
|
4292
|
+
controller.error(error);
|
4293
|
+
}
|
3630
4294
|
|
3631
4295
|
return;
|
3632
4296
|
}
|
@@ -3641,9 +4305,64 @@ function triggerErrorOnChunk(chunk, error) {
|
|
3641
4305
|
}
|
3642
4306
|
}
|
3643
4307
|
|
3644
|
-
function createResolvedModelChunk(response, value) {
|
4308
|
+
function createResolvedModelChunk(response, value, id) {
|
4309
|
+
// $FlowFixMe[invalid-constructor] Flow doesn't support functions as constructors
|
4310
|
+
return new Chunk(RESOLVED_MODEL, value, id, response);
|
4311
|
+
}
|
4312
|
+
|
4313
|
+
function resolveModelChunk(chunk, value, id) {
|
4314
|
+
if (chunk.status !== PENDING) {
|
4315
|
+
{
|
4316
|
+
// If we get more data to an already resolved ID, we assume that it's
|
4317
|
+
// a stream chunk since any other row shouldn't have more than one entry.
|
4318
|
+
var streamChunk = chunk;
|
4319
|
+
var controller = streamChunk.reason;
|
4320
|
+
|
4321
|
+
if (value[0] === 'C') {
|
4322
|
+
controller.close(value === 'C' ? '"$undefined"' : value.slice(1));
|
4323
|
+
} else {
|
4324
|
+
controller.enqueueModel(value);
|
4325
|
+
}
|
4326
|
+
}
|
4327
|
+
|
4328
|
+
return;
|
4329
|
+
}
|
4330
|
+
|
4331
|
+
var resolveListeners = chunk.value;
|
4332
|
+
var rejectListeners = chunk.reason;
|
4333
|
+
var resolvedChunk = chunk;
|
4334
|
+
resolvedChunk.status = RESOLVED_MODEL;
|
4335
|
+
resolvedChunk.value = value;
|
4336
|
+
resolvedChunk.reason = id;
|
4337
|
+
|
4338
|
+
if (resolveListeners !== null) {
|
4339
|
+
// This is unfortunate that we're reading this eagerly if
|
4340
|
+
// we already have listeners attached since they might no
|
4341
|
+
// longer be rendered or might not be the highest pri.
|
4342
|
+
initializeModelChunk(resolvedChunk); // The status might have changed after initialization.
|
4343
|
+
|
4344
|
+
wakeChunkIfInitialized(chunk, resolveListeners, rejectListeners);
|
4345
|
+
}
|
4346
|
+
}
|
4347
|
+
|
4348
|
+
function createInitializedStreamChunk(response, value, controller) {
|
4349
|
+
// We use the reason field to stash the controller since we already have that
|
4350
|
+
// field. It's a bit of a hack but efficient.
|
3645
4351
|
// $FlowFixMe[invalid-constructor] Flow doesn't support functions as constructors
|
3646
|
-
return new Chunk(
|
4352
|
+
return new Chunk(INITIALIZED, value, controller, response);
|
4353
|
+
}
|
4354
|
+
|
4355
|
+
function createResolvedIteratorResultChunk(response, value, done) {
|
4356
|
+
// To reuse code as much code as possible we add the wrapper element as part of the JSON.
|
4357
|
+
var iteratorResultJSON = (done ? '{"done":true,"value":' : '{"done":false,"value":') + value + '}'; // $FlowFixMe[invalid-constructor] Flow doesn't support functions as constructors
|
4358
|
+
|
4359
|
+
return new Chunk(RESOLVED_MODEL, iteratorResultJSON, -1, response);
|
4360
|
+
}
|
4361
|
+
|
4362
|
+
function resolveIteratorResultChunk(chunk, value, done) {
|
4363
|
+
// To reuse code as much code as possible we add the wrapper element as part of the JSON.
|
4364
|
+
var iteratorResultJSON = (done ? '{"done":true,"value":' : '{"done":false,"value":') + value + '}';
|
4365
|
+
resolveModelChunk(chunk, iteratorResultJSON, -1);
|
3647
4366
|
}
|
3648
4367
|
|
3649
4368
|
function bindArgs$1(fn, args) {
|
@@ -3674,11 +4393,51 @@ function loadServerReference$1(response, id, bound, parentChunk, parentObject, k
|
|
3674
4393
|
}
|
3675
4394
|
}
|
3676
4395
|
|
3677
|
-
promise.then(createModelResolver(parentChunk, parentObject, key, false, response, createModel), createModelReject(parentChunk)); // We need a placeholder value that will be replaced later.
|
4396
|
+
promise.then(createModelResolver(parentChunk, parentObject, key, false, response, createModel, []), createModelReject(parentChunk)); // We need a placeholder value that will be replaced later.
|
3678
4397
|
|
3679
4398
|
return null;
|
3680
4399
|
}
|
3681
4400
|
|
4401
|
+
function reviveModel(response, parentObj, parentKey, value, reference) {
|
4402
|
+
if (typeof value === 'string') {
|
4403
|
+
// We can't use .bind here because we need the "this" value.
|
4404
|
+
return parseModelString(response, parentObj, parentKey, value, reference);
|
4405
|
+
}
|
4406
|
+
|
4407
|
+
if (typeof value === 'object' && value !== null) {
|
4408
|
+
if (reference !== undefined && response._temporaryReferences !== undefined) {
|
4409
|
+
// Store this object's reference in case it's returned later.
|
4410
|
+
registerTemporaryReference(response._temporaryReferences, value, reference);
|
4411
|
+
}
|
4412
|
+
|
4413
|
+
if (Array.isArray(value)) {
|
4414
|
+
for (var i = 0; i < value.length; i++) {
|
4415
|
+
var childRef = reference !== undefined ? reference + ':' + i : undefined; // $FlowFixMe[cannot-write]
|
4416
|
+
|
4417
|
+
value[i] = reviveModel(response, value, '' + i, value[i], childRef);
|
4418
|
+
}
|
4419
|
+
} else {
|
4420
|
+
for (var key in value) {
|
4421
|
+
if (hasOwnProperty.call(value, key)) {
|
4422
|
+
var _childRef = reference !== undefined && key.indexOf(':') === -1 ? reference + ':' + key : undefined;
|
4423
|
+
|
4424
|
+
var newValue = reviveModel(response, value, key, value[key], _childRef);
|
4425
|
+
|
4426
|
+
if (newValue !== undefined) {
|
4427
|
+
// $FlowFixMe[cannot-write]
|
4428
|
+
value[key] = newValue;
|
4429
|
+
} else {
|
4430
|
+
// $FlowFixMe[cannot-write]
|
4431
|
+
delete value[key];
|
4432
|
+
}
|
4433
|
+
}
|
4434
|
+
}
|
4435
|
+
}
|
4436
|
+
}
|
4437
|
+
|
4438
|
+
return value;
|
4439
|
+
}
|
4440
|
+
|
3682
4441
|
var initializingChunk = null;
|
3683
4442
|
var initializingChunkBlockedModel = null;
|
3684
4443
|
|
@@ -3687,9 +4446,21 @@ function initializeModelChunk(chunk) {
|
|
3687
4446
|
var prevBlocked = initializingChunkBlockedModel;
|
3688
4447
|
initializingChunk = chunk;
|
3689
4448
|
initializingChunkBlockedModel = null;
|
4449
|
+
var rootReference = chunk.reason === -1 ? undefined : chunk.reason.toString(16);
|
4450
|
+
var resolvedModel = chunk.value; // We go to the CYCLIC state until we've fully resolved this.
|
4451
|
+
// We do this before parsing in case we try to initialize the same chunk
|
4452
|
+
// while parsing the model. Such as in a cyclic reference.
|
4453
|
+
|
4454
|
+
var cyclicChunk = chunk;
|
4455
|
+
cyclicChunk.status = CYCLIC;
|
4456
|
+
cyclicChunk.value = null;
|
4457
|
+
cyclicChunk.reason = null;
|
3690
4458
|
|
3691
4459
|
try {
|
3692
|
-
var
|
4460
|
+
var rawModel = JSON.parse(resolvedModel);
|
4461
|
+
var value = reviveModel(chunk._response, {
|
4462
|
+
'': rawModel
|
4463
|
+
}, '', rawModel, rootReference);
|
3693
4464
|
|
3694
4465
|
if (initializingChunkBlockedModel !== null && initializingChunkBlockedModel.deps > 0) {
|
3695
4466
|
initializingChunkBlockedModel.value = value; // We discovered new dependencies on modules that are not yet resolved.
|
@@ -3700,9 +4471,14 @@ function initializeModelChunk(chunk) {
|
|
3700
4471
|
blockedChunk.value = null;
|
3701
4472
|
blockedChunk.reason = null;
|
3702
4473
|
} else {
|
4474
|
+
var resolveListeners = cyclicChunk.value;
|
3703
4475
|
var initializedChunk = chunk;
|
3704
4476
|
initializedChunk.status = INITIALIZED;
|
3705
4477
|
initializedChunk.value = value;
|
4478
|
+
|
4479
|
+
if (resolveListeners !== null) {
|
4480
|
+
wakeChunk(resolveListeners, value);
|
4481
|
+
}
|
3706
4482
|
}
|
3707
4483
|
} catch (error) {
|
3708
4484
|
var erroredChunk = chunk;
|
@@ -3739,7 +4515,7 @@ function getChunk(response, id) {
|
|
3739
4515
|
|
3740
4516
|
if (backingEntry != null) {
|
3741
4517
|
// We assume that this is a string entry for now.
|
3742
|
-
chunk = createResolvedModelChunk(response, backingEntry);
|
4518
|
+
chunk = createResolvedModelChunk(response, backingEntry, id);
|
3743
4519
|
} else {
|
3744
4520
|
// We're still waiting on this entry to stream in.
|
3745
4521
|
chunk = createPendingChunk(response);
|
@@ -3751,7 +4527,7 @@ function getChunk(response, id) {
|
|
3751
4527
|
return chunk;
|
3752
4528
|
}
|
3753
4529
|
|
3754
|
-
function createModelResolver(chunk, parentObject, key, cyclic, response, map) {
|
4530
|
+
function createModelResolver(chunk, parentObject, key, cyclic, response, map, path) {
|
3755
4531
|
var blocked;
|
3756
4532
|
|
3757
4533
|
if (initializingChunkBlockedModel) {
|
@@ -3768,6 +4544,10 @@ function createModelResolver(chunk, parentObject, key, cyclic, response, map) {
|
|
3768
4544
|
}
|
3769
4545
|
|
3770
4546
|
return function (value) {
|
4547
|
+
for (var i = 1; i < path.length; i++) {
|
4548
|
+
value = value[path[i]];
|
4549
|
+
}
|
4550
|
+
|
3771
4551
|
parentObject[key] = map(response, value); // If this is the root object for a model reference, where `blocked.value`
|
3772
4552
|
// is a stale `null`, the resolved value can be used directly.
|
3773
4553
|
|
@@ -3800,7 +4580,9 @@ function createModelReject(chunk) {
|
|
3800
4580
|
};
|
3801
4581
|
}
|
3802
4582
|
|
3803
|
-
function getOutlinedModel(response,
|
4583
|
+
function getOutlinedModel(response, reference, parentObject, key, map) {
|
4584
|
+
var path = reference.split(':');
|
4585
|
+
var id = parseInt(path[0], 16);
|
3804
4586
|
var chunk = getChunk(response, id);
|
3805
4587
|
|
3806
4588
|
switch (chunk.status) {
|
@@ -3812,12 +4594,19 @@ function getOutlinedModel(response, id, parentObject, key, map) {
|
|
3812
4594
|
|
3813
4595
|
switch (chunk.status) {
|
3814
4596
|
case INITIALIZED:
|
3815
|
-
|
4597
|
+
var value = chunk.value;
|
4598
|
+
|
4599
|
+
for (var i = 1; i < path.length; i++) {
|
4600
|
+
value = value[path[i]];
|
4601
|
+
}
|
4602
|
+
|
4603
|
+
return map(response, value);
|
3816
4604
|
|
3817
4605
|
case PENDING:
|
3818
4606
|
case BLOCKED:
|
4607
|
+
case CYCLIC:
|
3819
4608
|
var parentChunk = initializingChunk;
|
3820
|
-
chunk.then(createModelResolver(parentChunk, parentObject, key,
|
4609
|
+
chunk.then(createModelResolver(parentChunk, parentObject, key, chunk.status === CYCLIC, response, map, path), createModelReject(parentChunk));
|
3821
4610
|
return null;
|
3822
4611
|
|
3823
4612
|
default:
|
@@ -3842,7 +4631,220 @@ function createModel(response, model) {
|
|
3842
4631
|
return model;
|
3843
4632
|
}
|
3844
4633
|
|
3845
|
-
function
|
4634
|
+
function parseTypedArray(response, reference, constructor, bytesPerElement, parentObject, parentKey) {
|
4635
|
+
var id = parseInt(reference.slice(2), 16);
|
4636
|
+
var prefix = response._prefix;
|
4637
|
+
var key = prefix + id; // We should have this backingEntry in the store already because we emitted
|
4638
|
+
// it before referencing it. It should be a Blob.
|
4639
|
+
|
4640
|
+
var backingEntry = response._formData.get(key);
|
4641
|
+
|
4642
|
+
var promise = constructor === ArrayBuffer ? backingEntry.arrayBuffer() : backingEntry.arrayBuffer().then(function (buffer) {
|
4643
|
+
return new constructor(buffer);
|
4644
|
+
}); // Since loading the buffer is an async operation we'll be blocking the parent
|
4645
|
+
// chunk.
|
4646
|
+
|
4647
|
+
var parentChunk = initializingChunk;
|
4648
|
+
promise.then(createModelResolver(parentChunk, parentObject, parentKey, false, response, createModel, []), createModelReject(parentChunk));
|
4649
|
+
return null;
|
4650
|
+
}
|
4651
|
+
|
4652
|
+
function resolveStream(response, id, stream, controller) {
|
4653
|
+
var chunks = response._chunks;
|
4654
|
+
var chunk = createInitializedStreamChunk(response, stream, controller);
|
4655
|
+
chunks.set(id, chunk);
|
4656
|
+
var prefix = response._prefix;
|
4657
|
+
var key = prefix + id;
|
4658
|
+
|
4659
|
+
var existingEntries = response._formData.getAll(key);
|
4660
|
+
|
4661
|
+
for (var i = 0; i < existingEntries.length; i++) {
|
4662
|
+
// We assume that this is a string entry for now.
|
4663
|
+
var value = existingEntries[i];
|
4664
|
+
|
4665
|
+
if (value[0] === 'C') {
|
4666
|
+
controller.close(value === 'C' ? '"$undefined"' : value.slice(1));
|
4667
|
+
} else {
|
4668
|
+
controller.enqueueModel(value);
|
4669
|
+
}
|
4670
|
+
}
|
4671
|
+
}
|
4672
|
+
|
4673
|
+
function parseReadableStream(response, reference, type, parentObject, parentKey) {
|
4674
|
+
var id = parseInt(reference.slice(2), 16);
|
4675
|
+
var controller = null;
|
4676
|
+
var stream = new ReadableStream({
|
4677
|
+
type: type,
|
4678
|
+
start: function (c) {
|
4679
|
+
controller = c;
|
4680
|
+
}
|
4681
|
+
});
|
4682
|
+
var previousBlockedChunk = null;
|
4683
|
+
var flightController = {
|
4684
|
+
enqueueModel: function (json) {
|
4685
|
+
if (previousBlockedChunk === null) {
|
4686
|
+
// If we're not blocked on any other chunks, we can try to eagerly initialize
|
4687
|
+
// this as a fast-path to avoid awaiting them.
|
4688
|
+
var chunk = createResolvedModelChunk(response, json, -1);
|
4689
|
+
initializeModelChunk(chunk);
|
4690
|
+
var initializedChunk = chunk;
|
4691
|
+
|
4692
|
+
if (initializedChunk.status === INITIALIZED) {
|
4693
|
+
controller.enqueue(initializedChunk.value);
|
4694
|
+
} else {
|
4695
|
+
chunk.then(function (v) {
|
4696
|
+
return controller.enqueue(v);
|
4697
|
+
}, function (e) {
|
4698
|
+
return controller.error(e);
|
4699
|
+
});
|
4700
|
+
previousBlockedChunk = chunk;
|
4701
|
+
}
|
4702
|
+
} else {
|
4703
|
+
// We're still waiting on a previous chunk so we can't enqueue quite yet.
|
4704
|
+
var blockedChunk = previousBlockedChunk;
|
4705
|
+
|
4706
|
+
var _chunk = createPendingChunk(response);
|
4707
|
+
|
4708
|
+
_chunk.then(function (v) {
|
4709
|
+
return controller.enqueue(v);
|
4710
|
+
}, function (e) {
|
4711
|
+
return controller.error(e);
|
4712
|
+
});
|
4713
|
+
|
4714
|
+
previousBlockedChunk = _chunk;
|
4715
|
+
blockedChunk.then(function () {
|
4716
|
+
if (previousBlockedChunk === _chunk) {
|
4717
|
+
// We were still the last chunk so we can now clear the queue and return
|
4718
|
+
// to synchronous emitting.
|
4719
|
+
previousBlockedChunk = null;
|
4720
|
+
}
|
4721
|
+
|
4722
|
+
resolveModelChunk(_chunk, json, -1);
|
4723
|
+
});
|
4724
|
+
}
|
4725
|
+
},
|
4726
|
+
close: function (json) {
|
4727
|
+
if (previousBlockedChunk === null) {
|
4728
|
+
controller.close();
|
4729
|
+
} else {
|
4730
|
+
var blockedChunk = previousBlockedChunk; // We shouldn't get any more enqueues after this so we can set it back to null.
|
4731
|
+
|
4732
|
+
previousBlockedChunk = null;
|
4733
|
+
blockedChunk.then(function () {
|
4734
|
+
return controller.close();
|
4735
|
+
});
|
4736
|
+
}
|
4737
|
+
},
|
4738
|
+
error: function (error) {
|
4739
|
+
if (previousBlockedChunk === null) {
|
4740
|
+
// $FlowFixMe[incompatible-call]
|
4741
|
+
controller.error(error);
|
4742
|
+
} else {
|
4743
|
+
var blockedChunk = previousBlockedChunk; // We shouldn't get any more enqueues after this so we can set it back to null.
|
4744
|
+
|
4745
|
+
previousBlockedChunk = null;
|
4746
|
+
blockedChunk.then(function () {
|
4747
|
+
return controller.error(error);
|
4748
|
+
});
|
4749
|
+
}
|
4750
|
+
}
|
4751
|
+
};
|
4752
|
+
resolveStream(response, id, stream, flightController);
|
4753
|
+
return stream;
|
4754
|
+
}
|
4755
|
+
|
4756
|
+
function asyncIterator() {
|
4757
|
+
// Self referencing iterator.
|
4758
|
+
return this;
|
4759
|
+
}
|
4760
|
+
|
4761
|
+
function createIterator(next) {
|
4762
|
+
var iterator = {
|
4763
|
+
next: next // TODO: Add return/throw as options for aborting.
|
4764
|
+
|
4765
|
+
}; // TODO: The iterator could inherit the AsyncIterator prototype which is not exposed as
|
4766
|
+
// a global but exists as a prototype of an AsyncGenerator. However, it's not needed
|
4767
|
+
// to satisfy the iterable protocol.
|
4768
|
+
|
4769
|
+
iterator[ASYNC_ITERATOR] = asyncIterator;
|
4770
|
+
return iterator;
|
4771
|
+
}
|
4772
|
+
|
4773
|
+
function parseAsyncIterable(response, reference, iterator, parentObject, parentKey) {
|
4774
|
+
var id = parseInt(reference.slice(2), 16);
|
4775
|
+
var buffer = [];
|
4776
|
+
var closed = false;
|
4777
|
+
var nextWriteIndex = 0;
|
4778
|
+
var flightController = {
|
4779
|
+
enqueueModel: function (value) {
|
4780
|
+
if (nextWriteIndex === buffer.length) {
|
4781
|
+
buffer[nextWriteIndex] = createResolvedIteratorResultChunk(response, value, false);
|
4782
|
+
} else {
|
4783
|
+
resolveIteratorResultChunk(buffer[nextWriteIndex], value, false);
|
4784
|
+
}
|
4785
|
+
|
4786
|
+
nextWriteIndex++;
|
4787
|
+
},
|
4788
|
+
close: function (value) {
|
4789
|
+
closed = true;
|
4790
|
+
|
4791
|
+
if (nextWriteIndex === buffer.length) {
|
4792
|
+
buffer[nextWriteIndex] = createResolvedIteratorResultChunk(response, value, true);
|
4793
|
+
} else {
|
4794
|
+
resolveIteratorResultChunk(buffer[nextWriteIndex], value, true);
|
4795
|
+
}
|
4796
|
+
|
4797
|
+
nextWriteIndex++;
|
4798
|
+
|
4799
|
+
while (nextWriteIndex < buffer.length) {
|
4800
|
+
// In generators, any extra reads from the iterator have the value undefined.
|
4801
|
+
resolveIteratorResultChunk(buffer[nextWriteIndex++], '"$undefined"', true);
|
4802
|
+
}
|
4803
|
+
},
|
4804
|
+
error: function (error) {
|
4805
|
+
closed = true;
|
4806
|
+
|
4807
|
+
if (nextWriteIndex === buffer.length) {
|
4808
|
+
buffer[nextWriteIndex] = createPendingChunk(response);
|
4809
|
+
}
|
4810
|
+
|
4811
|
+
while (nextWriteIndex < buffer.length) {
|
4812
|
+
triggerErrorOnChunk(buffer[nextWriteIndex++], error);
|
4813
|
+
}
|
4814
|
+
}
|
4815
|
+
};
|
4816
|
+
|
4817
|
+
var iterable = _defineProperty({}, ASYNC_ITERATOR, function () {
|
4818
|
+
var nextReadIndex = 0;
|
4819
|
+
return createIterator(function (arg) {
|
4820
|
+
if (arg !== undefined) {
|
4821
|
+
throw new Error('Values cannot be passed to next() of AsyncIterables passed to Client Components.');
|
4822
|
+
}
|
4823
|
+
|
4824
|
+
if (nextReadIndex === buffer.length) {
|
4825
|
+
if (closed) {
|
4826
|
+
// $FlowFixMe[invalid-constructor] Flow doesn't support functions as constructors
|
4827
|
+
return new Chunk(INITIALIZED, {
|
4828
|
+
done: true,
|
4829
|
+
value: undefined
|
4830
|
+
}, null, response);
|
4831
|
+
}
|
4832
|
+
|
4833
|
+
buffer[nextReadIndex] = createPendingChunk(response);
|
4834
|
+
}
|
4835
|
+
|
4836
|
+
return buffer[nextReadIndex++];
|
4837
|
+
});
|
4838
|
+
}); // TODO: If it's a single shot iterator we can optimize memory by cleaning up the buffer after
|
4839
|
+
// reading through the end, but currently we favor code size over this optimization.
|
4840
|
+
|
4841
|
+
|
4842
|
+
var stream = iterator ? iterable[ASYNC_ITERATOR]() : iterable;
|
4843
|
+
resolveStream(response, id, stream, flightController);
|
4844
|
+
return stream;
|
4845
|
+
}
|
4846
|
+
|
4847
|
+
function parseModelString(response, obj, key, value, reference) {
|
3846
4848
|
if (value[0] === '$') {
|
3847
4849
|
switch (value[1]) {
|
3848
4850
|
case '$':
|
@@ -3854,42 +4856,45 @@ function parseModelString(response, obj, key, value) {
|
|
3854
4856
|
case '@':
|
3855
4857
|
{
|
3856
4858
|
// Promise
|
3857
|
-
var
|
3858
|
-
|
3859
|
-
var chunk = getChunk(response, _id);
|
4859
|
+
var id = parseInt(value.slice(2), 16);
|
4860
|
+
var chunk = getChunk(response, id);
|
3860
4861
|
return chunk;
|
3861
4862
|
}
|
3862
4863
|
|
3863
4864
|
case 'F':
|
3864
4865
|
{
|
3865
4866
|
// Server Reference
|
3866
|
-
var
|
4867
|
+
var _ref2 = value.slice(2); // TODO: Just encode this in the reference inline instead of as a model.
|
3867
4868
|
|
3868
4869
|
|
3869
|
-
var metaData = getOutlinedModel(response,
|
4870
|
+
var metaData = getOutlinedModel(response, _ref2, obj, key, createModel);
|
3870
4871
|
return loadServerReference$1(response, metaData.id, metaData.bound, initializingChunk, obj, key);
|
3871
4872
|
}
|
3872
4873
|
|
3873
4874
|
case 'T':
|
3874
4875
|
{
|
3875
4876
|
// Temporary Reference
|
3876
|
-
|
4877
|
+
if (reference === undefined || response._temporaryReferences === undefined) {
|
4878
|
+
throw new Error('Could not reference an opaque temporary reference. ' + 'This is likely due to misconfiguring the temporaryReferences options ' + 'on the server.');
|
4879
|
+
}
|
4880
|
+
|
4881
|
+
return createTemporaryReference(response._temporaryReferences, reference);
|
3877
4882
|
}
|
3878
4883
|
|
3879
4884
|
case 'Q':
|
3880
4885
|
{
|
3881
4886
|
// Map
|
3882
|
-
var
|
4887
|
+
var _ref3 = value.slice(2);
|
3883
4888
|
|
3884
|
-
return getOutlinedModel(response,
|
4889
|
+
return getOutlinedModel(response, _ref3, obj, key, createMap);
|
3885
4890
|
}
|
3886
4891
|
|
3887
4892
|
case 'W':
|
3888
4893
|
{
|
3889
4894
|
// Set
|
3890
|
-
var
|
4895
|
+
var _ref4 = value.slice(2);
|
3891
4896
|
|
3892
|
-
return getOutlinedModel(response,
|
4897
|
+
return getOutlinedModel(response, _ref4, obj, key, createSet);
|
3893
4898
|
}
|
3894
4899
|
|
3895
4900
|
case 'K':
|
@@ -3914,9 +4919,9 @@ function parseModelString(response, obj, key, value) {
|
|
3914
4919
|
case 'i':
|
3915
4920
|
{
|
3916
4921
|
// Iterator
|
3917
|
-
var
|
4922
|
+
var _ref5 = value.slice(2);
|
3918
4923
|
|
3919
|
-
return getOutlinedModel(response,
|
4924
|
+
return getOutlinedModel(response, _ref5, obj, key, extractIterator);
|
3920
4925
|
}
|
3921
4926
|
|
3922
4927
|
case 'I':
|
@@ -3961,30 +4966,104 @@ function parseModelString(response, obj, key, value) {
|
|
3961
4966
|
}
|
3962
4967
|
}
|
3963
4968
|
|
4969
|
+
{
|
4970
|
+
switch (value[1]) {
|
4971
|
+
case 'A':
|
4972
|
+
return parseTypedArray(response, value, ArrayBuffer, 1, obj, key);
|
4973
|
+
|
4974
|
+
case 'O':
|
4975
|
+
return parseTypedArray(response, value, Int8Array, 1, obj, key);
|
4976
|
+
|
4977
|
+
case 'o':
|
4978
|
+
return parseTypedArray(response, value, Uint8Array, 1, obj, key);
|
4979
|
+
|
4980
|
+
case 'U':
|
4981
|
+
return parseTypedArray(response, value, Uint8ClampedArray, 1, obj, key);
|
4982
|
+
|
4983
|
+
case 'S':
|
4984
|
+
return parseTypedArray(response, value, Int16Array, 2, obj, key);
|
4985
|
+
|
4986
|
+
case 's':
|
4987
|
+
return parseTypedArray(response, value, Uint16Array, 2, obj, key);
|
4988
|
+
|
4989
|
+
case 'L':
|
4990
|
+
return parseTypedArray(response, value, Int32Array, 4, obj, key);
|
4991
|
+
|
4992
|
+
case 'l':
|
4993
|
+
return parseTypedArray(response, value, Uint32Array, 4, obj, key);
|
4994
|
+
|
4995
|
+
case 'G':
|
4996
|
+
return parseTypedArray(response, value, Float32Array, 4, obj, key);
|
4997
|
+
|
4998
|
+
case 'g':
|
4999
|
+
return parseTypedArray(response, value, Float64Array, 8, obj, key);
|
5000
|
+
|
5001
|
+
case 'M':
|
5002
|
+
return parseTypedArray(response, value, BigInt64Array, 8, obj, key);
|
5003
|
+
|
5004
|
+
case 'm':
|
5005
|
+
return parseTypedArray(response, value, BigUint64Array, 8, obj, key);
|
5006
|
+
|
5007
|
+
case 'V':
|
5008
|
+
return parseTypedArray(response, value, DataView, 1, obj, key);
|
5009
|
+
|
5010
|
+
case 'B':
|
5011
|
+
{
|
5012
|
+
// Blob
|
5013
|
+
var _id = parseInt(value.slice(2), 16);
|
5014
|
+
|
5015
|
+
var prefix = response._prefix;
|
5016
|
+
var blobKey = prefix + _id; // We should have this backingEntry in the store already because we emitted
|
5017
|
+
// it before referencing it. It should be a Blob.
|
5018
|
+
|
5019
|
+
var backingEntry = response._formData.get(blobKey);
|
5020
|
+
|
5021
|
+
return backingEntry;
|
5022
|
+
}
|
5023
|
+
}
|
5024
|
+
}
|
5025
|
+
|
5026
|
+
{
|
5027
|
+
switch (value[1]) {
|
5028
|
+
case 'R':
|
5029
|
+
{
|
5030
|
+
return parseReadableStream(response, value, undefined);
|
5031
|
+
}
|
3964
5032
|
|
3965
|
-
|
3966
|
-
|
5033
|
+
case 'r':
|
5034
|
+
{
|
5035
|
+
return parseReadableStream(response, value, 'bytes');
|
5036
|
+
}
|
5037
|
+
|
5038
|
+
case 'X':
|
5039
|
+
{
|
5040
|
+
return parseAsyncIterable(response, value, false);
|
5041
|
+
}
|
5042
|
+
|
5043
|
+
case 'x':
|
5044
|
+
{
|
5045
|
+
return parseAsyncIterable(response, value, true);
|
5046
|
+
}
|
5047
|
+
}
|
5048
|
+
} // We assume that anything else is a reference ID.
|
5049
|
+
|
5050
|
+
|
5051
|
+
var ref = value.slice(1);
|
5052
|
+
return getOutlinedModel(response, ref, obj, key, createModel);
|
3967
5053
|
}
|
3968
5054
|
|
3969
5055
|
return value;
|
3970
5056
|
}
|
3971
5057
|
|
3972
|
-
function createResponse(bundlerConfig, formFieldPrefix) {
|
3973
|
-
var backingFormData = arguments.length >
|
5058
|
+
function createResponse(bundlerConfig, formFieldPrefix, temporaryReferences) {
|
5059
|
+
var backingFormData = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : new FormData();
|
3974
5060
|
var chunks = new Map();
|
3975
5061
|
var response = {
|
3976
5062
|
_bundlerConfig: bundlerConfig,
|
3977
5063
|
_prefix: formFieldPrefix,
|
3978
5064
|
_formData: backingFormData,
|
3979
5065
|
_chunks: chunks,
|
3980
|
-
|
3981
|
-
if (typeof value === 'string') {
|
3982
|
-
// We can't use .bind here because we need the "this" value.
|
3983
|
-
return parseModelString(response, this, key, value);
|
3984
|
-
}
|
3985
|
-
|
3986
|
-
return value;
|
3987
|
-
}
|
5066
|
+
_temporaryReferences: temporaryReferences
|
3988
5067
|
};
|
3989
5068
|
return response;
|
3990
5069
|
}
|
@@ -4024,7 +5103,7 @@ function loadServerReference(bundlerConfig, id, bound) {
|
|
4024
5103
|
|
4025
5104
|
function decodeBoundActionMetaData(body, serverManifest, formFieldPrefix) {
|
4026
5105
|
// The data for this reference is encoded in multiple fields under this prefix.
|
4027
|
-
var actionResponse = createResponse(serverManifest, formFieldPrefix, body);
|
5106
|
+
var actionResponse = createResponse(serverManifest, formFieldPrefix, undefined, body);
|
4028
5107
|
close(actionResponse);
|
4029
5108
|
var refPromise = getRoot(actionResponse); // Force it to initialize
|
4030
5109
|
// $FlowFixMe
|
@@ -4119,7 +5198,7 @@ function decodeFormState(actionResult, body, serverManifest) {
|
|
4119
5198
|
}
|
4120
5199
|
|
4121
5200
|
function renderToReadableStream(model, webpackMap, options) {
|
4122
|
-
var request = createRequest(model, webpackMap, options ? options.onError : undefined, options ? options.identifierPrefix : undefined, options ? options.onPostpone : undefined, options ? options.environmentName : undefined);
|
5201
|
+
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);
|
4123
5202
|
|
4124
5203
|
if (options && options.signal) {
|
4125
5204
|
var signal = options.signal;
|
@@ -4155,20 +5234,21 @@ function renderToReadableStream(model, webpackMap, options) {
|
|
4155
5234
|
return stream;
|
4156
5235
|
}
|
4157
5236
|
|
4158
|
-
function decodeReply(body, webpackMap) {
|
5237
|
+
function decodeReply(body, webpackMap, options) {
|
4159
5238
|
if (typeof body === 'string') {
|
4160
5239
|
var form = new FormData();
|
4161
5240
|
form.append('0', body);
|
4162
5241
|
body = form;
|
4163
5242
|
}
|
4164
5243
|
|
4165
|
-
var response = createResponse(webpackMap, '', body);
|
5244
|
+
var response = createResponse(webpackMap, '', options ? options.temporaryReferences : undefined, body);
|
4166
5245
|
var root = getRoot(response);
|
4167
5246
|
close(response);
|
4168
5247
|
return root;
|
4169
5248
|
}
|
4170
5249
|
|
4171
5250
|
exports.createClientModuleProxy = createClientModuleProxy;
|
5251
|
+
exports.createTemporaryReferenceSet = createTemporaryReferenceSet;
|
4172
5252
|
exports.decodeAction = decodeAction;
|
4173
5253
|
exports.decodeFormState = decodeFormState;
|
4174
5254
|
exports.decodeReply = decodeReply;
|