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') {
|
@@ -770,11 +783,14 @@ var componentStorage = null;
|
|
770
783
|
|
771
784
|
var TEMPORARY_REFERENCE_TAG = Symbol.for('react.temporary.reference'); // eslint-disable-next-line no-unused-vars
|
772
785
|
|
773
|
-
function
|
786
|
+
function createTemporaryReferenceSet() {
|
787
|
+
return new WeakMap();
|
788
|
+
}
|
789
|
+
function isOpaqueTemporaryReference(reference) {
|
774
790
|
return reference.$$typeof === TEMPORARY_REFERENCE_TAG;
|
775
791
|
}
|
776
|
-
function
|
777
|
-
return temporaryReference
|
792
|
+
function resolveTemporaryReference(temporaryReferences, temporaryReference) {
|
793
|
+
return temporaryReferences.get(temporaryReference);
|
778
794
|
}
|
779
795
|
var proxyHandlers = {
|
780
796
|
get: function (target, name, receiver) {
|
@@ -785,12 +801,6 @@ var proxyHandlers = {
|
|
785
801
|
// have the Flight runtime extract the inner target instead.
|
786
802
|
return target.$$typeof;
|
787
803
|
|
788
|
-
case '$$id':
|
789
|
-
return target.$$id;
|
790
|
-
|
791
|
-
case '$$async':
|
792
|
-
return target.$$async;
|
793
|
-
|
794
804
|
case 'name':
|
795
805
|
return undefined;
|
796
806
|
|
@@ -825,21 +835,28 @@ var proxyHandlers = {
|
|
825
835
|
throw new Error('Cannot assign to a temporary client reference from a server module.');
|
826
836
|
}
|
827
837
|
};
|
828
|
-
function createTemporaryReference(id) {
|
838
|
+
function createTemporaryReference(temporaryReferences, id) {
|
829
839
|
var reference = Object.defineProperties(function () {
|
830
840
|
throw new Error( // eslint-disable-next-line react-internal/safe-string-coercion
|
831
841
|
"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.");
|
832
842
|
}, {
|
833
843
|
$$typeof: {
|
834
844
|
value: TEMPORARY_REFERENCE_TAG
|
835
|
-
},
|
836
|
-
$$id: {
|
837
|
-
value: id
|
838
845
|
}
|
839
846
|
});
|
840
|
-
|
847
|
+
var wrapper = new Proxy(reference, proxyHandlers);
|
848
|
+
registerTemporaryReference(temporaryReferences, wrapper, id);
|
849
|
+
return wrapper;
|
841
850
|
}
|
851
|
+
function registerTemporaryReference(temporaryReferences, object, id) {
|
852
|
+
temporaryReferences.set(object, id);
|
853
|
+
}
|
854
|
+
|
855
|
+
// When adding new symbols to this file,
|
856
|
+
// Please consider also adding to 'react-devtools-shared/src/backend/ReactSymbols'
|
857
|
+
// The Symbol used to tag the ReactElement-like types.
|
842
858
|
|
859
|
+
var REACT_LEGACY_ELEMENT_TYPE = Symbol.for('react.element');
|
843
860
|
var REACT_ELEMENT_TYPE = Symbol.for('react.transitional.element') ;
|
844
861
|
var REACT_FRAGMENT_TYPE = Symbol.for('react.fragment');
|
845
862
|
var REACT_CONTEXT_TYPE = Symbol.for('react.context');
|
@@ -865,6 +882,7 @@ function getIteratorFn(maybeIterable) {
|
|
865
882
|
|
866
883
|
return null;
|
867
884
|
}
|
885
|
+
var ASYNC_ITERATOR = Symbol.asyncIterator;
|
868
886
|
|
869
887
|
// Corresponds to ReactFiberWakeable and ReactFizzWakeable modules. Generally,
|
870
888
|
// changes to one module should be reflected in the others.
|
@@ -1500,10 +1518,7 @@ var stringify = JSON.stringify; // Serializable values
|
|
1500
1518
|
var PENDING$1 = 0;
|
1501
1519
|
var COMPLETED = 1;
|
1502
1520
|
var ABORTED = 3;
|
1503
|
-
var ERRORED$1 = 4;
|
1504
|
-
|
1505
|
-
var SEEN_BUT_NOT_YET_OUTLINED = -1;
|
1506
|
-
var NEVER_OUTLINED = -2;
|
1521
|
+
var ERRORED$1 = 4;
|
1507
1522
|
|
1508
1523
|
function defaultErrorHandler(error) {
|
1509
1524
|
console['error'](error); // Don't transform to our wrapper
|
@@ -1515,7 +1530,7 @@ function defaultPostponeHandler(reason) {// Noop
|
|
1515
1530
|
var OPEN = 0;
|
1516
1531
|
var CLOSING = 1;
|
1517
1532
|
var CLOSED = 2;
|
1518
|
-
function createRequest(model, bundlerConfig, onError, identifierPrefix, onPostpone, environmentName) {
|
1533
|
+
function createRequest(model, bundlerConfig, onError, identifierPrefix, onPostpone, environmentName, temporaryReferences) {
|
1519
1534
|
if (ReactSharedInternals.A !== null && ReactSharedInternals.A !== DefaultAsyncDispatcher) {
|
1520
1535
|
throw new Error('Currently React only supports one RSC renderer at a time.');
|
1521
1536
|
}
|
@@ -1547,6 +1562,7 @@ function createRequest(model, bundlerConfig, onError, identifierPrefix, onPostpo
|
|
1547
1562
|
writtenClientReferences: new Map(),
|
1548
1563
|
writtenServerReferences: new Map(),
|
1549
1564
|
writtenObjects: new WeakMap(),
|
1565
|
+
temporaryReferences: temporaryReferences,
|
1550
1566
|
identifierPrefix: identifierPrefix || '',
|
1551
1567
|
identifierCount: 1,
|
1552
1568
|
taintCleanupQueue: cleanupQueue,
|
@@ -1649,6 +1665,192 @@ function serializeThenable(request, task, thenable) {
|
|
1649
1665
|
return newTask.id;
|
1650
1666
|
}
|
1651
1667
|
|
1668
|
+
function serializeReadableStream(request, task, stream) {
|
1669
|
+
// Detect if this is a BYOB stream. BYOB streams should be able to be read as bytes on the
|
1670
|
+
// receiving side. It also implies that different chunks can be split up or merged as opposed
|
1671
|
+
// to a readable stream that happens to have Uint8Array as the type which might expect it to be
|
1672
|
+
// received in the same slices.
|
1673
|
+
// $FlowFixMe: This is a Node.js extension.
|
1674
|
+
var supportsBYOB = stream.supportsBYOB;
|
1675
|
+
|
1676
|
+
if (supportsBYOB === undefined) {
|
1677
|
+
try {
|
1678
|
+
// $FlowFixMe[extra-arg]: This argument is accepted.
|
1679
|
+
stream.getReader({
|
1680
|
+
mode: 'byob'
|
1681
|
+
}).releaseLock();
|
1682
|
+
supportsBYOB = true;
|
1683
|
+
} catch (x) {
|
1684
|
+
supportsBYOB = false;
|
1685
|
+
}
|
1686
|
+
}
|
1687
|
+
|
1688
|
+
var reader = stream.getReader(); // This task won't actually be retried. We just use it to attempt synchronous renders.
|
1689
|
+
|
1690
|
+
var streamTask = createTask(request, task.model, task.keyPath, task.implicitSlot, request.abortableTasks);
|
1691
|
+
request.abortableTasks.delete(streamTask);
|
1692
|
+
request.pendingChunks++; // The task represents the Start row. This adds a Stop row.
|
1693
|
+
|
1694
|
+
var startStreamRow = streamTask.id.toString(16) + ':' + (supportsBYOB ? 'r' : 'R') + '\n';
|
1695
|
+
request.completedRegularChunks.push(stringToChunk(startStreamRow)); // There's a race condition between when the stream is aborted and when the promise
|
1696
|
+
// resolves so we track whether we already aborted it to avoid writing twice.
|
1697
|
+
|
1698
|
+
var aborted = false;
|
1699
|
+
|
1700
|
+
function progress(entry) {
|
1701
|
+
if (aborted) {
|
1702
|
+
return;
|
1703
|
+
}
|
1704
|
+
|
1705
|
+
if (entry.done) {
|
1706
|
+
request.abortListeners.delete(error);
|
1707
|
+
var endStreamRow = streamTask.id.toString(16) + ':C\n';
|
1708
|
+
request.completedRegularChunks.push(stringToChunk(endStreamRow));
|
1709
|
+
enqueueFlush(request);
|
1710
|
+
aborted = true;
|
1711
|
+
} else {
|
1712
|
+
try {
|
1713
|
+
streamTask.model = entry.value;
|
1714
|
+
request.pendingChunks++;
|
1715
|
+
tryStreamTask(request, streamTask);
|
1716
|
+
enqueueFlush(request);
|
1717
|
+
reader.read().then(progress, error);
|
1718
|
+
} catch (x) {
|
1719
|
+
error(x);
|
1720
|
+
}
|
1721
|
+
}
|
1722
|
+
}
|
1723
|
+
|
1724
|
+
function error(reason) {
|
1725
|
+
if (aborted) {
|
1726
|
+
return;
|
1727
|
+
}
|
1728
|
+
|
1729
|
+
aborted = true;
|
1730
|
+
request.abortListeners.delete(error);
|
1731
|
+
|
1732
|
+
{
|
1733
|
+
var digest = logRecoverableError(request, reason);
|
1734
|
+
emitErrorChunk(request, streamTask.id, digest, reason);
|
1735
|
+
}
|
1736
|
+
|
1737
|
+
enqueueFlush(request); // $FlowFixMe should be able to pass mixed
|
1738
|
+
|
1739
|
+
reader.cancel(reason).then(error, error);
|
1740
|
+
}
|
1741
|
+
|
1742
|
+
request.abortListeners.add(error);
|
1743
|
+
reader.read().then(progress, error);
|
1744
|
+
return serializeByValueID(streamTask.id);
|
1745
|
+
} // This indirect exists so we can exclude its stack frame in DEV (and anything below it).
|
1746
|
+
|
1747
|
+
/** @noinline */
|
1748
|
+
|
1749
|
+
|
1750
|
+
function callIteratorInDEV(iterator, progress, error) {
|
1751
|
+
iterator.next().then(progress, error);
|
1752
|
+
}
|
1753
|
+
|
1754
|
+
function serializeAsyncIterable(request, task, iterable, iterator) {
|
1755
|
+
// Generators/Iterators are Iterables but they're also their own iterator
|
1756
|
+
// functions. If that's the case, we treat them as single-shot. Otherwise,
|
1757
|
+
// we assume that this iterable might be a multi-shot and allow it to be
|
1758
|
+
// iterated more than once on the client.
|
1759
|
+
var isIterator = iterable === iterator; // 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) + ':' + (isIterator ? 'x' : 'X') + '\n';
|
1766
|
+
request.completedRegularChunks.push(stringToChunk(startStreamRow));
|
1767
|
+
|
1768
|
+
{
|
1769
|
+
var debugInfo = iterable._debugInfo;
|
1770
|
+
|
1771
|
+
if (debugInfo) {
|
1772
|
+
forwardDebugInfo(request, streamTask.id, debugInfo);
|
1773
|
+
}
|
1774
|
+
} // There's a race condition between when the stream is aborted and when the promise
|
1775
|
+
// resolves so we track whether we already aborted it to avoid writing twice.
|
1776
|
+
|
1777
|
+
|
1778
|
+
var aborted = false;
|
1779
|
+
|
1780
|
+
function progress(entry) {
|
1781
|
+
if (aborted) {
|
1782
|
+
return;
|
1783
|
+
}
|
1784
|
+
|
1785
|
+
if (entry.done) {
|
1786
|
+
request.abortListeners.delete(error);
|
1787
|
+
var endStreamRow;
|
1788
|
+
|
1789
|
+
if (entry.value === undefined) {
|
1790
|
+
endStreamRow = streamTask.id.toString(16) + ':C\n';
|
1791
|
+
} else {
|
1792
|
+
// Unlike streams, the last value may not be undefined. If it's not
|
1793
|
+
// we outline it and encode a reference to it in the closing instruction.
|
1794
|
+
try {
|
1795
|
+
var chunkId = outlineModel(request, entry.value);
|
1796
|
+
endStreamRow = streamTask.id.toString(16) + ':C' + stringify(serializeByValueID(chunkId)) + '\n';
|
1797
|
+
} catch (x) {
|
1798
|
+
error(x);
|
1799
|
+
return;
|
1800
|
+
}
|
1801
|
+
}
|
1802
|
+
|
1803
|
+
request.completedRegularChunks.push(stringToChunk(endStreamRow));
|
1804
|
+
enqueueFlush(request);
|
1805
|
+
aborted = true;
|
1806
|
+
} else {
|
1807
|
+
try {
|
1808
|
+
streamTask.model = entry.value;
|
1809
|
+
request.pendingChunks++;
|
1810
|
+
tryStreamTask(request, streamTask);
|
1811
|
+
enqueueFlush(request);
|
1812
|
+
|
1813
|
+
if (true) {
|
1814
|
+
callIteratorInDEV(iterator, progress, error);
|
1815
|
+
}
|
1816
|
+
} catch (x) {
|
1817
|
+
error(x);
|
1818
|
+
return;
|
1819
|
+
}
|
1820
|
+
}
|
1821
|
+
}
|
1822
|
+
|
1823
|
+
function error(reason) {
|
1824
|
+
if (aborted) {
|
1825
|
+
return;
|
1826
|
+
}
|
1827
|
+
|
1828
|
+
aborted = true;
|
1829
|
+
request.abortListeners.delete(error);
|
1830
|
+
|
1831
|
+
{
|
1832
|
+
var digest = logRecoverableError(request, reason);
|
1833
|
+
emitErrorChunk(request, streamTask.id, digest, reason);
|
1834
|
+
}
|
1835
|
+
|
1836
|
+
enqueueFlush(request);
|
1837
|
+
|
1838
|
+
if (typeof iterator.throw === 'function') {
|
1839
|
+
// The iterator protocol doesn't necessarily include this but a generator do.
|
1840
|
+
// $FlowFixMe should be able to pass mixed
|
1841
|
+
iterator.throw(reason).then(error, error);
|
1842
|
+
}
|
1843
|
+
}
|
1844
|
+
|
1845
|
+
request.abortListeners.add(error);
|
1846
|
+
|
1847
|
+
{
|
1848
|
+
callIteratorInDEV(iterator, progress, error);
|
1849
|
+
}
|
1850
|
+
|
1851
|
+
return serializeByValueID(streamTask.id);
|
1852
|
+
}
|
1853
|
+
|
1652
1854
|
function emitHint(request, code, model) {
|
1653
1855
|
emitHintChunk(request, code, model);
|
1654
1856
|
enqueueFlush(request);
|
@@ -1720,16 +1922,42 @@ function createLazyWrapperAroundWakeable(wakeable) {
|
|
1720
1922
|
}
|
1721
1923
|
|
1722
1924
|
return lazyType;
|
1925
|
+
} // This indirect exists so we can exclude its stack frame in DEV (and anything below it).
|
1926
|
+
|
1927
|
+
/** @noinline */
|
1928
|
+
|
1929
|
+
|
1930
|
+
function callComponentInDEV(Component, props, componentDebugInfo) {
|
1931
|
+
// The secondArg is always undefined in Server Components since refs error early.
|
1932
|
+
var secondArg = undefined;
|
1933
|
+
setCurrentOwner(componentDebugInfo);
|
1934
|
+
|
1935
|
+
try {
|
1936
|
+
if (supportsComponentStorage) ; else {
|
1937
|
+
return Component(props, secondArg);
|
1938
|
+
}
|
1939
|
+
} finally {
|
1940
|
+
setCurrentOwner(null);
|
1941
|
+
}
|
1942
|
+
} // This indirect exists so we can exclude its stack frame in DEV (and anything below it).
|
1943
|
+
|
1944
|
+
/** @noinline */
|
1945
|
+
|
1946
|
+
|
1947
|
+
function callLazyInitInDEV(lazy) {
|
1948
|
+
var payload = lazy._payload;
|
1949
|
+
var init = lazy._init;
|
1950
|
+
return init(payload);
|
1723
1951
|
}
|
1724
1952
|
|
1725
|
-
function renderFunctionComponent(request, task, key, Component, props, owner
|
1953
|
+
function renderFunctionComponent(request, task, key, Component, props, owner, // DEV-only
|
1954
|
+
stack) // DEV-only
|
1955
|
+
{
|
1726
1956
|
// Reset the task's thenable state before continuing, so that if a later
|
1727
1957
|
// component suspends we can reuse the same task object. If the same
|
1728
1958
|
// component suspends again, the thenable state will be restored.
|
1729
1959
|
var prevThenableState = task.thenableState;
|
1730
|
-
task.thenableState = null;
|
1731
|
-
|
1732
|
-
var secondArg = undefined;
|
1960
|
+
task.thenableState = null;
|
1733
1961
|
var result;
|
1734
1962
|
var componentDebugInfo;
|
1735
1963
|
|
@@ -1752,24 +1980,17 @@ function renderFunctionComponent(request, task, key, Component, props, owner) {
|
|
1752
1980
|
name: componentName,
|
1753
1981
|
env: request.environmentName,
|
1754
1982
|
owner: owner
|
1755
|
-
};
|
1983
|
+
};
|
1756
1984
|
// If we had a smarter way to dedupe we might not have to do this if there ends up
|
1757
1985
|
// being no references to this as an owner.
|
1758
1986
|
|
1987
|
+
|
1759
1988
|
outlineModel(request, componentDebugInfo);
|
1760
1989
|
emitDebugChunk(request, componentDebugID, componentDebugInfo);
|
1761
1990
|
}
|
1762
1991
|
|
1763
1992
|
prepareToUseHooksForComponent(prevThenableState, componentDebugInfo);
|
1764
|
-
|
1765
|
-
|
1766
|
-
try {
|
1767
|
-
if (supportsComponentStorage) ; else {
|
1768
|
-
result = Component(props, secondArg);
|
1769
|
-
}
|
1770
|
-
} finally {
|
1771
|
-
setCurrentOwner(null);
|
1772
|
-
}
|
1993
|
+
result = callComponentInDEV(Component, props, componentDebugInfo);
|
1773
1994
|
}
|
1774
1995
|
|
1775
1996
|
if (typeof result === 'object' && result !== null) {
|
@@ -1821,6 +2042,33 @@ function renderFunctionComponent(request, task, key, Component, props, owner) {
|
|
1821
2042
|
{
|
1822
2043
|
result._debugInfo = iterableChild._debugInfo;
|
1823
2044
|
}
|
2045
|
+
} else if (typeof result[ASYNC_ITERATOR] === 'function' && (typeof ReadableStream !== 'function' || !(result instanceof ReadableStream))) {
|
2046
|
+
var _iterableChild = result;
|
2047
|
+
result = _defineProperty({}, ASYNC_ITERATOR, function () {
|
2048
|
+
var iterator = _iterableChild[ASYNC_ITERATOR]();
|
2049
|
+
|
2050
|
+
{
|
2051
|
+
// If this was an AsyncIterator but not an AsyncGeneratorFunction we warn because
|
2052
|
+
// it might have been a mistake. Technically you can make this mistake with
|
2053
|
+
// AsyncGeneratorFunctions and even single-shot AsyncIterables too but it's extra
|
2054
|
+
// tempting to try to return the value from a generator.
|
2055
|
+
if (iterator === _iterableChild) {
|
2056
|
+
var isGeneratorComponent = // $FlowIgnore[method-unbinding]
|
2057
|
+
Object.prototype.toString.call(Component) === '[object AsyncGeneratorFunction]' && // $FlowIgnore[method-unbinding]
|
2058
|
+
Object.prototype.toString.call(_iterableChild) === '[object AsyncGenerator]';
|
2059
|
+
|
2060
|
+
if (!isGeneratorComponent) {
|
2061
|
+
error('Returning an AsyncIterator from a Server Component is not supported ' + 'since it cannot be looped over more than once. ');
|
2062
|
+
}
|
2063
|
+
}
|
2064
|
+
}
|
2065
|
+
|
2066
|
+
return iterator;
|
2067
|
+
});
|
2068
|
+
|
2069
|
+
{
|
2070
|
+
result._debugInfo = _iterableChild._debugInfo;
|
2071
|
+
}
|
1824
2072
|
}
|
1825
2073
|
} // Track this element's key on the Server Component on the keyPath context..
|
1826
2074
|
|
@@ -1903,7 +2151,44 @@ function renderFragment(request, task, children) {
|
|
1903
2151
|
return children;
|
1904
2152
|
}
|
1905
2153
|
|
1906
|
-
function
|
2154
|
+
function renderAsyncFragment(request, task, children, getAsyncIterator) {
|
2155
|
+
if (task.keyPath !== null) {
|
2156
|
+
// We have a Server Component that specifies a key but we're now splitting
|
2157
|
+
// the tree using a fragment.
|
2158
|
+
var fragment = [REACT_ELEMENT_TYPE, REACT_FRAGMENT_TYPE, task.keyPath, {
|
2159
|
+
children: children
|
2160
|
+
}];
|
2161
|
+
|
2162
|
+
if (!task.implicitSlot) {
|
2163
|
+
// If this was keyed inside a set. I.e. the outer Server Component was keyed
|
2164
|
+
// then we need to handle reorders of the whole set. To do this we need to wrap
|
2165
|
+
// this array in a keyed Fragment.
|
2166
|
+
return fragment;
|
2167
|
+
} // If the outer Server Component was implicit but then an inner one had a key
|
2168
|
+
// we don't actually need to be able to move the whole set around. It'll always be
|
2169
|
+
// in an implicit slot. The key only exists to be able to reset the state of the
|
2170
|
+
// children. We could achieve the same effect by passing on the keyPath to the next
|
2171
|
+
// set of components inside the fragment. This would also allow a keyless fragment
|
2172
|
+
// reconcile against a single child.
|
2173
|
+
// Unfortunately because of JSON.stringify, we can't call the recursive loop for
|
2174
|
+
// each child within this context because we can't return a set with already resolved
|
2175
|
+
// values. E.g. a string would get double encoded. Returning would pop the context.
|
2176
|
+
// So instead, we wrap it with an unkeyed fragment and inner keyed fragment.
|
2177
|
+
|
2178
|
+
|
2179
|
+
return [fragment];
|
2180
|
+
} // Since we're yielding here, that implicitly resets the keyPath context on the
|
2181
|
+
// way up. Which is what we want since we've consumed it. If this changes to
|
2182
|
+
// be recursive serialization, we need to reset the keyPath and implicitSlot,
|
2183
|
+
// before recursing here.
|
2184
|
+
|
2185
|
+
|
2186
|
+
var asyncIterator = getAsyncIterator.call(children);
|
2187
|
+
return serializeAsyncIterable(request, task, children, asyncIterator);
|
2188
|
+
}
|
2189
|
+
|
2190
|
+
function renderClientElement(task, type, key, props, owner, // DEV-only
|
2191
|
+
stack) // DEV-only
|
1907
2192
|
{
|
1908
2193
|
// We prepend the terminal client element that actually gets serialized with
|
1909
2194
|
// the keys of any Server Components which are not serialized.
|
@@ -1953,7 +2238,8 @@ function outlineTask(request, task) {
|
|
1953
2238
|
return serializeLazyID(newTask.id);
|
1954
2239
|
}
|
1955
2240
|
|
1956
|
-
function renderElement(request, task, type, key, ref, props, owner
|
2241
|
+
function renderElement(request, task, type, key, ref, props, owner, // DEV only
|
2242
|
+
stack) // DEV only
|
1957
2243
|
{
|
1958
2244
|
if (ref !== null && ref !== undefined) {
|
1959
2245
|
// When the ref moves to the regular props object this will implicitly
|
@@ -1973,7 +2259,7 @@ function renderElement(request, task, type, key, ref, props, owner) // DEV only
|
|
1973
2259
|
}
|
1974
2260
|
|
1975
2261
|
if (typeof type === 'function') {
|
1976
|
-
if (isClientReference(type) ||
|
2262
|
+
if (isClientReference(type) || isOpaqueTemporaryReference(type)) {
|
1977
2263
|
// This is a reference to a Client Component.
|
1978
2264
|
return renderClientElement(task, type, key, props, owner);
|
1979
2265
|
} // This is a Server Component.
|
@@ -2010,9 +2296,12 @@ function renderElement(request, task, type, key, ref, props, owner) // DEV only
|
|
2010
2296
|
switch (type.$$typeof) {
|
2011
2297
|
case REACT_LAZY_TYPE:
|
2012
2298
|
{
|
2013
|
-
var
|
2014
|
-
|
2015
|
-
|
2299
|
+
var wrappedType;
|
2300
|
+
|
2301
|
+
{
|
2302
|
+
wrappedType = callLazyInitInDEV(type);
|
2303
|
+
}
|
2304
|
+
|
2016
2305
|
return renderElement(request, task, wrappedType, key, ref, props, owner);
|
2017
2306
|
}
|
2018
2307
|
|
@@ -2051,7 +2340,7 @@ function createTask(request, model, keyPath, implicitSlot, abortSet) {
|
|
2051
2340
|
// If we're about to write this into a new task we can assign it an ID early so that
|
2052
2341
|
// any other references can refer to the value we're about to write.
|
2053
2342
|
if (keyPath !== null || implicitSlot) ; else {
|
2054
|
-
request.writtenObjects.set(model, id);
|
2343
|
+
request.writtenObjects.set(model, serializeByValueID(id));
|
2055
2344
|
}
|
2056
2345
|
}
|
2057
2346
|
|
@@ -2114,10 +2403,6 @@ function serializeServerReferenceID(id) {
|
|
2114
2403
|
return '$F' + id.toString(16);
|
2115
2404
|
}
|
2116
2405
|
|
2117
|
-
function serializeTemporaryReferenceID(id) {
|
2118
|
-
return '$T' + id;
|
2119
|
-
}
|
2120
|
-
|
2121
2406
|
function serializeSymbolReference(name) {
|
2122
2407
|
return '$S' + name;
|
2123
2408
|
}
|
@@ -2234,9 +2519,8 @@ function serializeServerReference(request, serverReference) {
|
|
2234
2519
|
return serializeServerReferenceID(metadataId);
|
2235
2520
|
}
|
2236
2521
|
|
2237
|
-
function serializeTemporaryReference(request,
|
2238
|
-
|
2239
|
-
return serializeTemporaryReferenceID(id);
|
2522
|
+
function serializeTemporaryReference(request, reference) {
|
2523
|
+
return '$T' + reference;
|
2240
2524
|
}
|
2241
2525
|
|
2242
2526
|
function serializeLargeTextString(request, text) {
|
@@ -2248,20 +2532,6 @@ function serializeLargeTextString(request, text) {
|
|
2248
2532
|
|
2249
2533
|
function serializeMap(request, map) {
|
2250
2534
|
var entries = Array.from(map);
|
2251
|
-
|
2252
|
-
for (var i = 0; i < entries.length; i++) {
|
2253
|
-
var key = entries[i][0];
|
2254
|
-
|
2255
|
-
if (typeof key === 'object' && key !== null) {
|
2256
|
-
var writtenObjects = request.writtenObjects;
|
2257
|
-
var existingId = writtenObjects.get(key);
|
2258
|
-
|
2259
|
-
if (existingId === undefined) {
|
2260
|
-
writtenObjects.set(key, SEEN_BUT_NOT_YET_OUTLINED);
|
2261
|
-
}
|
2262
|
-
}
|
2263
|
-
}
|
2264
|
-
|
2265
2535
|
var id = outlineModel(request, entries);
|
2266
2536
|
return '$Q' + id.toString(16);
|
2267
2537
|
}
|
@@ -2274,20 +2544,6 @@ function serializeFormData(request, formData) {
|
|
2274
2544
|
|
2275
2545
|
function serializeSet(request, set) {
|
2276
2546
|
var entries = Array.from(set);
|
2277
|
-
|
2278
|
-
for (var i = 0; i < entries.length; i++) {
|
2279
|
-
var key = entries[i];
|
2280
|
-
|
2281
|
-
if (typeof key === 'object' && key !== null) {
|
2282
|
-
var writtenObjects = request.writtenObjects;
|
2283
|
-
var existingId = writtenObjects.get(key);
|
2284
|
-
|
2285
|
-
if (existingId === undefined) {
|
2286
|
-
writtenObjects.set(key, SEEN_BUT_NOT_YET_OUTLINED);
|
2287
|
-
}
|
2288
|
-
}
|
2289
|
-
}
|
2290
|
-
|
2291
2547
|
var id = outlineModel(request, entries);
|
2292
2548
|
return '$W' + id.toString(16);
|
2293
2549
|
}
|
@@ -2297,6 +2553,58 @@ function serializeIterator(request, iterator) {
|
|
2297
2553
|
return '$i' + id.toString(16);
|
2298
2554
|
}
|
2299
2555
|
|
2556
|
+
function serializeTypedArray(request, tag, typedArray) {
|
2557
|
+
request.pendingChunks++;
|
2558
|
+
var bufferId = request.nextChunkId++;
|
2559
|
+
emitTypedArrayChunk(request, bufferId, tag, typedArray);
|
2560
|
+
return serializeByValueID(bufferId);
|
2561
|
+
}
|
2562
|
+
|
2563
|
+
function serializeBlob(request, blob) {
|
2564
|
+
var model = [blob.type];
|
2565
|
+
var newTask = createTask(request, model, null, false, request.abortableTasks);
|
2566
|
+
var reader = blob.stream().getReader();
|
2567
|
+
var aborted = false;
|
2568
|
+
|
2569
|
+
function progress(entry) {
|
2570
|
+
if (aborted) {
|
2571
|
+
return;
|
2572
|
+
}
|
2573
|
+
|
2574
|
+
if (entry.done) {
|
2575
|
+
request.abortListeners.delete(error);
|
2576
|
+
aborted = true;
|
2577
|
+
pingTask(request, newTask);
|
2578
|
+
return;
|
2579
|
+
} // TODO: Emit the chunk early and refer to it later by dedupe.
|
2580
|
+
|
2581
|
+
|
2582
|
+
model.push(entry.value); // $FlowFixMe[incompatible-call]
|
2583
|
+
|
2584
|
+
return reader.read().then(progress).catch(error);
|
2585
|
+
}
|
2586
|
+
|
2587
|
+
function error(reason) {
|
2588
|
+
if (aborted) {
|
2589
|
+
return;
|
2590
|
+
}
|
2591
|
+
|
2592
|
+
aborted = true;
|
2593
|
+
request.abortListeners.delete(error);
|
2594
|
+
var digest = logRecoverableError(request, reason);
|
2595
|
+
emitErrorChunk(request, newTask.id, digest, reason);
|
2596
|
+
request.abortableTasks.delete(newTask);
|
2597
|
+
enqueueFlush(request); // $FlowFixMe should be able to pass mixed
|
2598
|
+
|
2599
|
+
reader.cancel(reason).then(error, error);
|
2600
|
+
}
|
2601
|
+
|
2602
|
+
request.abortListeners.add(error); // $FlowFixMe[incompatible-call]
|
2603
|
+
|
2604
|
+
reader.read().then(progress).catch(error);
|
2605
|
+
return '$B' + newTask.id.toString(16);
|
2606
|
+
}
|
2607
|
+
|
2300
2608
|
function escapeStringValue(value) {
|
2301
2609
|
if (value[0] === '$') {
|
2302
2610
|
// We need to escape $ prefixed strings since we use those to encode
|
@@ -2389,37 +2697,34 @@ function renderModelDestructive(request, task, parent, parentPropertyName, value
|
|
2389
2697
|
{
|
2390
2698
|
var _writtenObjects = request.writtenObjects;
|
2391
2699
|
|
2392
|
-
|
2393
|
-
|
2394
|
-
if (_existingId !== undefined) {
|
2395
|
-
if (task.keyPath !== null || task.implicitSlot) ; else if (modelRoot === value) {
|
2396
|
-
// This is the ID we're currently emitting so we need to write it
|
2397
|
-
// once but if we discover it again, we refer to it by id.
|
2398
|
-
modelRoot = null;
|
2399
|
-
} else if (_existingId === SEEN_BUT_NOT_YET_OUTLINED) {
|
2400
|
-
// TODO: If we throw here we can treat this as suspending which causes an outline
|
2401
|
-
// but that is able to reuse the same task if we're already in one but then that
|
2402
|
-
// will be a lazy future value rather than guaranteed to exist but maybe that's good.
|
2403
|
-
var newId = outlineModel(request, value);
|
2404
|
-
return serializeByValueID(newId);
|
2405
|
-
} else {
|
2406
|
-
// We've already emitted this as an outlined object, so we can refer to that by its
|
2407
|
-
// existing ID. TODO: We should use a lazy reference since, unlike plain objects,
|
2408
|
-
// elements might suspend so it might not have emitted yet even if we have the ID for
|
2409
|
-
// it. However, this creates an extra wrapper when it's not needed. We should really
|
2410
|
-
// detect whether this already was emitted and synchronously available. In that
|
2411
|
-
// case we can refer to it synchronously and only make it lazy otherwise.
|
2412
|
-
// We currently don't have a data structure that lets us see that though.
|
2413
|
-
return serializeByValueID(_existingId);
|
2414
|
-
}
|
2415
|
-
} else {
|
2416
|
-
// This is the first time we've seen this object. We may never see it again
|
2417
|
-
// so we'll inline it. Mark it as seen. If we see it again, we'll outline.
|
2418
|
-
_writtenObjects.set(value, SEEN_BUT_NOT_YET_OUTLINED); // The element's props are marked as "never outlined" so that they are inlined into
|
2419
|
-
// the same row as the element itself.
|
2420
|
-
|
2700
|
+
if (task.keyPath !== null || task.implicitSlot) ; else {
|
2701
|
+
var _existingReference = _writtenObjects.get(value);
|
2421
2702
|
|
2422
|
-
|
2703
|
+
if (_existingReference !== undefined) {
|
2704
|
+
if (modelRoot === value) {
|
2705
|
+
// This is the ID we're currently emitting so we need to write it
|
2706
|
+
// once but if we discover it again, we refer to it by id.
|
2707
|
+
modelRoot = null;
|
2708
|
+
} else {
|
2709
|
+
// We've already emitted this as an outlined object, so we can refer to that by its
|
2710
|
+
// existing ID. TODO: We should use a lazy reference since, unlike plain objects,
|
2711
|
+
// elements might suspend so it might not have emitted yet even if we have the ID for
|
2712
|
+
// it. However, this creates an extra wrapper when it's not needed. We should really
|
2713
|
+
// detect whether this already was emitted and synchronously available. In that
|
2714
|
+
// case we can refer to it synchronously and only make it lazy otherwise.
|
2715
|
+
// We currently don't have a data structure that lets us see that though.
|
2716
|
+
return _existingReference;
|
2717
|
+
}
|
2718
|
+
} else if (parentPropertyName.indexOf(':') === -1) {
|
2719
|
+
// TODO: If the property name contains a colon, we don't dedupe. Escape instead.
|
2720
|
+
var parentReference = _writtenObjects.get(parent);
|
2721
|
+
|
2722
|
+
if (parentReference !== undefined) {
|
2723
|
+
// If the parent has a reference, we can refer to this object indirectly
|
2724
|
+
// through the property name inside that parent.
|
2725
|
+
_writtenObjects.set(value, parentReference + ':' + parentPropertyName);
|
2726
|
+
}
|
2727
|
+
}
|
2423
2728
|
}
|
2424
2729
|
|
2425
2730
|
var element = value;
|
@@ -2462,9 +2767,11 @@ function renderModelDestructive(request, task, parent, parentPropertyName, value
|
|
2462
2767
|
// from suspending the lazy before.
|
2463
2768
|
task.thenableState = null;
|
2464
2769
|
var lazy = value;
|
2465
|
-
var
|
2466
|
-
|
2467
|
-
|
2770
|
+
var resolvedModel;
|
2771
|
+
|
2772
|
+
{
|
2773
|
+
resolvedModel = callLazyInitInDEV(lazy);
|
2774
|
+
}
|
2468
2775
|
|
2469
2776
|
{
|
2470
2777
|
var _debugInfo = lazy._debugInfo;
|
@@ -2486,17 +2793,30 @@ function renderModelDestructive(request, task, parent, parentPropertyName, value
|
|
2486
2793
|
|
2487
2794
|
return renderModelDestructive(request, task, emptyRoot, '', resolvedModel);
|
2488
2795
|
}
|
2796
|
+
|
2797
|
+
case REACT_LEGACY_ELEMENT_TYPE:
|
2798
|
+
{
|
2799
|
+
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.');
|
2800
|
+
}
|
2489
2801
|
}
|
2490
2802
|
|
2491
2803
|
if (isClientReference(value)) {
|
2492
2804
|
return serializeClientReference(request, parent, parentPropertyName, value);
|
2493
2805
|
}
|
2494
2806
|
|
2807
|
+
if (request.temporaryReferences !== undefined) {
|
2808
|
+
var tempRef = resolveTemporaryReference(request.temporaryReferences, value);
|
2809
|
+
|
2810
|
+
if (tempRef !== undefined) {
|
2811
|
+
return serializeTemporaryReference(request, tempRef);
|
2812
|
+
}
|
2813
|
+
}
|
2814
|
+
|
2495
2815
|
var writtenObjects = request.writtenObjects;
|
2496
|
-
var
|
2816
|
+
var existingReference = writtenObjects.get(value); // $FlowFixMe[method-unbinding]
|
2497
2817
|
|
2498
2818
|
if (typeof value.then === 'function') {
|
2499
|
-
if (
|
2819
|
+
if (existingReference !== undefined) {
|
2500
2820
|
if (task.keyPath !== null || task.implicitSlot) {
|
2501
2821
|
// If we're in some kind of context we can't reuse the result of this render or
|
2502
2822
|
// previous renders of this element. We only reuse Promises if they're not wrapped
|
@@ -2510,35 +2830,58 @@ function renderModelDestructive(request, task, parent, parentPropertyName, value
|
|
2510
2830
|
modelRoot = null;
|
2511
2831
|
} else {
|
2512
2832
|
// We've seen this promise before, so we can just refer to the same result.
|
2513
|
-
return
|
2833
|
+
return existingReference;
|
2514
2834
|
}
|
2515
2835
|
} // We assume that any object with a .then property is a "Thenable" type,
|
2516
2836
|
// or a Promise type. Either of which can be represented by a Promise.
|
2517
2837
|
|
2518
2838
|
|
2519
2839
|
var promiseId = serializeThenable(request, task, value);
|
2520
|
-
|
2521
|
-
|
2840
|
+
var promiseReference = serializePromiseID(promiseId);
|
2841
|
+
writtenObjects.set(value, promiseReference);
|
2842
|
+
return promiseReference;
|
2522
2843
|
}
|
2523
2844
|
|
2524
|
-
if (
|
2845
|
+
if (existingReference !== undefined) {
|
2525
2846
|
if (modelRoot === value) {
|
2526
2847
|
// This is the ID we're currently emitting so we need to write it
|
2527
2848
|
// once but if we discover it again, we refer to it by id.
|
2528
2849
|
modelRoot = null;
|
2529
|
-
} else
|
2530
|
-
var _newId = outlineModel(request, value);
|
2531
|
-
|
2532
|
-
return serializeByValueID(_newId);
|
2533
|
-
} else if (existingId !== NEVER_OUTLINED) {
|
2850
|
+
} else {
|
2534
2851
|
// We've already emitted this as an outlined object, so we can
|
2535
2852
|
// just refer to that by its existing ID.
|
2536
|
-
return
|
2853
|
+
return existingReference;
|
2854
|
+
}
|
2855
|
+
} else if (parentPropertyName.indexOf(':') === -1) {
|
2856
|
+
// TODO: If the property name contains a colon, we don't dedupe. Escape instead.
|
2857
|
+
var _parentReference = writtenObjects.get(parent);
|
2858
|
+
|
2859
|
+
if (_parentReference !== undefined) {
|
2860
|
+
// If the parent has a reference, we can refer to this object indirectly
|
2861
|
+
// through the property name inside that parent.
|
2862
|
+
var propertyName = parentPropertyName;
|
2863
|
+
|
2864
|
+
if (isArray(parent) && parent[0] === REACT_ELEMENT_TYPE) {
|
2865
|
+
// For elements, we've converted it to an array but we'll have converted
|
2866
|
+
// it back to an element before we read the references so the property
|
2867
|
+
// needs to be aliased.
|
2868
|
+
switch (parentPropertyName) {
|
2869
|
+
case '1':
|
2870
|
+
propertyName = 'type';
|
2871
|
+
break;
|
2872
|
+
|
2873
|
+
case '2':
|
2874
|
+
propertyName = 'key';
|
2875
|
+
break;
|
2876
|
+
|
2877
|
+
case '3':
|
2878
|
+
propertyName = 'props';
|
2879
|
+
break;
|
2880
|
+
}
|
2881
|
+
}
|
2882
|
+
|
2883
|
+
writtenObjects.set(value, _parentReference + ':' + propertyName);
|
2537
2884
|
}
|
2538
|
-
} else {
|
2539
|
-
// This is the first time we've seen this object. We may never see it again
|
2540
|
-
// so we'll inline it. Mark it as seen. If we see it again, we'll outline.
|
2541
|
-
writtenObjects.set(value, SEEN_BUT_NOT_YET_OUTLINED);
|
2542
2885
|
}
|
2543
2886
|
|
2544
2887
|
if (isArray(value)) {
|
@@ -2558,31 +2901,116 @@ function renderModelDestructive(request, task, parent, parentPropertyName, value
|
|
2558
2901
|
return serializeFormData(request, value);
|
2559
2902
|
}
|
2560
2903
|
|
2561
|
-
|
2904
|
+
{
|
2905
|
+
if (value instanceof ArrayBuffer) {
|
2906
|
+
return serializeTypedArray(request, 'A', new Uint8Array(value));
|
2907
|
+
}
|
2562
2908
|
|
2563
|
-
|
2564
|
-
|
2565
|
-
|
2909
|
+
if (value instanceof Int8Array) {
|
2910
|
+
// char
|
2911
|
+
return serializeTypedArray(request, 'O', value);
|
2912
|
+
}
|
2566
2913
|
|
2567
|
-
if (
|
2568
|
-
//
|
2569
|
-
return
|
2914
|
+
if (value instanceof Uint8Array) {
|
2915
|
+
// unsigned char
|
2916
|
+
return serializeTypedArray(request, 'o', value);
|
2570
2917
|
}
|
2571
2918
|
|
2572
|
-
|
2573
|
-
|
2919
|
+
if (value instanceof Uint8ClampedArray) {
|
2920
|
+
// unsigned clamped char
|
2921
|
+
return serializeTypedArray(request, 'U', value);
|
2922
|
+
}
|
2574
2923
|
|
2924
|
+
if (value instanceof Int16Array) {
|
2925
|
+
// sort
|
2926
|
+
return serializeTypedArray(request, 'S', value);
|
2927
|
+
}
|
2575
2928
|
|
2576
|
-
|
2929
|
+
if (value instanceof Uint16Array) {
|
2930
|
+
// unsigned short
|
2931
|
+
return serializeTypedArray(request, 's', value);
|
2932
|
+
}
|
2577
2933
|
|
2578
|
-
|
2579
|
-
|
2580
|
-
|
2934
|
+
if (value instanceof Int32Array) {
|
2935
|
+
// long
|
2936
|
+
return serializeTypedArray(request, 'L', value);
|
2937
|
+
}
|
2581
2938
|
|
2582
|
-
|
2583
|
-
|
2584
|
-
|
2585
|
-
}
|
2939
|
+
if (value instanceof Uint32Array) {
|
2940
|
+
// unsigned long
|
2941
|
+
return serializeTypedArray(request, 'l', value);
|
2942
|
+
}
|
2943
|
+
|
2944
|
+
if (value instanceof Float32Array) {
|
2945
|
+
// float
|
2946
|
+
return serializeTypedArray(request, 'G', value);
|
2947
|
+
}
|
2948
|
+
|
2949
|
+
if (value instanceof Float64Array) {
|
2950
|
+
// double
|
2951
|
+
return serializeTypedArray(request, 'g', value);
|
2952
|
+
}
|
2953
|
+
|
2954
|
+
if (value instanceof BigInt64Array) {
|
2955
|
+
// number
|
2956
|
+
return serializeTypedArray(request, 'M', value);
|
2957
|
+
}
|
2958
|
+
|
2959
|
+
if (value instanceof BigUint64Array) {
|
2960
|
+
// unsigned number
|
2961
|
+
// We use "m" instead of "n" since JSON can start with "null"
|
2962
|
+
return serializeTypedArray(request, 'm', value);
|
2963
|
+
}
|
2964
|
+
|
2965
|
+
if (value instanceof DataView) {
|
2966
|
+
return serializeTypedArray(request, 'V', value);
|
2967
|
+
} // TODO: Blob is not available in old Node. Remove the typeof check later.
|
2968
|
+
|
2969
|
+
|
2970
|
+
if (typeof Blob === 'function' && value instanceof Blob) {
|
2971
|
+
return serializeBlob(request, value);
|
2972
|
+
}
|
2973
|
+
}
|
2974
|
+
|
2975
|
+
var iteratorFn = getIteratorFn(value);
|
2976
|
+
|
2977
|
+
if (iteratorFn) {
|
2978
|
+
// TODO: Should we serialize the return value as well like we do for AsyncIterables?
|
2979
|
+
var iterator = iteratorFn.call(value);
|
2980
|
+
|
2981
|
+
if (iterator === value) {
|
2982
|
+
// Iterator, not Iterable
|
2983
|
+
return serializeIterator(request, iterator);
|
2984
|
+
}
|
2985
|
+
|
2986
|
+
return renderFragment(request, task, Array.from(iterator));
|
2987
|
+
}
|
2988
|
+
|
2989
|
+
{
|
2990
|
+
// TODO: Blob is not available in old Node. Remove the typeof check later.
|
2991
|
+
if (typeof ReadableStream === 'function' && value instanceof ReadableStream) {
|
2992
|
+
return serializeReadableStream(request, task, value);
|
2993
|
+
}
|
2994
|
+
|
2995
|
+
var getAsyncIterator = value[ASYNC_ITERATOR];
|
2996
|
+
|
2997
|
+
if (typeof getAsyncIterator === 'function') {
|
2998
|
+
// We treat AsyncIterables as a Fragment and as such we might need to key them.
|
2999
|
+
return renderAsyncFragment(request, task, value, getAsyncIterator);
|
3000
|
+
}
|
3001
|
+
} // Verify that this is a simple plain object.
|
3002
|
+
|
3003
|
+
|
3004
|
+
var proto = getPrototypeOf(value);
|
3005
|
+
|
3006
|
+
if (proto !== ObjectPrototype && (proto === null || getPrototypeOf(proto) !== null)) {
|
3007
|
+
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.');
|
3008
|
+
}
|
3009
|
+
|
3010
|
+
{
|
3011
|
+
if (objectName(value) !== 'Object') {
|
3012
|
+
error('Only plain objects can be passed to Client Components from Server Components. ' + '%s objects are not supported.%s', objectName(value), describeObjectForErrorMessage(parent, parentPropertyName));
|
3013
|
+
} else if (!isSimpleObject(value)) {
|
2586
3014
|
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));
|
2587
3015
|
} else if (Object.getOwnPropertySymbols) {
|
2588
3016
|
var symbols = Object.getOwnPropertySymbols(value);
|
@@ -2641,11 +3069,17 @@ function renderModelDestructive(request, task, parent, parentPropertyName, value
|
|
2641
3069
|
return serializeServerReference(request, value);
|
2642
3070
|
}
|
2643
3071
|
|
2644
|
-
if (
|
2645
|
-
|
3072
|
+
if (request.temporaryReferences !== undefined) {
|
3073
|
+
var _tempRef = resolveTemporaryReference(request.temporaryReferences, value);
|
3074
|
+
|
3075
|
+
if (_tempRef !== undefined) {
|
3076
|
+
return serializeTemporaryReference(request, _tempRef);
|
3077
|
+
}
|
2646
3078
|
}
|
2647
3079
|
|
2648
|
-
if (
|
3080
|
+
if (isOpaqueTemporaryReference(value)) {
|
3081
|
+
throw new Error('Could not reference an opaque temporary reference. ' + 'This is likely due to misconfiguring the temporaryReferences options ' + 'on the server.');
|
3082
|
+
} else if (/^on[A-Z]/.test(parentPropertyName)) {
|
2649
3083
|
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.');
|
2650
3084
|
} else if ((jsxChildrenParents.has(parent) || jsxPropsParents.has(parent) && parentPropertyName === 'children')) {
|
2651
3085
|
var componentName = value.displayName || value.name || 'Component';
|
@@ -2657,11 +3091,10 @@ function renderModelDestructive(request, task, parent, parentPropertyName, value
|
|
2657
3091
|
|
2658
3092
|
if (typeof value === 'symbol') {
|
2659
3093
|
var writtenSymbols = request.writtenSymbols;
|
3094
|
+
var existingId = writtenSymbols.get(value);
|
2660
3095
|
|
2661
|
-
|
2662
|
-
|
2663
|
-
if (_existingId2 !== undefined) {
|
2664
|
-
return serializeByValueID(_existingId2);
|
3096
|
+
if (existingId !== undefined) {
|
3097
|
+
return serializeByValueID(existingId);
|
2665
3098
|
} // $FlowFixMe[incompatible-type] `description` might be undefined
|
2666
3099
|
|
2667
3100
|
|
@@ -2843,6 +3276,18 @@ function emitDebugChunk(request, id, debugInfo) {
|
|
2843
3276
|
request.completedRegularChunks.push(processedChunk);
|
2844
3277
|
}
|
2845
3278
|
|
3279
|
+
function emitTypedArrayChunk(request, id, tag, typedArray) {
|
3280
|
+
|
3281
|
+
request.pendingChunks++; // Extra chunk for the header.
|
3282
|
+
// TODO: Convert to little endian if that's not the server default.
|
3283
|
+
|
3284
|
+
var binaryChunk = typedArrayToBinaryChunk(typedArray);
|
3285
|
+
var binaryLength = byteLengthOfBinaryChunk(binaryChunk);
|
3286
|
+
var row = id.toString(16) + ':' + tag + binaryLength.toString(16) + ',';
|
3287
|
+
var headerChunk = stringToChunk(row);
|
3288
|
+
request.completedRegularChunks.push(headerChunk, binaryChunk);
|
3289
|
+
}
|
3290
|
+
|
2846
3291
|
function emitTextChunk(request, id, text) {
|
2847
3292
|
request.pendingChunks++; // Extra chunk for the header.
|
2848
3293
|
|
@@ -2878,6 +3323,14 @@ function renderConsoleValue(request, counter, parent, parentPropertyName, value)
|
|
2878
3323
|
return serializeClientReference(request, parent, parentPropertyName, value);
|
2879
3324
|
}
|
2880
3325
|
|
3326
|
+
if (request.temporaryReferences !== undefined) {
|
3327
|
+
var tempRef = resolveTemporaryReference(request.temporaryReferences, value);
|
3328
|
+
|
3329
|
+
if (tempRef !== undefined) {
|
3330
|
+
return serializeTemporaryReference(request, tempRef);
|
3331
|
+
}
|
3332
|
+
}
|
3333
|
+
|
2881
3334
|
if (counter.objectCount > 20) {
|
2882
3335
|
// We've reached our max number of objects to serialize across the wire so we serialize this
|
2883
3336
|
// object but no properties inside of it, as a place holder.
|
@@ -2886,12 +3339,12 @@ function renderConsoleValue(request, counter, parent, parentPropertyName, value)
|
|
2886
3339
|
|
2887
3340
|
counter.objectCount++;
|
2888
3341
|
var writtenObjects = request.writtenObjects;
|
2889
|
-
var
|
3342
|
+
var existingReference = writtenObjects.get(value); // $FlowFixMe[method-unbinding]
|
2890
3343
|
|
2891
3344
|
if (typeof value.then === 'function') {
|
2892
|
-
if (
|
3345
|
+
if (existingReference !== undefined) {
|
2893
3346
|
// We've seen this promise before, so we can just refer to the same result.
|
2894
|
-
return
|
3347
|
+
return existingReference;
|
2895
3348
|
}
|
2896
3349
|
|
2897
3350
|
var thenable = value;
|
@@ -2923,10 +3376,10 @@ function renderConsoleValue(request, counter, parent, parentPropertyName, value)
|
|
2923
3376
|
return serializeInfinitePromise();
|
2924
3377
|
}
|
2925
3378
|
|
2926
|
-
if (
|
3379
|
+
if (existingReference !== undefined) {
|
2927
3380
|
// We've already emitted this as a real object, so we can
|
2928
|
-
// just refer to that by its existing
|
2929
|
-
return
|
3381
|
+
// just refer to that by its existing reference.
|
3382
|
+
return existingReference;
|
2930
3383
|
}
|
2931
3384
|
|
2932
3385
|
if (isArray(value)) {
|
@@ -2946,6 +3399,77 @@ function renderConsoleValue(request, counter, parent, parentPropertyName, value)
|
|
2946
3399
|
return serializeFormData(request, value);
|
2947
3400
|
}
|
2948
3401
|
|
3402
|
+
{
|
3403
|
+
if (value instanceof ArrayBuffer) {
|
3404
|
+
return serializeTypedArray(request, 'A', new Uint8Array(value));
|
3405
|
+
}
|
3406
|
+
|
3407
|
+
if (value instanceof Int8Array) {
|
3408
|
+
// char
|
3409
|
+
return serializeTypedArray(request, 'O', value);
|
3410
|
+
}
|
3411
|
+
|
3412
|
+
if (value instanceof Uint8Array) {
|
3413
|
+
// unsigned char
|
3414
|
+
return serializeTypedArray(request, 'o', value);
|
3415
|
+
}
|
3416
|
+
|
3417
|
+
if (value instanceof Uint8ClampedArray) {
|
3418
|
+
// unsigned clamped char
|
3419
|
+
return serializeTypedArray(request, 'U', value);
|
3420
|
+
}
|
3421
|
+
|
3422
|
+
if (value instanceof Int16Array) {
|
3423
|
+
// sort
|
3424
|
+
return serializeTypedArray(request, 'S', value);
|
3425
|
+
}
|
3426
|
+
|
3427
|
+
if (value instanceof Uint16Array) {
|
3428
|
+
// unsigned short
|
3429
|
+
return serializeTypedArray(request, 's', value);
|
3430
|
+
}
|
3431
|
+
|
3432
|
+
if (value instanceof Int32Array) {
|
3433
|
+
// long
|
3434
|
+
return serializeTypedArray(request, 'L', value);
|
3435
|
+
}
|
3436
|
+
|
3437
|
+
if (value instanceof Uint32Array) {
|
3438
|
+
// unsigned long
|
3439
|
+
return serializeTypedArray(request, 'l', value);
|
3440
|
+
}
|
3441
|
+
|
3442
|
+
if (value instanceof Float32Array) {
|
3443
|
+
// float
|
3444
|
+
return serializeTypedArray(request, 'G', value);
|
3445
|
+
}
|
3446
|
+
|
3447
|
+
if (value instanceof Float64Array) {
|
3448
|
+
// double
|
3449
|
+
return serializeTypedArray(request, 'g', value);
|
3450
|
+
}
|
3451
|
+
|
3452
|
+
if (value instanceof BigInt64Array) {
|
3453
|
+
// number
|
3454
|
+
return serializeTypedArray(request, 'M', value);
|
3455
|
+
}
|
3456
|
+
|
3457
|
+
if (value instanceof BigUint64Array) {
|
3458
|
+
// unsigned number
|
3459
|
+
// We use "m" instead of "n" since JSON can start with "null"
|
3460
|
+
return serializeTypedArray(request, 'm', value);
|
3461
|
+
}
|
3462
|
+
|
3463
|
+
if (value instanceof DataView) {
|
3464
|
+
return serializeTypedArray(request, 'V', value);
|
3465
|
+
} // TODO: Blob is not available in old Node. Remove the typeof check later.
|
3466
|
+
|
3467
|
+
|
3468
|
+
if (typeof Blob === 'function' && value instanceof Blob) {
|
3469
|
+
return serializeBlob(request, value);
|
3470
|
+
}
|
3471
|
+
}
|
3472
|
+
|
2949
3473
|
var iteratorFn = getIteratorFn(value);
|
2950
3474
|
|
2951
3475
|
if (iteratorFn) {
|
@@ -2991,8 +3515,12 @@ function renderConsoleValue(request, counter, parent, parentPropertyName, value)
|
|
2991
3515
|
return serializeClientReference(request, parent, parentPropertyName, value);
|
2992
3516
|
}
|
2993
3517
|
|
2994
|
-
if (
|
2995
|
-
|
3518
|
+
if (request.temporaryReferences !== undefined) {
|
3519
|
+
var _tempRef2 = resolveTemporaryReference(request.temporaryReferences, value);
|
3520
|
+
|
3521
|
+
if (_tempRef2 !== undefined) {
|
3522
|
+
return serializeTemporaryReference(request, _tempRef2);
|
3523
|
+
}
|
2996
3524
|
} // Serialize the body of the function as an eval so it can be printed.
|
2997
3525
|
// $FlowFixMe[method-unbinding]
|
2998
3526
|
|
@@ -3002,11 +3530,10 @@ function renderConsoleValue(request, counter, parent, parentPropertyName, value)
|
|
3002
3530
|
|
3003
3531
|
if (typeof value === 'symbol') {
|
3004
3532
|
var writtenSymbols = request.writtenSymbols;
|
3533
|
+
var existingId = writtenSymbols.get(value);
|
3005
3534
|
|
3006
|
-
|
3007
|
-
|
3008
|
-
if (_existingId3 !== undefined) {
|
3009
|
-
return serializeByValueID(_existingId3);
|
3535
|
+
if (existingId !== undefined) {
|
3536
|
+
return serializeByValueID(existingId);
|
3010
3537
|
} // $FlowFixMe[incompatible-type] `description` might be undefined
|
3011
3538
|
|
3012
3539
|
|
@@ -3061,6 +3588,85 @@ function emitChunk(request, task, value) {
|
|
3061
3588
|
emitTextChunk(request, id, value);
|
3062
3589
|
return;
|
3063
3590
|
}
|
3591
|
+
|
3592
|
+
{
|
3593
|
+
if (value instanceof ArrayBuffer) {
|
3594
|
+
emitTypedArrayChunk(request, id, 'A', new Uint8Array(value));
|
3595
|
+
return;
|
3596
|
+
}
|
3597
|
+
|
3598
|
+
if (value instanceof Int8Array) {
|
3599
|
+
// char
|
3600
|
+
emitTypedArrayChunk(request, id, 'O', value);
|
3601
|
+
return;
|
3602
|
+
}
|
3603
|
+
|
3604
|
+
if (value instanceof Uint8Array) {
|
3605
|
+
// unsigned char
|
3606
|
+
emitTypedArrayChunk(request, id, 'o', value);
|
3607
|
+
return;
|
3608
|
+
}
|
3609
|
+
|
3610
|
+
if (value instanceof Uint8ClampedArray) {
|
3611
|
+
// unsigned clamped char
|
3612
|
+
emitTypedArrayChunk(request, id, 'U', value);
|
3613
|
+
return;
|
3614
|
+
}
|
3615
|
+
|
3616
|
+
if (value instanceof Int16Array) {
|
3617
|
+
// sort
|
3618
|
+
emitTypedArrayChunk(request, id, 'S', value);
|
3619
|
+
return;
|
3620
|
+
}
|
3621
|
+
|
3622
|
+
if (value instanceof Uint16Array) {
|
3623
|
+
// unsigned short
|
3624
|
+
emitTypedArrayChunk(request, id, 's', value);
|
3625
|
+
return;
|
3626
|
+
}
|
3627
|
+
|
3628
|
+
if (value instanceof Int32Array) {
|
3629
|
+
// long
|
3630
|
+
emitTypedArrayChunk(request, id, 'L', value);
|
3631
|
+
return;
|
3632
|
+
}
|
3633
|
+
|
3634
|
+
if (value instanceof Uint32Array) {
|
3635
|
+
// unsigned long
|
3636
|
+
emitTypedArrayChunk(request, id, 'l', value);
|
3637
|
+
return;
|
3638
|
+
}
|
3639
|
+
|
3640
|
+
if (value instanceof Float32Array) {
|
3641
|
+
// float
|
3642
|
+
emitTypedArrayChunk(request, id, 'G', value);
|
3643
|
+
return;
|
3644
|
+
}
|
3645
|
+
|
3646
|
+
if (value instanceof Float64Array) {
|
3647
|
+
// double
|
3648
|
+
emitTypedArrayChunk(request, id, 'g', value);
|
3649
|
+
return;
|
3650
|
+
}
|
3651
|
+
|
3652
|
+
if (value instanceof BigInt64Array) {
|
3653
|
+
// number
|
3654
|
+
emitTypedArrayChunk(request, id, 'M', value);
|
3655
|
+
return;
|
3656
|
+
}
|
3657
|
+
|
3658
|
+
if (value instanceof BigUint64Array) {
|
3659
|
+
// unsigned number
|
3660
|
+
// We use "m" instead of "n" since JSON can start with "null"
|
3661
|
+
emitTypedArrayChunk(request, id, 'm', value);
|
3662
|
+
return;
|
3663
|
+
}
|
3664
|
+
|
3665
|
+
if (value instanceof DataView) {
|
3666
|
+
emitTypedArrayChunk(request, id, 'V', value);
|
3667
|
+
return;
|
3668
|
+
}
|
3669
|
+
} // For anything else we need to try to serialize it using JSON.
|
3064
3670
|
// $FlowFixMe[incompatible-type] stringify can return null for undefined but we never do
|
3065
3671
|
|
3066
3672
|
|
@@ -3106,8 +3712,11 @@ function retryTask(request, task) {
|
|
3106
3712
|
task.implicitSlot = false;
|
3107
3713
|
|
3108
3714
|
if (typeof resolvedModel === 'object' && resolvedModel !== null) {
|
3109
|
-
//
|
3715
|
+
// We're not in a contextual place here so we can refer to this object by this ID for
|
3716
|
+
// any future references.
|
3717
|
+
request.writtenObjects.set(resolvedModel, serializeByValueID(task.id)); // Object might contain unresolved values like additional elements.
|
3110
3718
|
// This is simulating what the JSON loop would do if this was part of it.
|
3719
|
+
|
3111
3720
|
emitChunk(request, task, resolvedModel);
|
3112
3721
|
} else {
|
3113
3722
|
// If the value is a string, it means it's a terminal value and we already escaped it
|
@@ -3149,6 +3758,26 @@ function retryTask(request, task) {
|
|
3149
3758
|
}
|
3150
3759
|
}
|
3151
3760
|
|
3761
|
+
function tryStreamTask(request, task) {
|
3762
|
+
// This is used to try to emit something synchronously but if it suspends,
|
3763
|
+
// we emit a reference to a new outlined task immediately instead.
|
3764
|
+
var prevDebugID = debugID;
|
3765
|
+
|
3766
|
+
{
|
3767
|
+
// We don't use the id of the stream task for debugID. Instead we leave it null
|
3768
|
+
// so that we instead outline the row to get a new debugID if needed.
|
3769
|
+
debugID = null;
|
3770
|
+
}
|
3771
|
+
|
3772
|
+
try {
|
3773
|
+
emitChunk(request, task, task.model);
|
3774
|
+
} finally {
|
3775
|
+
{
|
3776
|
+
debugID = prevDebugID;
|
3777
|
+
}
|
3778
|
+
}
|
3779
|
+
}
|
3780
|
+
|
3152
3781
|
function performWork(request) {
|
3153
3782
|
var prevDispatcher = ReactSharedInternals.H;
|
3154
3783
|
ReactSharedInternals.H = HooksDispatcher;
|
@@ -3538,8 +4167,12 @@ function loadChunk(chunkId, filename) {
|
|
3538
4167
|
return __webpack_chunk_load__(chunkId);
|
3539
4168
|
}
|
3540
4169
|
|
4170
|
+
// $FlowFixMe[method-unbinding]
|
4171
|
+
var hasOwnProperty = Object.prototype.hasOwnProperty;
|
4172
|
+
|
3541
4173
|
var PENDING = 'pending';
|
3542
4174
|
var BLOCKED = 'blocked';
|
4175
|
+
var CYCLIC = 'cyclic';
|
3543
4176
|
var RESOLVED_MODEL = 'resolved_model';
|
3544
4177
|
var INITIALIZED = 'fulfilled';
|
3545
4178
|
var ERRORED = 'rejected'; // $FlowFixMe[missing-this-annot]
|
@@ -3572,6 +4205,7 @@ Chunk.prototype.then = function (resolve, reject) {
|
|
3572
4205
|
|
3573
4206
|
case PENDING:
|
3574
4207
|
case BLOCKED:
|
4208
|
+
case CYCLIC:
|
3575
4209
|
if (resolve) {
|
3576
4210
|
if (chunk.value === null) {
|
3577
4211
|
chunk.value = [];
|
@@ -3613,8 +4247,38 @@ function wakeChunk(listeners, value) {
|
|
3613
4247
|
}
|
3614
4248
|
}
|
3615
4249
|
|
4250
|
+
function wakeChunkIfInitialized(chunk, resolveListeners, rejectListeners) {
|
4251
|
+
switch (chunk.status) {
|
4252
|
+
case INITIALIZED:
|
4253
|
+
wakeChunk(resolveListeners, chunk.value);
|
4254
|
+
break;
|
4255
|
+
|
4256
|
+
case PENDING:
|
4257
|
+
case BLOCKED:
|
4258
|
+
case CYCLIC:
|
4259
|
+
chunk.value = resolveListeners;
|
4260
|
+
chunk.reason = rejectListeners;
|
4261
|
+
break;
|
4262
|
+
|
4263
|
+
case ERRORED:
|
4264
|
+
if (rejectListeners) {
|
4265
|
+
wakeChunk(rejectListeners, chunk.reason);
|
4266
|
+
}
|
4267
|
+
|
4268
|
+
break;
|
4269
|
+
}
|
4270
|
+
}
|
4271
|
+
|
3616
4272
|
function triggerErrorOnChunk(chunk, error) {
|
3617
4273
|
if (chunk.status !== PENDING && chunk.status !== BLOCKED) {
|
4274
|
+
{
|
4275
|
+
// If we get more data to an already resolved ID, we assume that it's
|
4276
|
+
// a stream chunk since any other row shouldn't have more than one entry.
|
4277
|
+
var streamChunk = chunk;
|
4278
|
+
var controller = streamChunk.reason; // $FlowFixMe[incompatible-call]: The error method should accept mixed.
|
4279
|
+
|
4280
|
+
controller.error(error);
|
4281
|
+
}
|
3618
4282
|
|
3619
4283
|
return;
|
3620
4284
|
}
|
@@ -3629,9 +4293,64 @@ function triggerErrorOnChunk(chunk, error) {
|
|
3629
4293
|
}
|
3630
4294
|
}
|
3631
4295
|
|
3632
|
-
function createResolvedModelChunk(response, value) {
|
4296
|
+
function createResolvedModelChunk(response, value, id) {
|
4297
|
+
// $FlowFixMe[invalid-constructor] Flow doesn't support functions as constructors
|
4298
|
+
return new Chunk(RESOLVED_MODEL, value, id, response);
|
4299
|
+
}
|
4300
|
+
|
4301
|
+
function resolveModelChunk(chunk, value, id) {
|
4302
|
+
if (chunk.status !== PENDING) {
|
4303
|
+
{
|
4304
|
+
// If we get more data to an already resolved ID, we assume that it's
|
4305
|
+
// a stream chunk since any other row shouldn't have more than one entry.
|
4306
|
+
var streamChunk = chunk;
|
4307
|
+
var controller = streamChunk.reason;
|
4308
|
+
|
4309
|
+
if (value[0] === 'C') {
|
4310
|
+
controller.close(value === 'C' ? '"$undefined"' : value.slice(1));
|
4311
|
+
} else {
|
4312
|
+
controller.enqueueModel(value);
|
4313
|
+
}
|
4314
|
+
}
|
4315
|
+
|
4316
|
+
return;
|
4317
|
+
}
|
4318
|
+
|
4319
|
+
var resolveListeners = chunk.value;
|
4320
|
+
var rejectListeners = chunk.reason;
|
4321
|
+
var resolvedChunk = chunk;
|
4322
|
+
resolvedChunk.status = RESOLVED_MODEL;
|
4323
|
+
resolvedChunk.value = value;
|
4324
|
+
resolvedChunk.reason = id;
|
4325
|
+
|
4326
|
+
if (resolveListeners !== null) {
|
4327
|
+
// This is unfortunate that we're reading this eagerly if
|
4328
|
+
// we already have listeners attached since they might no
|
4329
|
+
// longer be rendered or might not be the highest pri.
|
4330
|
+
initializeModelChunk(resolvedChunk); // The status might have changed after initialization.
|
4331
|
+
|
4332
|
+
wakeChunkIfInitialized(chunk, resolveListeners, rejectListeners);
|
4333
|
+
}
|
4334
|
+
}
|
4335
|
+
|
4336
|
+
function createInitializedStreamChunk(response, value, controller) {
|
4337
|
+
// We use the reason field to stash the controller since we already have that
|
4338
|
+
// field. It's a bit of a hack but efficient.
|
3633
4339
|
// $FlowFixMe[invalid-constructor] Flow doesn't support functions as constructors
|
3634
|
-
return new Chunk(
|
4340
|
+
return new Chunk(INITIALIZED, value, controller, response);
|
4341
|
+
}
|
4342
|
+
|
4343
|
+
function createResolvedIteratorResultChunk(response, value, done) {
|
4344
|
+
// To reuse code as much code as possible we add the wrapper element as part of the JSON.
|
4345
|
+
var iteratorResultJSON = (done ? '{"done":true,"value":' : '{"done":false,"value":') + value + '}'; // $FlowFixMe[invalid-constructor] Flow doesn't support functions as constructors
|
4346
|
+
|
4347
|
+
return new Chunk(RESOLVED_MODEL, iteratorResultJSON, -1, response);
|
4348
|
+
}
|
4349
|
+
|
4350
|
+
function resolveIteratorResultChunk(chunk, value, done) {
|
4351
|
+
// To reuse code as much code as possible we add the wrapper element as part of the JSON.
|
4352
|
+
var iteratorResultJSON = (done ? '{"done":true,"value":' : '{"done":false,"value":') + value + '}';
|
4353
|
+
resolveModelChunk(chunk, iteratorResultJSON, -1);
|
3635
4354
|
}
|
3636
4355
|
|
3637
4356
|
function bindArgs$1(fn, args) {
|
@@ -3662,11 +4381,51 @@ function loadServerReference$1(response, id, bound, parentChunk, parentObject, k
|
|
3662
4381
|
}
|
3663
4382
|
}
|
3664
4383
|
|
3665
|
-
promise.then(createModelResolver(parentChunk, parentObject, key, false, response, createModel), createModelReject(parentChunk)); // We need a placeholder value that will be replaced later.
|
4384
|
+
promise.then(createModelResolver(parentChunk, parentObject, key, false, response, createModel, []), createModelReject(parentChunk)); // We need a placeholder value that will be replaced later.
|
3666
4385
|
|
3667
4386
|
return null;
|
3668
4387
|
}
|
3669
4388
|
|
4389
|
+
function reviveModel(response, parentObj, parentKey, value, reference) {
|
4390
|
+
if (typeof value === 'string') {
|
4391
|
+
// We can't use .bind here because we need the "this" value.
|
4392
|
+
return parseModelString(response, parentObj, parentKey, value, reference);
|
4393
|
+
}
|
4394
|
+
|
4395
|
+
if (typeof value === 'object' && value !== null) {
|
4396
|
+
if (reference !== undefined && response._temporaryReferences !== undefined) {
|
4397
|
+
// Store this object's reference in case it's returned later.
|
4398
|
+
registerTemporaryReference(response._temporaryReferences, value, reference);
|
4399
|
+
}
|
4400
|
+
|
4401
|
+
if (Array.isArray(value)) {
|
4402
|
+
for (var i = 0; i < value.length; i++) {
|
4403
|
+
var childRef = reference !== undefined ? reference + ':' + i : undefined; // $FlowFixMe[cannot-write]
|
4404
|
+
|
4405
|
+
value[i] = reviveModel(response, value, '' + i, value[i], childRef);
|
4406
|
+
}
|
4407
|
+
} else {
|
4408
|
+
for (var key in value) {
|
4409
|
+
if (hasOwnProperty.call(value, key)) {
|
4410
|
+
var _childRef = reference !== undefined && key.indexOf(':') === -1 ? reference + ':' + key : undefined;
|
4411
|
+
|
4412
|
+
var newValue = reviveModel(response, value, key, value[key], _childRef);
|
4413
|
+
|
4414
|
+
if (newValue !== undefined) {
|
4415
|
+
// $FlowFixMe[cannot-write]
|
4416
|
+
value[key] = newValue;
|
4417
|
+
} else {
|
4418
|
+
// $FlowFixMe[cannot-write]
|
4419
|
+
delete value[key];
|
4420
|
+
}
|
4421
|
+
}
|
4422
|
+
}
|
4423
|
+
}
|
4424
|
+
}
|
4425
|
+
|
4426
|
+
return value;
|
4427
|
+
}
|
4428
|
+
|
3670
4429
|
var initializingChunk = null;
|
3671
4430
|
var initializingChunkBlockedModel = null;
|
3672
4431
|
|
@@ -3675,9 +4434,21 @@ function initializeModelChunk(chunk) {
|
|
3675
4434
|
var prevBlocked = initializingChunkBlockedModel;
|
3676
4435
|
initializingChunk = chunk;
|
3677
4436
|
initializingChunkBlockedModel = null;
|
4437
|
+
var rootReference = chunk.reason === -1 ? undefined : chunk.reason.toString(16);
|
4438
|
+
var resolvedModel = chunk.value; // We go to the CYCLIC state until we've fully resolved this.
|
4439
|
+
// We do this before parsing in case we try to initialize the same chunk
|
4440
|
+
// while parsing the model. Such as in a cyclic reference.
|
4441
|
+
|
4442
|
+
var cyclicChunk = chunk;
|
4443
|
+
cyclicChunk.status = CYCLIC;
|
4444
|
+
cyclicChunk.value = null;
|
4445
|
+
cyclicChunk.reason = null;
|
3678
4446
|
|
3679
4447
|
try {
|
3680
|
-
var
|
4448
|
+
var rawModel = JSON.parse(resolvedModel);
|
4449
|
+
var value = reviveModel(chunk._response, {
|
4450
|
+
'': rawModel
|
4451
|
+
}, '', rawModel, rootReference);
|
3681
4452
|
|
3682
4453
|
if (initializingChunkBlockedModel !== null && initializingChunkBlockedModel.deps > 0) {
|
3683
4454
|
initializingChunkBlockedModel.value = value; // We discovered new dependencies on modules that are not yet resolved.
|
@@ -3688,9 +4459,14 @@ function initializeModelChunk(chunk) {
|
|
3688
4459
|
blockedChunk.value = null;
|
3689
4460
|
blockedChunk.reason = null;
|
3690
4461
|
} else {
|
4462
|
+
var resolveListeners = cyclicChunk.value;
|
3691
4463
|
var initializedChunk = chunk;
|
3692
4464
|
initializedChunk.status = INITIALIZED;
|
3693
4465
|
initializedChunk.value = value;
|
4466
|
+
|
4467
|
+
if (resolveListeners !== null) {
|
4468
|
+
wakeChunk(resolveListeners, value);
|
4469
|
+
}
|
3694
4470
|
}
|
3695
4471
|
} catch (error) {
|
3696
4472
|
var erroredChunk = chunk;
|
@@ -3727,7 +4503,7 @@ function getChunk(response, id) {
|
|
3727
4503
|
|
3728
4504
|
if (backingEntry != null) {
|
3729
4505
|
// We assume that this is a string entry for now.
|
3730
|
-
chunk = createResolvedModelChunk(response, backingEntry);
|
4506
|
+
chunk = createResolvedModelChunk(response, backingEntry, id);
|
3731
4507
|
} else {
|
3732
4508
|
// We're still waiting on this entry to stream in.
|
3733
4509
|
chunk = createPendingChunk(response);
|
@@ -3739,7 +4515,7 @@ function getChunk(response, id) {
|
|
3739
4515
|
return chunk;
|
3740
4516
|
}
|
3741
4517
|
|
3742
|
-
function createModelResolver(chunk, parentObject, key, cyclic, response, map) {
|
4518
|
+
function createModelResolver(chunk, parentObject, key, cyclic, response, map, path) {
|
3743
4519
|
var blocked;
|
3744
4520
|
|
3745
4521
|
if (initializingChunkBlockedModel) {
|
@@ -3756,6 +4532,10 @@ function createModelResolver(chunk, parentObject, key, cyclic, response, map) {
|
|
3756
4532
|
}
|
3757
4533
|
|
3758
4534
|
return function (value) {
|
4535
|
+
for (var i = 1; i < path.length; i++) {
|
4536
|
+
value = value[path[i]];
|
4537
|
+
}
|
4538
|
+
|
3759
4539
|
parentObject[key] = map(response, value); // If this is the root object for a model reference, where `blocked.value`
|
3760
4540
|
// is a stale `null`, the resolved value can be used directly.
|
3761
4541
|
|
@@ -3788,7 +4568,9 @@ function createModelReject(chunk) {
|
|
3788
4568
|
};
|
3789
4569
|
}
|
3790
4570
|
|
3791
|
-
function getOutlinedModel(response,
|
4571
|
+
function getOutlinedModel(response, reference, parentObject, key, map) {
|
4572
|
+
var path = reference.split(':');
|
4573
|
+
var id = parseInt(path[0], 16);
|
3792
4574
|
var chunk = getChunk(response, id);
|
3793
4575
|
|
3794
4576
|
switch (chunk.status) {
|
@@ -3800,12 +4582,19 @@ function getOutlinedModel(response, id, parentObject, key, map) {
|
|
3800
4582
|
|
3801
4583
|
switch (chunk.status) {
|
3802
4584
|
case INITIALIZED:
|
3803
|
-
|
4585
|
+
var value = chunk.value;
|
4586
|
+
|
4587
|
+
for (var i = 1; i < path.length; i++) {
|
4588
|
+
value = value[path[i]];
|
4589
|
+
}
|
4590
|
+
|
4591
|
+
return map(response, value);
|
3804
4592
|
|
3805
4593
|
case PENDING:
|
3806
4594
|
case BLOCKED:
|
4595
|
+
case CYCLIC:
|
3807
4596
|
var parentChunk = initializingChunk;
|
3808
|
-
chunk.then(createModelResolver(parentChunk, parentObject, key,
|
4597
|
+
chunk.then(createModelResolver(parentChunk, parentObject, key, chunk.status === CYCLIC, response, map, path), createModelReject(parentChunk));
|
3809
4598
|
return null;
|
3810
4599
|
|
3811
4600
|
default:
|
@@ -3830,7 +4619,220 @@ function createModel(response, model) {
|
|
3830
4619
|
return model;
|
3831
4620
|
}
|
3832
4621
|
|
3833
|
-
function
|
4622
|
+
function parseTypedArray(response, reference, constructor, bytesPerElement, parentObject, parentKey) {
|
4623
|
+
var id = parseInt(reference.slice(2), 16);
|
4624
|
+
var prefix = response._prefix;
|
4625
|
+
var key = prefix + id; // We should have this backingEntry in the store already because we emitted
|
4626
|
+
// it before referencing it. It should be a Blob.
|
4627
|
+
|
4628
|
+
var backingEntry = response._formData.get(key);
|
4629
|
+
|
4630
|
+
var promise = constructor === ArrayBuffer ? backingEntry.arrayBuffer() : backingEntry.arrayBuffer().then(function (buffer) {
|
4631
|
+
return new constructor(buffer);
|
4632
|
+
}); // Since loading the buffer is an async operation we'll be blocking the parent
|
4633
|
+
// chunk.
|
4634
|
+
|
4635
|
+
var parentChunk = initializingChunk;
|
4636
|
+
promise.then(createModelResolver(parentChunk, parentObject, parentKey, false, response, createModel, []), createModelReject(parentChunk));
|
4637
|
+
return null;
|
4638
|
+
}
|
4639
|
+
|
4640
|
+
function resolveStream(response, id, stream, controller) {
|
4641
|
+
var chunks = response._chunks;
|
4642
|
+
var chunk = createInitializedStreamChunk(response, stream, controller);
|
4643
|
+
chunks.set(id, chunk);
|
4644
|
+
var prefix = response._prefix;
|
4645
|
+
var key = prefix + id;
|
4646
|
+
|
4647
|
+
var existingEntries = response._formData.getAll(key);
|
4648
|
+
|
4649
|
+
for (var i = 0; i < existingEntries.length; i++) {
|
4650
|
+
// We assume that this is a string entry for now.
|
4651
|
+
var value = existingEntries[i];
|
4652
|
+
|
4653
|
+
if (value[0] === 'C') {
|
4654
|
+
controller.close(value === 'C' ? '"$undefined"' : value.slice(1));
|
4655
|
+
} else {
|
4656
|
+
controller.enqueueModel(value);
|
4657
|
+
}
|
4658
|
+
}
|
4659
|
+
}
|
4660
|
+
|
4661
|
+
function parseReadableStream(response, reference, type, parentObject, parentKey) {
|
4662
|
+
var id = parseInt(reference.slice(2), 16);
|
4663
|
+
var controller = null;
|
4664
|
+
var stream = new ReadableStream({
|
4665
|
+
type: type,
|
4666
|
+
start: function (c) {
|
4667
|
+
controller = c;
|
4668
|
+
}
|
4669
|
+
});
|
4670
|
+
var previousBlockedChunk = null;
|
4671
|
+
var flightController = {
|
4672
|
+
enqueueModel: function (json) {
|
4673
|
+
if (previousBlockedChunk === null) {
|
4674
|
+
// If we're not blocked on any other chunks, we can try to eagerly initialize
|
4675
|
+
// this as a fast-path to avoid awaiting them.
|
4676
|
+
var chunk = createResolvedModelChunk(response, json, -1);
|
4677
|
+
initializeModelChunk(chunk);
|
4678
|
+
var initializedChunk = chunk;
|
4679
|
+
|
4680
|
+
if (initializedChunk.status === INITIALIZED) {
|
4681
|
+
controller.enqueue(initializedChunk.value);
|
4682
|
+
} else {
|
4683
|
+
chunk.then(function (v) {
|
4684
|
+
return controller.enqueue(v);
|
4685
|
+
}, function (e) {
|
4686
|
+
return controller.error(e);
|
4687
|
+
});
|
4688
|
+
previousBlockedChunk = chunk;
|
4689
|
+
}
|
4690
|
+
} else {
|
4691
|
+
// We're still waiting on a previous chunk so we can't enqueue quite yet.
|
4692
|
+
var blockedChunk = previousBlockedChunk;
|
4693
|
+
|
4694
|
+
var _chunk = createPendingChunk(response);
|
4695
|
+
|
4696
|
+
_chunk.then(function (v) {
|
4697
|
+
return controller.enqueue(v);
|
4698
|
+
}, function (e) {
|
4699
|
+
return controller.error(e);
|
4700
|
+
});
|
4701
|
+
|
4702
|
+
previousBlockedChunk = _chunk;
|
4703
|
+
blockedChunk.then(function () {
|
4704
|
+
if (previousBlockedChunk === _chunk) {
|
4705
|
+
// We were still the last chunk so we can now clear the queue and return
|
4706
|
+
// to synchronous emitting.
|
4707
|
+
previousBlockedChunk = null;
|
4708
|
+
}
|
4709
|
+
|
4710
|
+
resolveModelChunk(_chunk, json, -1);
|
4711
|
+
});
|
4712
|
+
}
|
4713
|
+
},
|
4714
|
+
close: function (json) {
|
4715
|
+
if (previousBlockedChunk === null) {
|
4716
|
+
controller.close();
|
4717
|
+
} else {
|
4718
|
+
var blockedChunk = previousBlockedChunk; // We shouldn't get any more enqueues after this so we can set it back to null.
|
4719
|
+
|
4720
|
+
previousBlockedChunk = null;
|
4721
|
+
blockedChunk.then(function () {
|
4722
|
+
return controller.close();
|
4723
|
+
});
|
4724
|
+
}
|
4725
|
+
},
|
4726
|
+
error: function (error) {
|
4727
|
+
if (previousBlockedChunk === null) {
|
4728
|
+
// $FlowFixMe[incompatible-call]
|
4729
|
+
controller.error(error);
|
4730
|
+
} else {
|
4731
|
+
var blockedChunk = previousBlockedChunk; // We shouldn't get any more enqueues after this so we can set it back to null.
|
4732
|
+
|
4733
|
+
previousBlockedChunk = null;
|
4734
|
+
blockedChunk.then(function () {
|
4735
|
+
return controller.error(error);
|
4736
|
+
});
|
4737
|
+
}
|
4738
|
+
}
|
4739
|
+
};
|
4740
|
+
resolveStream(response, id, stream, flightController);
|
4741
|
+
return stream;
|
4742
|
+
}
|
4743
|
+
|
4744
|
+
function asyncIterator() {
|
4745
|
+
// Self referencing iterator.
|
4746
|
+
return this;
|
4747
|
+
}
|
4748
|
+
|
4749
|
+
function createIterator(next) {
|
4750
|
+
var iterator = {
|
4751
|
+
next: next // TODO: Add return/throw as options for aborting.
|
4752
|
+
|
4753
|
+
}; // TODO: The iterator could inherit the AsyncIterator prototype which is not exposed as
|
4754
|
+
// a global but exists as a prototype of an AsyncGenerator. However, it's not needed
|
4755
|
+
// to satisfy the iterable protocol.
|
4756
|
+
|
4757
|
+
iterator[ASYNC_ITERATOR] = asyncIterator;
|
4758
|
+
return iterator;
|
4759
|
+
}
|
4760
|
+
|
4761
|
+
function parseAsyncIterable(response, reference, iterator, parentObject, parentKey) {
|
4762
|
+
var id = parseInt(reference.slice(2), 16);
|
4763
|
+
var buffer = [];
|
4764
|
+
var closed = false;
|
4765
|
+
var nextWriteIndex = 0;
|
4766
|
+
var flightController = {
|
4767
|
+
enqueueModel: function (value) {
|
4768
|
+
if (nextWriteIndex === buffer.length) {
|
4769
|
+
buffer[nextWriteIndex] = createResolvedIteratorResultChunk(response, value, false);
|
4770
|
+
} else {
|
4771
|
+
resolveIteratorResultChunk(buffer[nextWriteIndex], value, false);
|
4772
|
+
}
|
4773
|
+
|
4774
|
+
nextWriteIndex++;
|
4775
|
+
},
|
4776
|
+
close: function (value) {
|
4777
|
+
closed = true;
|
4778
|
+
|
4779
|
+
if (nextWriteIndex === buffer.length) {
|
4780
|
+
buffer[nextWriteIndex] = createResolvedIteratorResultChunk(response, value, true);
|
4781
|
+
} else {
|
4782
|
+
resolveIteratorResultChunk(buffer[nextWriteIndex], value, true);
|
4783
|
+
}
|
4784
|
+
|
4785
|
+
nextWriteIndex++;
|
4786
|
+
|
4787
|
+
while (nextWriteIndex < buffer.length) {
|
4788
|
+
// In generators, any extra reads from the iterator have the value undefined.
|
4789
|
+
resolveIteratorResultChunk(buffer[nextWriteIndex++], '"$undefined"', true);
|
4790
|
+
}
|
4791
|
+
},
|
4792
|
+
error: function (error) {
|
4793
|
+
closed = true;
|
4794
|
+
|
4795
|
+
if (nextWriteIndex === buffer.length) {
|
4796
|
+
buffer[nextWriteIndex] = createPendingChunk(response);
|
4797
|
+
}
|
4798
|
+
|
4799
|
+
while (nextWriteIndex < buffer.length) {
|
4800
|
+
triggerErrorOnChunk(buffer[nextWriteIndex++], error);
|
4801
|
+
}
|
4802
|
+
}
|
4803
|
+
};
|
4804
|
+
|
4805
|
+
var iterable = _defineProperty({}, ASYNC_ITERATOR, function () {
|
4806
|
+
var nextReadIndex = 0;
|
4807
|
+
return createIterator(function (arg) {
|
4808
|
+
if (arg !== undefined) {
|
4809
|
+
throw new Error('Values cannot be passed to next() of AsyncIterables passed to Client Components.');
|
4810
|
+
}
|
4811
|
+
|
4812
|
+
if (nextReadIndex === buffer.length) {
|
4813
|
+
if (closed) {
|
4814
|
+
// $FlowFixMe[invalid-constructor] Flow doesn't support functions as constructors
|
4815
|
+
return new Chunk(INITIALIZED, {
|
4816
|
+
done: true,
|
4817
|
+
value: undefined
|
4818
|
+
}, null, response);
|
4819
|
+
}
|
4820
|
+
|
4821
|
+
buffer[nextReadIndex] = createPendingChunk(response);
|
4822
|
+
}
|
4823
|
+
|
4824
|
+
return buffer[nextReadIndex++];
|
4825
|
+
});
|
4826
|
+
}); // TODO: If it's a single shot iterator we can optimize memory by cleaning up the buffer after
|
4827
|
+
// reading through the end, but currently we favor code size over this optimization.
|
4828
|
+
|
4829
|
+
|
4830
|
+
var stream = iterator ? iterable[ASYNC_ITERATOR]() : iterable;
|
4831
|
+
resolveStream(response, id, stream, flightController);
|
4832
|
+
return stream;
|
4833
|
+
}
|
4834
|
+
|
4835
|
+
function parseModelString(response, obj, key, value, reference) {
|
3834
4836
|
if (value[0] === '$') {
|
3835
4837
|
switch (value[1]) {
|
3836
4838
|
case '$':
|
@@ -3842,42 +4844,45 @@ function parseModelString(response, obj, key, value) {
|
|
3842
4844
|
case '@':
|
3843
4845
|
{
|
3844
4846
|
// Promise
|
3845
|
-
var
|
3846
|
-
|
3847
|
-
var chunk = getChunk(response, _id);
|
4847
|
+
var id = parseInt(value.slice(2), 16);
|
4848
|
+
var chunk = getChunk(response, id);
|
3848
4849
|
return chunk;
|
3849
4850
|
}
|
3850
4851
|
|
3851
4852
|
case 'F':
|
3852
4853
|
{
|
3853
4854
|
// Server Reference
|
3854
|
-
var
|
4855
|
+
var _ref2 = value.slice(2); // TODO: Just encode this in the reference inline instead of as a model.
|
3855
4856
|
|
3856
4857
|
|
3857
|
-
var metaData = getOutlinedModel(response,
|
4858
|
+
var metaData = getOutlinedModel(response, _ref2, obj, key, createModel);
|
3858
4859
|
return loadServerReference$1(response, metaData.id, metaData.bound, initializingChunk, obj, key);
|
3859
4860
|
}
|
3860
4861
|
|
3861
4862
|
case 'T':
|
3862
4863
|
{
|
3863
4864
|
// Temporary Reference
|
3864
|
-
|
4865
|
+
if (reference === undefined || response._temporaryReferences === undefined) {
|
4866
|
+
throw new Error('Could not reference an opaque temporary reference. ' + 'This is likely due to misconfiguring the temporaryReferences options ' + 'on the server.');
|
4867
|
+
}
|
4868
|
+
|
4869
|
+
return createTemporaryReference(response._temporaryReferences, reference);
|
3865
4870
|
}
|
3866
4871
|
|
3867
4872
|
case 'Q':
|
3868
4873
|
{
|
3869
4874
|
// Map
|
3870
|
-
var
|
4875
|
+
var _ref3 = value.slice(2);
|
3871
4876
|
|
3872
|
-
return getOutlinedModel(response,
|
4877
|
+
return getOutlinedModel(response, _ref3, obj, key, createMap);
|
3873
4878
|
}
|
3874
4879
|
|
3875
4880
|
case 'W':
|
3876
4881
|
{
|
3877
4882
|
// Set
|
3878
|
-
var
|
4883
|
+
var _ref4 = value.slice(2);
|
3879
4884
|
|
3880
|
-
return getOutlinedModel(response,
|
4885
|
+
return getOutlinedModel(response, _ref4, obj, key, createSet);
|
3881
4886
|
}
|
3882
4887
|
|
3883
4888
|
case 'K':
|
@@ -3902,9 +4907,9 @@ function parseModelString(response, obj, key, value) {
|
|
3902
4907
|
case 'i':
|
3903
4908
|
{
|
3904
4909
|
// Iterator
|
3905
|
-
var
|
4910
|
+
var _ref5 = value.slice(2);
|
3906
4911
|
|
3907
|
-
return getOutlinedModel(response,
|
4912
|
+
return getOutlinedModel(response, _ref5, obj, key, extractIterator);
|
3908
4913
|
}
|
3909
4914
|
|
3910
4915
|
case 'I':
|
@@ -3949,30 +4954,104 @@ function parseModelString(response, obj, key, value) {
|
|
3949
4954
|
}
|
3950
4955
|
}
|
3951
4956
|
|
4957
|
+
{
|
4958
|
+
switch (value[1]) {
|
4959
|
+
case 'A':
|
4960
|
+
return parseTypedArray(response, value, ArrayBuffer, 1, obj, key);
|
4961
|
+
|
4962
|
+
case 'O':
|
4963
|
+
return parseTypedArray(response, value, Int8Array, 1, obj, key);
|
4964
|
+
|
4965
|
+
case 'o':
|
4966
|
+
return parseTypedArray(response, value, Uint8Array, 1, obj, key);
|
4967
|
+
|
4968
|
+
case 'U':
|
4969
|
+
return parseTypedArray(response, value, Uint8ClampedArray, 1, obj, key);
|
4970
|
+
|
4971
|
+
case 'S':
|
4972
|
+
return parseTypedArray(response, value, Int16Array, 2, obj, key);
|
4973
|
+
|
4974
|
+
case 's':
|
4975
|
+
return parseTypedArray(response, value, Uint16Array, 2, obj, key);
|
4976
|
+
|
4977
|
+
case 'L':
|
4978
|
+
return parseTypedArray(response, value, Int32Array, 4, obj, key);
|
4979
|
+
|
4980
|
+
case 'l':
|
4981
|
+
return parseTypedArray(response, value, Uint32Array, 4, obj, key);
|
3952
4982
|
|
3953
|
-
|
3954
|
-
|
4983
|
+
case 'G':
|
4984
|
+
return parseTypedArray(response, value, Float32Array, 4, obj, key);
|
4985
|
+
|
4986
|
+
case 'g':
|
4987
|
+
return parseTypedArray(response, value, Float64Array, 8, obj, key);
|
4988
|
+
|
4989
|
+
case 'M':
|
4990
|
+
return parseTypedArray(response, value, BigInt64Array, 8, obj, key);
|
4991
|
+
|
4992
|
+
case 'm':
|
4993
|
+
return parseTypedArray(response, value, BigUint64Array, 8, obj, key);
|
4994
|
+
|
4995
|
+
case 'V':
|
4996
|
+
return parseTypedArray(response, value, DataView, 1, obj, key);
|
4997
|
+
|
4998
|
+
case 'B':
|
4999
|
+
{
|
5000
|
+
// Blob
|
5001
|
+
var _id = parseInt(value.slice(2), 16);
|
5002
|
+
|
5003
|
+
var prefix = response._prefix;
|
5004
|
+
var blobKey = prefix + _id; // We should have this backingEntry in the store already because we emitted
|
5005
|
+
// it before referencing it. It should be a Blob.
|
5006
|
+
|
5007
|
+
var backingEntry = response._formData.get(blobKey);
|
5008
|
+
|
5009
|
+
return backingEntry;
|
5010
|
+
}
|
5011
|
+
}
|
5012
|
+
}
|
5013
|
+
|
5014
|
+
{
|
5015
|
+
switch (value[1]) {
|
5016
|
+
case 'R':
|
5017
|
+
{
|
5018
|
+
return parseReadableStream(response, value, undefined);
|
5019
|
+
}
|
5020
|
+
|
5021
|
+
case 'r':
|
5022
|
+
{
|
5023
|
+
return parseReadableStream(response, value, 'bytes');
|
5024
|
+
}
|
5025
|
+
|
5026
|
+
case 'X':
|
5027
|
+
{
|
5028
|
+
return parseAsyncIterable(response, value, false);
|
5029
|
+
}
|
5030
|
+
|
5031
|
+
case 'x':
|
5032
|
+
{
|
5033
|
+
return parseAsyncIterable(response, value, true);
|
5034
|
+
}
|
5035
|
+
}
|
5036
|
+
} // We assume that anything else is a reference ID.
|
5037
|
+
|
5038
|
+
|
5039
|
+
var ref = value.slice(1);
|
5040
|
+
return getOutlinedModel(response, ref, obj, key, createModel);
|
3955
5041
|
}
|
3956
5042
|
|
3957
5043
|
return value;
|
3958
5044
|
}
|
3959
5045
|
|
3960
|
-
function createResponse(bundlerConfig, formFieldPrefix) {
|
3961
|
-
var backingFormData = arguments.length >
|
5046
|
+
function createResponse(bundlerConfig, formFieldPrefix, temporaryReferences) {
|
5047
|
+
var backingFormData = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : new FormData();
|
3962
5048
|
var chunks = new Map();
|
3963
5049
|
var response = {
|
3964
5050
|
_bundlerConfig: bundlerConfig,
|
3965
5051
|
_prefix: formFieldPrefix,
|
3966
5052
|
_formData: backingFormData,
|
3967
5053
|
_chunks: chunks,
|
3968
|
-
|
3969
|
-
if (typeof value === 'string') {
|
3970
|
-
// We can't use .bind here because we need the "this" value.
|
3971
|
-
return parseModelString(response, this, key, value);
|
3972
|
-
}
|
3973
|
-
|
3974
|
-
return value;
|
3975
|
-
}
|
5054
|
+
_temporaryReferences: temporaryReferences
|
3976
5055
|
};
|
3977
5056
|
return response;
|
3978
5057
|
}
|
@@ -4012,7 +5091,7 @@ function loadServerReference(bundlerConfig, id, bound) {
|
|
4012
5091
|
|
4013
5092
|
function decodeBoundActionMetaData(body, serverManifest, formFieldPrefix) {
|
4014
5093
|
// The data for this reference is encoded in multiple fields under this prefix.
|
4015
|
-
var actionResponse = createResponse(serverManifest, formFieldPrefix, body);
|
5094
|
+
var actionResponse = createResponse(serverManifest, formFieldPrefix, undefined, body);
|
4016
5095
|
close(actionResponse);
|
4017
5096
|
var refPromise = getRoot(actionResponse); // Force it to initialize
|
4018
5097
|
// $FlowFixMe
|
@@ -4107,7 +5186,7 @@ function decodeFormState(actionResult, body, serverManifest) {
|
|
4107
5186
|
}
|
4108
5187
|
|
4109
5188
|
function renderToReadableStream(model, webpackMap, options) {
|
4110
|
-
var request = createRequest(model, webpackMap, options ? options.onError : undefined, options ? options.identifierPrefix : undefined, options ? options.onPostpone : undefined, options ? options.environmentName : undefined);
|
5189
|
+
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);
|
4111
5190
|
|
4112
5191
|
if (options && options.signal) {
|
4113
5192
|
var signal = options.signal;
|
@@ -4143,20 +5222,21 @@ function renderToReadableStream(model, webpackMap, options) {
|
|
4143
5222
|
return stream;
|
4144
5223
|
}
|
4145
5224
|
|
4146
|
-
function decodeReply(body, webpackMap) {
|
5225
|
+
function decodeReply(body, webpackMap, options) {
|
4147
5226
|
if (typeof body === 'string') {
|
4148
5227
|
var form = new FormData();
|
4149
5228
|
form.append('0', body);
|
4150
5229
|
body = form;
|
4151
5230
|
}
|
4152
5231
|
|
4153
|
-
var response = createResponse(webpackMap, '', body);
|
5232
|
+
var response = createResponse(webpackMap, '', options ? options.temporaryReferences : undefined, body);
|
4154
5233
|
var root = getRoot(response);
|
4155
5234
|
close(response);
|
4156
5235
|
return root;
|
4157
5236
|
}
|
4158
5237
|
|
4159
5238
|
exports.createClientModuleProxy = createClientModuleProxy;
|
5239
|
+
exports.createTemporaryReferenceSet = createTemporaryReferenceSet;
|
4160
5240
|
exports.decodeAction = decodeAction;
|
4161
5241
|
exports.decodeFormState = decodeFormState;
|
4162
5242
|
exports.decodeReply = decodeReply;
|