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
@@ -18,8 +18,20 @@ var util = require('util');
|
|
18
18
|
var ReactDOM = require('react-dom');
|
19
19
|
var React = require('react');
|
20
20
|
|
21
|
-
|
22
|
-
|
21
|
+
function _defineProperty(obj, key, value) {
|
22
|
+
if (key in obj) {
|
23
|
+
Object.defineProperty(obj, key, {
|
24
|
+
value: value,
|
25
|
+
enumerable: true,
|
26
|
+
configurable: true,
|
27
|
+
writable: true
|
28
|
+
});
|
29
|
+
} else {
|
30
|
+
obj[key] = value;
|
31
|
+
}
|
32
|
+
|
33
|
+
return obj;
|
34
|
+
}
|
23
35
|
|
24
36
|
function createStringDecoder() {
|
25
37
|
return new util.TextDecoder();
|
@@ -813,20 +825,11 @@ function describeObjectForErrorMessage(objectOrArray, expandedName) {
|
|
813
825
|
return '\n ' + str;
|
814
826
|
}
|
815
827
|
|
816
|
-
function writeTemporaryReference(set, object) {
|
817
|
-
|
818
|
-
// object. This ensures that we always generate a deterministic encoding of
|
819
|
-
// each slot in the reply for cacheability.
|
820
|
-
var newId = set.length;
|
821
|
-
set.push(object);
|
822
|
-
return newId;
|
828
|
+
function writeTemporaryReference(set, reference, object) {
|
829
|
+
set.set(reference, object);
|
823
830
|
}
|
824
|
-
function readTemporaryReference(set,
|
825
|
-
|
826
|
-
throw new Error("The RSC response contained a reference that doesn't exist in the temporary reference set. " + 'Always pass the matching set that was used to create the reply when parsing its response.');
|
827
|
-
}
|
828
|
-
|
829
|
-
return set[id];
|
831
|
+
function readTemporaryReference(set, reference) {
|
832
|
+
return set.get(reference);
|
830
833
|
}
|
831
834
|
|
832
835
|
var ObjectPrototype = Object.prototype;
|
@@ -845,8 +848,8 @@ function serializeServerReferenceID(id) {
|
|
845
848
|
return '$F' + id.toString(16);
|
846
849
|
}
|
847
850
|
|
848
|
-
function
|
849
|
-
return '$T'
|
851
|
+
function serializeTemporaryReferenceMarker() {
|
852
|
+
return '$T';
|
850
853
|
}
|
851
854
|
|
852
855
|
function serializeFormDataReference(id) {
|
@@ -894,6 +897,10 @@ function serializeSetID(id) {
|
|
894
897
|
return '$W' + id.toString(16);
|
895
898
|
}
|
896
899
|
|
900
|
+
function serializeBlobID(id) {
|
901
|
+
return '$B' + id.toString(16);
|
902
|
+
}
|
903
|
+
|
897
904
|
function serializeIteratorID(id) {
|
898
905
|
return '$i' + id.toString(16);
|
899
906
|
}
|
@@ -912,6 +919,170 @@ function processReply(root, formFieldPrefix, temporaryReferences, resolve, rejec
|
|
912
919
|
var nextPartId = 1;
|
913
920
|
var pendingParts = 0;
|
914
921
|
var formData = null;
|
922
|
+
var writtenObjects = new WeakMap();
|
923
|
+
var modelRoot = root;
|
924
|
+
|
925
|
+
function serializeTypedArray(tag, typedArray) {
|
926
|
+
var blob = new Blob([// We should be able to pass the buffer straight through but Node < 18 treat
|
927
|
+
// multi-byte array blobs differently so we first convert it to single-byte.
|
928
|
+
new Uint8Array(typedArray.buffer, typedArray.byteOffset, typedArray.byteLength)]);
|
929
|
+
var blobId = nextPartId++;
|
930
|
+
|
931
|
+
if (formData === null) {
|
932
|
+
formData = new FormData();
|
933
|
+
}
|
934
|
+
|
935
|
+
formData.append(formFieldPrefix + blobId, blob);
|
936
|
+
return '$' + tag + blobId.toString(16);
|
937
|
+
}
|
938
|
+
|
939
|
+
function serializeBinaryReader(reader) {
|
940
|
+
if (formData === null) {
|
941
|
+
// Upgrade to use FormData to allow us to stream this value.
|
942
|
+
formData = new FormData();
|
943
|
+
}
|
944
|
+
|
945
|
+
var data = formData;
|
946
|
+
pendingParts++;
|
947
|
+
var streamId = nextPartId++;
|
948
|
+
var buffer = [];
|
949
|
+
|
950
|
+
function progress(entry) {
|
951
|
+
if (entry.done) {
|
952
|
+
var blobId = nextPartId++; // eslint-disable-next-line react-internal/safe-string-coercion
|
953
|
+
|
954
|
+
data.append(formFieldPrefix + blobId, new Blob(buffer)); // eslint-disable-next-line react-internal/safe-string-coercion
|
955
|
+
|
956
|
+
data.append(formFieldPrefix + streamId, '"$o' + blobId.toString(16) + '"'); // eslint-disable-next-line react-internal/safe-string-coercion
|
957
|
+
|
958
|
+
data.append(formFieldPrefix + streamId, 'C'); // Close signal
|
959
|
+
|
960
|
+
pendingParts--;
|
961
|
+
|
962
|
+
if (pendingParts === 0) {
|
963
|
+
resolve(data);
|
964
|
+
}
|
965
|
+
} else {
|
966
|
+
buffer.push(entry.value);
|
967
|
+
reader.read(new Uint8Array(1024)).then(progress, reject);
|
968
|
+
}
|
969
|
+
}
|
970
|
+
|
971
|
+
reader.read(new Uint8Array(1024)).then(progress, reject);
|
972
|
+
return '$r' + streamId.toString(16);
|
973
|
+
}
|
974
|
+
|
975
|
+
function serializeReader(reader) {
|
976
|
+
if (formData === null) {
|
977
|
+
// Upgrade to use FormData to allow us to stream this value.
|
978
|
+
formData = new FormData();
|
979
|
+
}
|
980
|
+
|
981
|
+
var data = formData;
|
982
|
+
pendingParts++;
|
983
|
+
var streamId = nextPartId++;
|
984
|
+
|
985
|
+
function progress(entry) {
|
986
|
+
if (entry.done) {
|
987
|
+
// eslint-disable-next-line react-internal/safe-string-coercion
|
988
|
+
data.append(formFieldPrefix + streamId, 'C'); // Close signal
|
989
|
+
|
990
|
+
pendingParts--;
|
991
|
+
|
992
|
+
if (pendingParts === 0) {
|
993
|
+
resolve(data);
|
994
|
+
}
|
995
|
+
} else {
|
996
|
+
try {
|
997
|
+
// $FlowFixMe[incompatible-type]: While plain JSON can return undefined we never do here.
|
998
|
+
var partJSON = JSON.stringify(entry.value, resolveToJSON); // eslint-disable-next-line react-internal/safe-string-coercion
|
999
|
+
|
1000
|
+
data.append(formFieldPrefix + streamId, partJSON);
|
1001
|
+
reader.read().then(progress, reject);
|
1002
|
+
} catch (x) {
|
1003
|
+
reject(x);
|
1004
|
+
}
|
1005
|
+
}
|
1006
|
+
}
|
1007
|
+
|
1008
|
+
reader.read().then(progress, reject);
|
1009
|
+
return '$R' + streamId.toString(16);
|
1010
|
+
}
|
1011
|
+
|
1012
|
+
function serializeReadableStream(stream) {
|
1013
|
+
// Detect if this is a BYOB stream. BYOB streams should be able to be read as bytes on the
|
1014
|
+
// receiving side. For binary streams, we serialize them as plain Blobs.
|
1015
|
+
var binaryReader;
|
1016
|
+
|
1017
|
+
try {
|
1018
|
+
// $FlowFixMe[extra-arg]: This argument is accepted.
|
1019
|
+
binaryReader = stream.getReader({
|
1020
|
+
mode: 'byob'
|
1021
|
+
});
|
1022
|
+
} catch (x) {
|
1023
|
+
return serializeReader(stream.getReader());
|
1024
|
+
}
|
1025
|
+
|
1026
|
+
return serializeBinaryReader(binaryReader);
|
1027
|
+
}
|
1028
|
+
|
1029
|
+
function serializeAsyncIterable(iterable, iterator) {
|
1030
|
+
if (formData === null) {
|
1031
|
+
// Upgrade to use FormData to allow us to stream this value.
|
1032
|
+
formData = new FormData();
|
1033
|
+
}
|
1034
|
+
|
1035
|
+
var data = formData;
|
1036
|
+
pendingParts++;
|
1037
|
+
var streamId = nextPartId++; // Generators/Iterators are Iterables but they're also their own iterator
|
1038
|
+
// functions. If that's the case, we treat them as single-shot. Otherwise,
|
1039
|
+
// we assume that this iterable might be a multi-shot and allow it to be
|
1040
|
+
// iterated more than once on the receiving server.
|
1041
|
+
|
1042
|
+
var isIterator = iterable === iterator; // There's a race condition between when the stream is aborted and when the promise
|
1043
|
+
// resolves so we track whether we already aborted it to avoid writing twice.
|
1044
|
+
|
1045
|
+
function progress(entry) {
|
1046
|
+
if (entry.done) {
|
1047
|
+
if (entry.value === undefined) {
|
1048
|
+
// eslint-disable-next-line react-internal/safe-string-coercion
|
1049
|
+
data.append(formFieldPrefix + streamId, 'C'); // Close signal
|
1050
|
+
} else {
|
1051
|
+
// Unlike streams, the last value may not be undefined. If it's not
|
1052
|
+
// we outline it and encode a reference to it in the closing instruction.
|
1053
|
+
try {
|
1054
|
+
// $FlowFixMe[incompatible-type]: While plain JSON can return undefined we never do here.
|
1055
|
+
var partJSON = JSON.stringify(entry.value, resolveToJSON);
|
1056
|
+
data.append(formFieldPrefix + streamId, 'C' + partJSON); // Close signal
|
1057
|
+
} catch (x) {
|
1058
|
+
reject(x);
|
1059
|
+
return;
|
1060
|
+
}
|
1061
|
+
}
|
1062
|
+
|
1063
|
+
pendingParts--;
|
1064
|
+
|
1065
|
+
if (pendingParts === 0) {
|
1066
|
+
resolve(data);
|
1067
|
+
}
|
1068
|
+
} else {
|
1069
|
+
try {
|
1070
|
+
// $FlowFixMe[incompatible-type]: While plain JSON can return undefined we never do here.
|
1071
|
+
var _partJSON = JSON.stringify(entry.value, resolveToJSON); // eslint-disable-next-line react-internal/safe-string-coercion
|
1072
|
+
|
1073
|
+
|
1074
|
+
data.append(formFieldPrefix + streamId, _partJSON);
|
1075
|
+
iterator.next().then(progress, reject);
|
1076
|
+
} catch (x) {
|
1077
|
+
reject(x);
|
1078
|
+
return;
|
1079
|
+
}
|
1080
|
+
}
|
1081
|
+
}
|
1082
|
+
|
1083
|
+
iterator.next().then(progress, reject);
|
1084
|
+
return '$' + (isIterator ? 'x' : 'X') + streamId.toString(16);
|
1085
|
+
}
|
915
1086
|
|
916
1087
|
function resolveToJSON(key, value) {
|
917
1088
|
var parent = this; // Make sure that `parent[key]` wasn't JSONified before `value` was passed to us
|
@@ -937,11 +1108,21 @@ function processReply(root, formFieldPrefix, temporaryReferences, resolve, rejec
|
|
937
1108
|
switch (value.$$typeof) {
|
938
1109
|
case REACT_ELEMENT_TYPE:
|
939
1110
|
{
|
940
|
-
if (temporaryReferences
|
941
|
-
|
1111
|
+
if (temporaryReferences !== undefined && key.indexOf(':') === -1) {
|
1112
|
+
// TODO: If the property name contains a colon, we don't dedupe. Escape instead.
|
1113
|
+
var parentReference = writtenObjects.get(parent);
|
1114
|
+
|
1115
|
+
if (parentReference !== undefined) {
|
1116
|
+
// If the parent has a reference, we can refer to this object indirectly
|
1117
|
+
// through the property name inside that parent.
|
1118
|
+
var reference = parentReference + ':' + key; // Store this object so that the server can refer to it later in responses.
|
1119
|
+
|
1120
|
+
writeTemporaryReference(temporaryReferences, reference, value);
|
1121
|
+
return serializeTemporaryReferenceMarker();
|
1122
|
+
}
|
942
1123
|
}
|
943
1124
|
|
944
|
-
|
1125
|
+
throw new Error('React Element cannot be passed to Server Functions from the Client without a ' + 'temporary reference set. Pass a TemporaryReferenceSet to the options.' + (describeObjectForErrorMessage(parent, key) ));
|
945
1126
|
}
|
946
1127
|
|
947
1128
|
case REACT_LAZY_TYPE:
|
@@ -963,7 +1144,7 @@ function processReply(root, formFieldPrefix, temporaryReferences, resolve, rejec
|
|
963
1144
|
// because it ensures a more deterministic encoding.
|
964
1145
|
|
965
1146
|
var lazyId = nextPartId++;
|
966
|
-
var partJSON =
|
1147
|
+
var partJSON = serializeModel(resolvedModel, lazyId); // $FlowFixMe[incompatible-type] We know it's not null because we assigned it above.
|
967
1148
|
|
968
1149
|
var data = formData; // eslint-disable-next-line react-internal/safe-string-coercion
|
969
1150
|
|
@@ -982,7 +1163,7 @@ function processReply(root, formFieldPrefix, temporaryReferences, resolve, rejec
|
|
982
1163
|
// While the first promise resolved, its value isn't necessarily what we'll
|
983
1164
|
// resolve into because we might suspend again.
|
984
1165
|
try {
|
985
|
-
var _partJSON2 =
|
1166
|
+
var _partJSON2 = serializeModel(value, _lazyId); // $FlowFixMe[incompatible-type] We know it's not null because we assigned it above.
|
986
1167
|
|
987
1168
|
|
988
1169
|
var _data = formData; // eslint-disable-next-line react-internal/safe-string-coercion
|
@@ -1028,7 +1209,7 @@ function processReply(root, formFieldPrefix, temporaryReferences, resolve, rejec
|
|
1028
1209
|
|
1029
1210
|
_thenable.then(function (partValue) {
|
1030
1211
|
try {
|
1031
|
-
var _partJSON3 =
|
1212
|
+
var _partJSON3 = serializeModel(partValue, promiseId); // $FlowFixMe[incompatible-type] We know it's not null because we assigned it above.
|
1032
1213
|
|
1033
1214
|
|
1034
1215
|
var _data2 = formData; // eslint-disable-next-line react-internal/safe-string-coercion
|
@@ -1050,6 +1231,36 @@ function processReply(root, formFieldPrefix, temporaryReferences, resolve, rejec
|
|
1050
1231
|
return serializePromiseID(promiseId);
|
1051
1232
|
}
|
1052
1233
|
|
1234
|
+
var existingReference = writtenObjects.get(value);
|
1235
|
+
|
1236
|
+
if (existingReference !== undefined) {
|
1237
|
+
if (modelRoot === value) {
|
1238
|
+
// This is the ID we're currently emitting so we need to write it
|
1239
|
+
// once but if we discover it again, we refer to it by id.
|
1240
|
+
modelRoot = null;
|
1241
|
+
} else {
|
1242
|
+
// We've already emitted this as an outlined object, so we can
|
1243
|
+
// just refer to that by its existing ID.
|
1244
|
+
return existingReference;
|
1245
|
+
}
|
1246
|
+
} else if (key.indexOf(':') === -1) {
|
1247
|
+
// TODO: If the property name contains a colon, we don't dedupe. Escape instead.
|
1248
|
+
var _parentReference = writtenObjects.get(parent);
|
1249
|
+
|
1250
|
+
if (_parentReference !== undefined) {
|
1251
|
+
// If the parent has a reference, we can refer to this object indirectly
|
1252
|
+
// through the property name inside that parent.
|
1253
|
+
var _reference = _parentReference + ':' + key;
|
1254
|
+
|
1255
|
+
writtenObjects.set(value, _reference);
|
1256
|
+
|
1257
|
+
if (temporaryReferences !== undefined) {
|
1258
|
+
// Store this object so that the server can refer to it later in responses.
|
1259
|
+
writeTemporaryReference(temporaryReferences, _reference, value);
|
1260
|
+
}
|
1261
|
+
}
|
1262
|
+
}
|
1263
|
+
|
1053
1264
|
if (isArray(value)) {
|
1054
1265
|
// $FlowFixMe[incompatible-return]
|
1055
1266
|
return value;
|
@@ -1076,29 +1287,117 @@ function processReply(root, formFieldPrefix, temporaryReferences, resolve, rejec
|
|
1076
1287
|
}
|
1077
1288
|
|
1078
1289
|
if (value instanceof Map) {
|
1079
|
-
var
|
1290
|
+
var mapId = nextPartId++;
|
1291
|
+
|
1292
|
+
var _partJSON4 = serializeModel(Array.from(value), mapId);
|
1080
1293
|
|
1081
1294
|
if (formData === null) {
|
1082
1295
|
formData = new FormData();
|
1083
1296
|
}
|
1084
1297
|
|
1085
|
-
var mapId = nextPartId++;
|
1086
1298
|
formData.append(formFieldPrefix + mapId, _partJSON4);
|
1087
1299
|
return serializeMapID(mapId);
|
1088
1300
|
}
|
1089
1301
|
|
1090
1302
|
if (value instanceof Set) {
|
1091
|
-
var
|
1303
|
+
var setId = nextPartId++;
|
1304
|
+
|
1305
|
+
var _partJSON5 = serializeModel(Array.from(value), setId);
|
1092
1306
|
|
1093
1307
|
if (formData === null) {
|
1094
1308
|
formData = new FormData();
|
1095
1309
|
}
|
1096
1310
|
|
1097
|
-
var setId = nextPartId++;
|
1098
1311
|
formData.append(formFieldPrefix + setId, _partJSON5);
|
1099
1312
|
return serializeSetID(setId);
|
1100
1313
|
}
|
1101
1314
|
|
1315
|
+
{
|
1316
|
+
if (value instanceof ArrayBuffer) {
|
1317
|
+
var blob = new Blob([value]);
|
1318
|
+
var blobId = nextPartId++;
|
1319
|
+
|
1320
|
+
if (formData === null) {
|
1321
|
+
formData = new FormData();
|
1322
|
+
}
|
1323
|
+
|
1324
|
+
formData.append(formFieldPrefix + blobId, blob);
|
1325
|
+
return '$' + 'A' + blobId.toString(16);
|
1326
|
+
}
|
1327
|
+
|
1328
|
+
if (value instanceof Int8Array) {
|
1329
|
+
// char
|
1330
|
+
return serializeTypedArray('O', value);
|
1331
|
+
}
|
1332
|
+
|
1333
|
+
if (value instanceof Uint8Array) {
|
1334
|
+
// unsigned char
|
1335
|
+
return serializeTypedArray('o', value);
|
1336
|
+
}
|
1337
|
+
|
1338
|
+
if (value instanceof Uint8ClampedArray) {
|
1339
|
+
// unsigned clamped char
|
1340
|
+
return serializeTypedArray('U', value);
|
1341
|
+
}
|
1342
|
+
|
1343
|
+
if (value instanceof Int16Array) {
|
1344
|
+
// sort
|
1345
|
+
return serializeTypedArray('S', value);
|
1346
|
+
}
|
1347
|
+
|
1348
|
+
if (value instanceof Uint16Array) {
|
1349
|
+
// unsigned short
|
1350
|
+
return serializeTypedArray('s', value);
|
1351
|
+
}
|
1352
|
+
|
1353
|
+
if (value instanceof Int32Array) {
|
1354
|
+
// long
|
1355
|
+
return serializeTypedArray('L', value);
|
1356
|
+
}
|
1357
|
+
|
1358
|
+
if (value instanceof Uint32Array) {
|
1359
|
+
// unsigned long
|
1360
|
+
return serializeTypedArray('l', value);
|
1361
|
+
}
|
1362
|
+
|
1363
|
+
if (value instanceof Float32Array) {
|
1364
|
+
// float
|
1365
|
+
return serializeTypedArray('G', value);
|
1366
|
+
}
|
1367
|
+
|
1368
|
+
if (value instanceof Float64Array) {
|
1369
|
+
// double
|
1370
|
+
return serializeTypedArray('g', value);
|
1371
|
+
}
|
1372
|
+
|
1373
|
+
if (value instanceof BigInt64Array) {
|
1374
|
+
// number
|
1375
|
+
return serializeTypedArray('M', value);
|
1376
|
+
}
|
1377
|
+
|
1378
|
+
if (value instanceof BigUint64Array) {
|
1379
|
+
// unsigned number
|
1380
|
+
// We use "m" instead of "n" since JSON can start with "null"
|
1381
|
+
return serializeTypedArray('m', value);
|
1382
|
+
}
|
1383
|
+
|
1384
|
+
if (value instanceof DataView) {
|
1385
|
+
return serializeTypedArray('V', value);
|
1386
|
+
} // TODO: Blob is not available in old Node/browsers. Remove the typeof check later.
|
1387
|
+
|
1388
|
+
|
1389
|
+
if (typeof Blob === 'function' && value instanceof Blob) {
|
1390
|
+
if (formData === null) {
|
1391
|
+
formData = new FormData();
|
1392
|
+
}
|
1393
|
+
|
1394
|
+
var _blobId = nextPartId++;
|
1395
|
+
|
1396
|
+
formData.append(formFieldPrefix + _blobId, value);
|
1397
|
+
return serializeBlobID(_blobId);
|
1398
|
+
}
|
1399
|
+
}
|
1400
|
+
|
1102
1401
|
var iteratorFn = getIteratorFn(value);
|
1103
1402
|
|
1104
1403
|
if (iteratorFn) {
|
@@ -1106,13 +1405,14 @@ function processReply(root, formFieldPrefix, temporaryReferences, resolve, rejec
|
|
1106
1405
|
|
1107
1406
|
if (iterator === value) {
|
1108
1407
|
// Iterator, not Iterable
|
1109
|
-
var
|
1408
|
+
var iteratorId = nextPartId++;
|
1409
|
+
|
1410
|
+
var _partJSON6 = serializeModel(Array.from(iterator), iteratorId);
|
1110
1411
|
|
1111
1412
|
if (formData === null) {
|
1112
1413
|
formData = new FormData();
|
1113
1414
|
}
|
1114
1415
|
|
1115
|
-
var iteratorId = nextPartId++;
|
1116
1416
|
formData.append(formFieldPrefix + iteratorId, _partJSON6);
|
1117
1417
|
return serializeIteratorID(iteratorId);
|
1118
1418
|
}
|
@@ -1120,16 +1420,31 @@ function processReply(root, formFieldPrefix, temporaryReferences, resolve, rejec
|
|
1120
1420
|
return Array.from(iterator);
|
1121
1421
|
}
|
1122
1422
|
|
1423
|
+
{
|
1424
|
+
// TODO: ReadableStream is not available in old Node. Remove the typeof check later.
|
1425
|
+
if (typeof ReadableStream === 'function' && value instanceof ReadableStream) {
|
1426
|
+
return serializeReadableStream(value);
|
1427
|
+
}
|
1428
|
+
|
1429
|
+
var getAsyncIterator = value[ASYNC_ITERATOR];
|
1430
|
+
|
1431
|
+
if (typeof getAsyncIterator === 'function') {
|
1432
|
+
// We treat AsyncIterables as a Fragment and as such we might need to key them.
|
1433
|
+
return serializeAsyncIterable(value, getAsyncIterator.call(value));
|
1434
|
+
}
|
1435
|
+
} // Verify that this is a simple plain object.
|
1436
|
+
|
1123
1437
|
|
1124
1438
|
var proto = getPrototypeOf(value);
|
1125
1439
|
|
1126
1440
|
if (proto !== ObjectPrototype && (proto === null || getPrototypeOf(proto) !== null)) {
|
1127
1441
|
if (temporaryReferences === undefined) {
|
1128
1442
|
throw new Error('Only plain objects, and a few built-ins, can be passed to Server Actions. ' + 'Classes or null prototypes are not supported.');
|
1129
|
-
} // We
|
1443
|
+
} // We will have written this object to the temporary reference set above
|
1444
|
+
// so we can replace it with a marker to refer to this slot later.
|
1130
1445
|
|
1131
1446
|
|
1132
|
-
return
|
1447
|
+
return serializeTemporaryReferenceMarker();
|
1133
1448
|
}
|
1134
1449
|
|
1135
1450
|
{
|
@@ -1198,19 +1513,41 @@ function processReply(root, formFieldPrefix, temporaryReferences, resolve, rejec
|
|
1198
1513
|
return serializeServerReferenceID(_refId);
|
1199
1514
|
}
|
1200
1515
|
|
1201
|
-
if (temporaryReferences
|
1202
|
-
|
1516
|
+
if (temporaryReferences !== undefined && key.indexOf(':') === -1) {
|
1517
|
+
// TODO: If the property name contains a colon, we don't dedupe. Escape instead.
|
1518
|
+
var _parentReference2 = writtenObjects.get(parent);
|
1519
|
+
|
1520
|
+
if (_parentReference2 !== undefined) {
|
1521
|
+
// If the parent has a reference, we can refer to this object indirectly
|
1522
|
+
// through the property name inside that parent.
|
1523
|
+
var _reference2 = _parentReference2 + ':' + key; // Store this object so that the server can refer to it later in responses.
|
1524
|
+
|
1525
|
+
|
1526
|
+
writeTemporaryReference(temporaryReferences, _reference2, value);
|
1527
|
+
return serializeTemporaryReferenceMarker();
|
1528
|
+
}
|
1203
1529
|
}
|
1204
1530
|
|
1205
|
-
|
1531
|
+
throw new Error('Client Functions cannot be passed directly to Server Functions. ' + 'Only Functions passed from the Server can be passed back again.');
|
1206
1532
|
}
|
1207
1533
|
|
1208
1534
|
if (typeof value === 'symbol') {
|
1209
|
-
if (temporaryReferences
|
1210
|
-
|
1535
|
+
if (temporaryReferences !== undefined && key.indexOf(':') === -1) {
|
1536
|
+
// TODO: If the property name contains a colon, we don't dedupe. Escape instead.
|
1537
|
+
var _parentReference3 = writtenObjects.get(parent);
|
1538
|
+
|
1539
|
+
if (_parentReference3 !== undefined) {
|
1540
|
+
// If the parent has a reference, we can refer to this object indirectly
|
1541
|
+
// through the property name inside that parent.
|
1542
|
+
var _reference3 = _parentReference3 + ':' + key; // Store this object so that the server can refer to it later in responses.
|
1543
|
+
|
1544
|
+
|
1545
|
+
writeTemporaryReference(temporaryReferences, _reference3, value);
|
1546
|
+
return serializeTemporaryReferenceMarker();
|
1547
|
+
}
|
1211
1548
|
}
|
1212
1549
|
|
1213
|
-
|
1550
|
+
throw new Error('Symbols cannot be passed to a Server Function without a ' + 'temporary reference set. Pass a TemporaryReferenceSet to the options.' + (describeObjectForErrorMessage(parent, key) ));
|
1214
1551
|
}
|
1215
1552
|
|
1216
1553
|
if (typeof value === 'bigint') {
|
@@ -1218,10 +1555,25 @@ function processReply(root, formFieldPrefix, temporaryReferences, resolve, rejec
|
|
1218
1555
|
}
|
1219
1556
|
|
1220
1557
|
throw new Error("Type " + typeof value + " is not supported as an argument to a Server Function.");
|
1221
|
-
}
|
1558
|
+
}
|
1559
|
+
|
1560
|
+
function serializeModel(model, id) {
|
1561
|
+
if (typeof model === 'object' && model !== null) {
|
1562
|
+
var reference = serializeByValueID(id);
|
1563
|
+
writtenObjects.set(model, reference);
|
1222
1564
|
|
1565
|
+
if (temporaryReferences !== undefined) {
|
1566
|
+
// Store this object so that the server can refer to it later in responses.
|
1567
|
+
writeTemporaryReference(temporaryReferences, reference, model);
|
1568
|
+
}
|
1569
|
+
}
|
1570
|
+
|
1571
|
+
modelRoot = model; // $FlowFixMe[incompatible-return] it's not going to be undefined because we'll encode it.
|
1572
|
+
|
1573
|
+
return JSON.stringify(model, resolveToJSON);
|
1574
|
+
}
|
1223
1575
|
|
1224
|
-
var json =
|
1576
|
+
var json = serializeModel(root, 0);
|
1225
1577
|
|
1226
1578
|
if (formData === null) {
|
1227
1579
|
// If it's a simple data structure, we just use plain JSON.
|
@@ -1647,6 +1999,14 @@ function wakeChunkIfInitialized(chunk, resolveListeners, rejectListeners) {
|
|
1647
1999
|
|
1648
2000
|
function triggerErrorOnChunk(chunk, error) {
|
1649
2001
|
if (chunk.status !== PENDING && chunk.status !== BLOCKED) {
|
2002
|
+
{
|
2003
|
+
// If we get more data to an already resolved ID, we assume that it's
|
2004
|
+
// a stream chunk since any other row shouldn't have more than one entry.
|
2005
|
+
var streamChunk = chunk;
|
2006
|
+
var controller = streamChunk.reason; // $FlowFixMe[incompatible-call]: The error method should accept mixed.
|
2007
|
+
|
2008
|
+
controller.error(error);
|
2009
|
+
}
|
1650
2010
|
|
1651
2011
|
return;
|
1652
2012
|
}
|
@@ -1676,8 +2036,48 @@ function createInitializedTextChunk(response, value) {
|
|
1676
2036
|
return new Chunk(INITIALIZED, value, null, response);
|
1677
2037
|
}
|
1678
2038
|
|
2039
|
+
function createInitializedBufferChunk(response, value) {
|
2040
|
+
// $FlowFixMe[invalid-constructor] Flow doesn't support functions as constructors
|
2041
|
+
return new Chunk(INITIALIZED, value, null, response);
|
2042
|
+
}
|
2043
|
+
|
2044
|
+
function createInitializedIteratorResultChunk(response, value, done) {
|
2045
|
+
// $FlowFixMe[invalid-constructor] Flow doesn't support functions as constructors
|
2046
|
+
return new Chunk(INITIALIZED, {
|
2047
|
+
done: done,
|
2048
|
+
value: value
|
2049
|
+
}, null, response);
|
2050
|
+
}
|
2051
|
+
|
2052
|
+
function createInitializedStreamChunk(response, value, controller) {
|
2053
|
+
// We use the reason field to stash the controller since we already have that
|
2054
|
+
// field. It's a bit of a hack but efficient.
|
2055
|
+
// $FlowFixMe[invalid-constructor] Flow doesn't support functions as constructors
|
2056
|
+
return new Chunk(INITIALIZED, value, controller, response);
|
2057
|
+
}
|
2058
|
+
|
2059
|
+
function createResolvedIteratorResultChunk(response, value, done) {
|
2060
|
+
// To reuse code as much code as possible we add the wrapper element as part of the JSON.
|
2061
|
+
var iteratorResultJSON = (done ? '{"done":true,"value":' : '{"done":false,"value":') + value + '}'; // $FlowFixMe[invalid-constructor] Flow doesn't support functions as constructors
|
2062
|
+
|
2063
|
+
return new Chunk(RESOLVED_MODEL, iteratorResultJSON, null, response);
|
2064
|
+
}
|
2065
|
+
|
2066
|
+
function resolveIteratorResultChunk(chunk, value, done) {
|
2067
|
+
// To reuse code as much code as possible we add the wrapper element as part of the JSON.
|
2068
|
+
var iteratorResultJSON = (done ? '{"done":true,"value":' : '{"done":false,"value":') + value + '}';
|
2069
|
+
resolveModelChunk(chunk, iteratorResultJSON);
|
2070
|
+
}
|
2071
|
+
|
1679
2072
|
function resolveModelChunk(chunk, value) {
|
1680
2073
|
if (chunk.status !== PENDING) {
|
2074
|
+
{
|
2075
|
+
// If we get more data to an already resolved ID, we assume that it's
|
2076
|
+
// a stream chunk since any other row shouldn't have more than one entry.
|
2077
|
+
var streamChunk = chunk;
|
2078
|
+
var controller = streamChunk.reason;
|
2079
|
+
controller.enqueueModel(value);
|
2080
|
+
}
|
1681
2081
|
|
1682
2082
|
return;
|
1683
2083
|
}
|
@@ -1796,7 +2196,8 @@ function nullRefGetter() {
|
|
1796
2196
|
}
|
1797
2197
|
}
|
1798
2198
|
|
1799
|
-
function createElement(type, key, props, owner
|
2199
|
+
function createElement(type, key, props, owner, // DEV-only
|
2200
|
+
stack) // DEV-only
|
1800
2201
|
{
|
1801
2202
|
var element;
|
1802
2203
|
|
@@ -1834,6 +2235,10 @@ function createElement(type, key, props, owner) // DEV-only
|
|
1834
2235
|
writable: true,
|
1835
2236
|
value: null
|
1836
2237
|
});
|
2238
|
+
// _debugInfo later. We could move it into _store which remains mutable.
|
2239
|
+
|
2240
|
+
|
2241
|
+
Object.freeze(element.props);
|
1837
2242
|
}
|
1838
2243
|
|
1839
2244
|
return element;
|
@@ -1867,7 +2272,7 @@ function getChunk(response, id) {
|
|
1867
2272
|
return chunk;
|
1868
2273
|
}
|
1869
2274
|
|
1870
|
-
function createModelResolver(chunk, parentObject, key, cyclic, response, map) {
|
2275
|
+
function createModelResolver(chunk, parentObject, key, cyclic, response, map, path) {
|
1871
2276
|
var blocked;
|
1872
2277
|
|
1873
2278
|
if (initializingChunkBlockedModel) {
|
@@ -1884,6 +2289,10 @@ function createModelResolver(chunk, parentObject, key, cyclic, response, map) {
|
|
1884
2289
|
}
|
1885
2290
|
|
1886
2291
|
return function (value) {
|
2292
|
+
for (var i = 1; i < path.length; i++) {
|
2293
|
+
value = value[path[i]];
|
2294
|
+
}
|
2295
|
+
|
1887
2296
|
parentObject[key] = map(response, value); // If this is the root object for a model reference, where `blocked.value`
|
1888
2297
|
// is a stale `null`, the resolved value can be used directly.
|
1889
2298
|
|
@@ -1944,7 +2353,9 @@ function createServerReferenceProxy(response, metaData) {
|
|
1944
2353
|
return proxy;
|
1945
2354
|
}
|
1946
2355
|
|
1947
|
-
function getOutlinedModel(response,
|
2356
|
+
function getOutlinedModel(response, reference, parentObject, key, map) {
|
2357
|
+
var path = reference.split(':');
|
2358
|
+
var id = parseInt(path[0], 16);
|
1948
2359
|
var chunk = getChunk(response, id);
|
1949
2360
|
|
1950
2361
|
switch (chunk.status) {
|
@@ -1960,7 +2371,13 @@ function getOutlinedModel(response, id, parentObject, key, map) {
|
|
1960
2371
|
|
1961
2372
|
switch (chunk.status) {
|
1962
2373
|
case INITIALIZED:
|
1963
|
-
var
|
2374
|
+
var value = chunk.value;
|
2375
|
+
|
2376
|
+
for (var i = 1; i < path.length; i++) {
|
2377
|
+
value = value[path[i]];
|
2378
|
+
}
|
2379
|
+
|
2380
|
+
var chunkValue = map(response, value);
|
1964
2381
|
|
1965
2382
|
if (chunk._debugInfo) {
|
1966
2383
|
// If we have a direct reference to an object that was rendered by a synchronous
|
@@ -1988,7 +2405,7 @@ function getOutlinedModel(response, id, parentObject, key, map) {
|
|
1988
2405
|
case BLOCKED:
|
1989
2406
|
case CYCLIC:
|
1990
2407
|
var parentChunk = initializingChunk;
|
1991
|
-
chunk.then(createModelResolver(parentChunk, parentObject, key, chunk.status === CYCLIC, response, map), createModelReject(parentChunk));
|
2408
|
+
chunk.then(createModelResolver(parentChunk, parentObject, key, chunk.status === CYCLIC, response, map, path), createModelReject(parentChunk));
|
1992
2409
|
return null;
|
1993
2410
|
|
1994
2411
|
default:
|
@@ -2004,6 +2421,12 @@ function createSet(response, model) {
|
|
2004
2421
|
return new Set(model);
|
2005
2422
|
}
|
2006
2423
|
|
2424
|
+
function createBlob(response, model) {
|
2425
|
+
return new Blob(model.slice(1), {
|
2426
|
+
type: model[0]
|
2427
|
+
});
|
2428
|
+
}
|
2429
|
+
|
2007
2430
|
function createFormData(response, model) {
|
2008
2431
|
var formData = new FormData();
|
2009
2432
|
|
@@ -2071,61 +2494,63 @@ function parseModelString(response, parentObject, key, value) {
|
|
2071
2494
|
case 'F':
|
2072
2495
|
{
|
2073
2496
|
// Server Reference
|
2074
|
-
var
|
2075
|
-
|
2076
|
-
return getOutlinedModel(response, _id2, parentObject, key, createServerReferenceProxy);
|
2497
|
+
var ref = value.slice(2);
|
2498
|
+
return getOutlinedModel(response, ref, parentObject, key, createServerReferenceProxy);
|
2077
2499
|
}
|
2078
2500
|
|
2079
2501
|
case 'T':
|
2080
2502
|
{
|
2081
2503
|
// Temporary Reference
|
2082
|
-
var
|
2083
|
-
|
2504
|
+
var reference = '$' + value.slice(2);
|
2084
2505
|
var temporaryReferences = response._tempRefs;
|
2085
2506
|
|
2086
2507
|
if (temporaryReferences == null) {
|
2087
2508
|
throw new Error('Missing a temporary reference set but the RSC response returned a temporary reference. ' + 'Pass a temporaryReference option with the set that was used with the reply.');
|
2088
2509
|
}
|
2089
2510
|
|
2090
|
-
return readTemporaryReference(temporaryReferences,
|
2511
|
+
return readTemporaryReference(temporaryReferences, reference);
|
2091
2512
|
}
|
2092
2513
|
|
2093
2514
|
case 'Q':
|
2094
2515
|
{
|
2095
2516
|
// Map
|
2096
|
-
var
|
2517
|
+
var _ref = value.slice(2);
|
2097
2518
|
|
2098
|
-
return getOutlinedModel(response,
|
2519
|
+
return getOutlinedModel(response, _ref, parentObject, key, createMap);
|
2099
2520
|
}
|
2100
2521
|
|
2101
2522
|
case 'W':
|
2102
2523
|
{
|
2103
2524
|
// Set
|
2104
|
-
var
|
2525
|
+
var _ref2 = value.slice(2);
|
2105
2526
|
|
2106
|
-
return getOutlinedModel(response,
|
2527
|
+
return getOutlinedModel(response, _ref2, parentObject, key, createSet);
|
2107
2528
|
}
|
2108
2529
|
|
2109
2530
|
case 'B':
|
2110
2531
|
{
|
2532
|
+
// Blob
|
2533
|
+
{
|
2534
|
+
var _ref3 = value.slice(2);
|
2111
2535
|
|
2112
|
-
|
2536
|
+
return getOutlinedModel(response, _ref3, parentObject, key, createBlob);
|
2537
|
+
}
|
2113
2538
|
}
|
2114
2539
|
|
2115
2540
|
case 'K':
|
2116
2541
|
{
|
2117
2542
|
// FormData
|
2118
|
-
var
|
2543
|
+
var _ref4 = value.slice(2);
|
2119
2544
|
|
2120
|
-
return getOutlinedModel(response,
|
2545
|
+
return getOutlinedModel(response, _ref4, parentObject, key, createFormData);
|
2121
2546
|
}
|
2122
2547
|
|
2123
2548
|
case 'i':
|
2124
2549
|
{
|
2125
2550
|
// Iterator
|
2126
|
-
var
|
2551
|
+
var _ref5 = value.slice(2);
|
2127
2552
|
|
2128
|
-
return getOutlinedModel(response,
|
2553
|
+
return getOutlinedModel(response, _ref5, parentObject, key, extractIterator);
|
2129
2554
|
}
|
2130
2555
|
|
2131
2556
|
case 'I':
|
@@ -2189,9 +2614,9 @@ function parseModelString(response, parentObject, key, value) {
|
|
2189
2614
|
default:
|
2190
2615
|
{
|
2191
2616
|
// We assume that anything else is a reference ID.
|
2192
|
-
var
|
2617
|
+
var _ref6 = value.slice(1);
|
2193
2618
|
|
2194
|
-
return getOutlinedModel(response,
|
2619
|
+
return getOutlinedModel(response, _ref6, parentObject, key, createModel);
|
2195
2620
|
}
|
2196
2621
|
}
|
2197
2622
|
}
|
@@ -2252,9 +2677,41 @@ function resolveModel(response, id, model) {
|
|
2252
2677
|
function resolveText(response, id, text) {
|
2253
2678
|
var chunks = response._chunks;
|
2254
2679
|
|
2680
|
+
{
|
2681
|
+
var chunk = chunks.get(id);
|
2682
|
+
|
2683
|
+
if (chunk && chunk.status !== PENDING) {
|
2684
|
+
// If we get more data to an already resolved ID, we assume that it's
|
2685
|
+
// a stream chunk since any other row shouldn't have more than one entry.
|
2686
|
+
var streamChunk = chunk;
|
2687
|
+
var controller = streamChunk.reason;
|
2688
|
+
controller.enqueueValue(text);
|
2689
|
+
return;
|
2690
|
+
}
|
2691
|
+
}
|
2692
|
+
|
2255
2693
|
chunks.set(id, createInitializedTextChunk(response, text));
|
2256
2694
|
}
|
2257
2695
|
|
2696
|
+
function resolveBuffer(response, id, buffer) {
|
2697
|
+
var chunks = response._chunks;
|
2698
|
+
|
2699
|
+
{
|
2700
|
+
var chunk = chunks.get(id);
|
2701
|
+
|
2702
|
+
if (chunk && chunk.status !== PENDING) {
|
2703
|
+
// If we get more data to an already resolved ID, we assume that it's
|
2704
|
+
// a stream chunk since any other row shouldn't have more than one entry.
|
2705
|
+
var streamChunk = chunk;
|
2706
|
+
var controller = streamChunk.reason;
|
2707
|
+
controller.enqueueValue(buffer);
|
2708
|
+
return;
|
2709
|
+
}
|
2710
|
+
}
|
2711
|
+
|
2712
|
+
chunks.set(id, createInitializedBufferChunk(response, buffer));
|
2713
|
+
}
|
2714
|
+
|
2258
2715
|
function resolveModule(response, id, model) {
|
2259
2716
|
var chunks = response._chunks;
|
2260
2717
|
var chunk = chunks.get(id);
|
@@ -2297,6 +2754,245 @@ function resolveModule(response, id, model) {
|
|
2297
2754
|
}
|
2298
2755
|
}
|
2299
2756
|
|
2757
|
+
function resolveStream(response, id, stream, controller) {
|
2758
|
+
var chunks = response._chunks;
|
2759
|
+
var chunk = chunks.get(id);
|
2760
|
+
|
2761
|
+
if (!chunk) {
|
2762
|
+
chunks.set(id, createInitializedStreamChunk(response, stream, controller));
|
2763
|
+
return;
|
2764
|
+
}
|
2765
|
+
|
2766
|
+
if (chunk.status !== PENDING) {
|
2767
|
+
// We already resolved. We didn't expect to see this.
|
2768
|
+
return;
|
2769
|
+
}
|
2770
|
+
|
2771
|
+
var resolveListeners = chunk.value;
|
2772
|
+
var resolvedChunk = chunk;
|
2773
|
+
resolvedChunk.status = INITIALIZED;
|
2774
|
+
resolvedChunk.value = stream;
|
2775
|
+
resolvedChunk.reason = controller;
|
2776
|
+
|
2777
|
+
if (resolveListeners !== null) {
|
2778
|
+
wakeChunk(resolveListeners, chunk.value);
|
2779
|
+
}
|
2780
|
+
}
|
2781
|
+
|
2782
|
+
function startReadableStream(response, id, type) {
|
2783
|
+
var controller = null;
|
2784
|
+
var stream = new ReadableStream({
|
2785
|
+
type: type,
|
2786
|
+
start: function (c) {
|
2787
|
+
controller = c;
|
2788
|
+
}
|
2789
|
+
});
|
2790
|
+
var previousBlockedChunk = null;
|
2791
|
+
var flightController = {
|
2792
|
+
enqueueValue: function (value) {
|
2793
|
+
if (previousBlockedChunk === null) {
|
2794
|
+
controller.enqueue(value);
|
2795
|
+
} else {
|
2796
|
+
// We're still waiting on a previous chunk so we can't enqueue quite yet.
|
2797
|
+
previousBlockedChunk.then(function () {
|
2798
|
+
controller.enqueue(value);
|
2799
|
+
});
|
2800
|
+
}
|
2801
|
+
},
|
2802
|
+
enqueueModel: function (json) {
|
2803
|
+
if (previousBlockedChunk === null) {
|
2804
|
+
// If we're not blocked on any other chunks, we can try to eagerly initialize
|
2805
|
+
// this as a fast-path to avoid awaiting them.
|
2806
|
+
var chunk = createResolvedModelChunk(response, json);
|
2807
|
+
initializeModelChunk(chunk);
|
2808
|
+
var initializedChunk = chunk;
|
2809
|
+
|
2810
|
+
if (initializedChunk.status === INITIALIZED) {
|
2811
|
+
controller.enqueue(initializedChunk.value);
|
2812
|
+
} else {
|
2813
|
+
chunk.then(function (v) {
|
2814
|
+
return controller.enqueue(v);
|
2815
|
+
}, function (e) {
|
2816
|
+
return controller.error(e);
|
2817
|
+
});
|
2818
|
+
previousBlockedChunk = chunk;
|
2819
|
+
}
|
2820
|
+
} else {
|
2821
|
+
// We're still waiting on a previous chunk so we can't enqueue quite yet.
|
2822
|
+
var blockedChunk = previousBlockedChunk;
|
2823
|
+
|
2824
|
+
var _chunk2 = createPendingChunk(response);
|
2825
|
+
|
2826
|
+
_chunk2.then(function (v) {
|
2827
|
+
return controller.enqueue(v);
|
2828
|
+
}, function (e) {
|
2829
|
+
return controller.error(e);
|
2830
|
+
});
|
2831
|
+
|
2832
|
+
previousBlockedChunk = _chunk2;
|
2833
|
+
blockedChunk.then(function () {
|
2834
|
+
if (previousBlockedChunk === _chunk2) {
|
2835
|
+
// We were still the last chunk so we can now clear the queue and return
|
2836
|
+
// to synchronous emitting.
|
2837
|
+
previousBlockedChunk = null;
|
2838
|
+
}
|
2839
|
+
|
2840
|
+
resolveModelChunk(_chunk2, json);
|
2841
|
+
});
|
2842
|
+
}
|
2843
|
+
},
|
2844
|
+
close: function (json) {
|
2845
|
+
if (previousBlockedChunk === null) {
|
2846
|
+
controller.close();
|
2847
|
+
} else {
|
2848
|
+
var blockedChunk = previousBlockedChunk; // We shouldn't get any more enqueues after this so we can set it back to null.
|
2849
|
+
|
2850
|
+
previousBlockedChunk = null;
|
2851
|
+
blockedChunk.then(function () {
|
2852
|
+
return controller.close();
|
2853
|
+
});
|
2854
|
+
}
|
2855
|
+
},
|
2856
|
+
error: function (error) {
|
2857
|
+
if (previousBlockedChunk === null) {
|
2858
|
+
// $FlowFixMe[incompatible-call]
|
2859
|
+
controller.error(error);
|
2860
|
+
} else {
|
2861
|
+
var blockedChunk = previousBlockedChunk; // We shouldn't get any more enqueues after this so we can set it back to null.
|
2862
|
+
|
2863
|
+
previousBlockedChunk = null;
|
2864
|
+
blockedChunk.then(function () {
|
2865
|
+
return controller.error(error);
|
2866
|
+
});
|
2867
|
+
}
|
2868
|
+
}
|
2869
|
+
};
|
2870
|
+
resolveStream(response, id, stream, flightController);
|
2871
|
+
}
|
2872
|
+
|
2873
|
+
function asyncIterator() {
|
2874
|
+
// Self referencing iterator.
|
2875
|
+
return this;
|
2876
|
+
}
|
2877
|
+
|
2878
|
+
function createIterator(next) {
|
2879
|
+
var iterator = {
|
2880
|
+
next: next // TODO: Add return/throw as options for aborting.
|
2881
|
+
|
2882
|
+
}; // TODO: The iterator could inherit the AsyncIterator prototype which is not exposed as
|
2883
|
+
// a global but exists as a prototype of an AsyncGenerator. However, it's not needed
|
2884
|
+
// to satisfy the iterable protocol.
|
2885
|
+
|
2886
|
+
iterator[ASYNC_ITERATOR] = asyncIterator;
|
2887
|
+
return iterator;
|
2888
|
+
}
|
2889
|
+
|
2890
|
+
function startAsyncIterable(response, id, iterator) {
|
2891
|
+
var buffer = [];
|
2892
|
+
var closed = false;
|
2893
|
+
var nextWriteIndex = 0;
|
2894
|
+
var flightController = {
|
2895
|
+
enqueueValue: function (value) {
|
2896
|
+
if (nextWriteIndex === buffer.length) {
|
2897
|
+
buffer[nextWriteIndex] = createInitializedIteratorResultChunk(response, value, false);
|
2898
|
+
} else {
|
2899
|
+
var chunk = buffer[nextWriteIndex];
|
2900
|
+
var resolveListeners = chunk.value;
|
2901
|
+
var rejectListeners = chunk.reason;
|
2902
|
+
var initializedChunk = chunk;
|
2903
|
+
initializedChunk.status = INITIALIZED;
|
2904
|
+
initializedChunk.value = {
|
2905
|
+
done: false,
|
2906
|
+
value: value
|
2907
|
+
};
|
2908
|
+
|
2909
|
+
if (resolveListeners !== null) {
|
2910
|
+
wakeChunkIfInitialized(chunk, resolveListeners, rejectListeners);
|
2911
|
+
}
|
2912
|
+
}
|
2913
|
+
|
2914
|
+
nextWriteIndex++;
|
2915
|
+
},
|
2916
|
+
enqueueModel: function (value) {
|
2917
|
+
if (nextWriteIndex === buffer.length) {
|
2918
|
+
buffer[nextWriteIndex] = createResolvedIteratorResultChunk(response, value, false);
|
2919
|
+
} else {
|
2920
|
+
resolveIteratorResultChunk(buffer[nextWriteIndex], value, false);
|
2921
|
+
}
|
2922
|
+
|
2923
|
+
nextWriteIndex++;
|
2924
|
+
},
|
2925
|
+
close: function (value) {
|
2926
|
+
closed = true;
|
2927
|
+
|
2928
|
+
if (nextWriteIndex === buffer.length) {
|
2929
|
+
buffer[nextWriteIndex] = createResolvedIteratorResultChunk(response, value, true);
|
2930
|
+
} else {
|
2931
|
+
resolveIteratorResultChunk(buffer[nextWriteIndex], value, true);
|
2932
|
+
}
|
2933
|
+
|
2934
|
+
nextWriteIndex++;
|
2935
|
+
|
2936
|
+
while (nextWriteIndex < buffer.length) {
|
2937
|
+
// In generators, any extra reads from the iterator have the value undefined.
|
2938
|
+
resolveIteratorResultChunk(buffer[nextWriteIndex++], '"$undefined"', true);
|
2939
|
+
}
|
2940
|
+
},
|
2941
|
+
error: function (error) {
|
2942
|
+
closed = true;
|
2943
|
+
|
2944
|
+
if (nextWriteIndex === buffer.length) {
|
2945
|
+
buffer[nextWriteIndex] = createPendingChunk(response);
|
2946
|
+
}
|
2947
|
+
|
2948
|
+
while (nextWriteIndex < buffer.length) {
|
2949
|
+
triggerErrorOnChunk(buffer[nextWriteIndex++], error);
|
2950
|
+
}
|
2951
|
+
}
|
2952
|
+
};
|
2953
|
+
|
2954
|
+
var iterable = _defineProperty({}, ASYNC_ITERATOR, function () {
|
2955
|
+
var nextReadIndex = 0;
|
2956
|
+
return createIterator(function (arg) {
|
2957
|
+
if (arg !== undefined) {
|
2958
|
+
throw new Error('Values cannot be passed to next() of AsyncIterables passed to Client Components.');
|
2959
|
+
}
|
2960
|
+
|
2961
|
+
if (nextReadIndex === buffer.length) {
|
2962
|
+
if (closed) {
|
2963
|
+
// $FlowFixMe[invalid-constructor] Flow doesn't support functions as constructors
|
2964
|
+
return new Chunk(INITIALIZED, {
|
2965
|
+
done: true,
|
2966
|
+
value: undefined
|
2967
|
+
}, null, response);
|
2968
|
+
}
|
2969
|
+
|
2970
|
+
buffer[nextReadIndex] = createPendingChunk(response);
|
2971
|
+
}
|
2972
|
+
|
2973
|
+
return buffer[nextReadIndex++];
|
2974
|
+
});
|
2975
|
+
}); // TODO: If it's a single shot iterator we can optimize memory by cleaning up the buffer after
|
2976
|
+
// reading through the end, but currently we favor code size over this optimization.
|
2977
|
+
|
2978
|
+
|
2979
|
+
resolveStream(response, id, iterator ? iterable[ASYNC_ITERATOR]() : iterable, flightController);
|
2980
|
+
}
|
2981
|
+
|
2982
|
+
function stopStream(response, id, row) {
|
2983
|
+
var chunks = response._chunks;
|
2984
|
+
var chunk = chunks.get(id);
|
2985
|
+
|
2986
|
+
if (!chunk || chunk.status !== INITIALIZED) {
|
2987
|
+
// We didn't expect not to have an existing stream;
|
2988
|
+
return;
|
2989
|
+
}
|
2990
|
+
|
2991
|
+
var streamChunk = chunk;
|
2992
|
+
var controller = streamChunk.reason;
|
2993
|
+
controller.close(row === '' ? '"$undefined"' : row);
|
2994
|
+
}
|
2995
|
+
|
2300
2996
|
function resolveErrorDev(response, id, digest, message, stack) {
|
2301
2997
|
|
2302
2998
|
|
@@ -2338,7 +3034,127 @@ function resolveConsoleEntry(response, value) {
|
|
2338
3034
|
printToConsole(methodName, args, env);
|
2339
3035
|
}
|
2340
3036
|
|
3037
|
+
function mergeBuffer(buffer, lastChunk) {
|
3038
|
+
var l = buffer.length; // Count the bytes we'll need
|
3039
|
+
|
3040
|
+
var byteLength = lastChunk.length;
|
3041
|
+
|
3042
|
+
for (var i = 0; i < l; i++) {
|
3043
|
+
byteLength += buffer[i].byteLength;
|
3044
|
+
} // Allocate enough contiguous space
|
3045
|
+
|
3046
|
+
|
3047
|
+
var result = new Uint8Array(byteLength);
|
3048
|
+
var offset = 0; // Copy all the buffers into it.
|
3049
|
+
|
3050
|
+
for (var _i = 0; _i < l; _i++) {
|
3051
|
+
var chunk = buffer[_i];
|
3052
|
+
result.set(chunk, offset);
|
3053
|
+
offset += chunk.byteLength;
|
3054
|
+
}
|
3055
|
+
|
3056
|
+
result.set(lastChunk, offset);
|
3057
|
+
return result;
|
3058
|
+
}
|
3059
|
+
|
3060
|
+
function resolveTypedArray(response, id, buffer, lastChunk, constructor, bytesPerElement) {
|
3061
|
+
// If the view fits into one original buffer, we just reuse that buffer instead of
|
3062
|
+
// copying it out to a separate copy. This means that it's not always possible to
|
3063
|
+
// transfer these values to other threads without copying first since they may
|
3064
|
+
// share array buffer. For this to work, it must also have bytes aligned to a
|
3065
|
+
// multiple of a size of the type.
|
3066
|
+
var chunk = buffer.length === 0 && lastChunk.byteOffset % bytesPerElement === 0 ? lastChunk : mergeBuffer(buffer, lastChunk); // TODO: The transfer protocol of RSC is little-endian. If the client isn't little-endian
|
3067
|
+
// we should convert it instead. In practice big endian isn't really Web compatible so it's
|
3068
|
+
// somewhat safe to assume that browsers aren't going to run it, but maybe there's some SSR
|
3069
|
+
// server that's affected.
|
3070
|
+
|
3071
|
+
var view = new constructor(chunk.buffer, chunk.byteOffset, chunk.byteLength / bytesPerElement);
|
3072
|
+
resolveBuffer(response, id, view);
|
3073
|
+
}
|
3074
|
+
|
2341
3075
|
function processFullRow(response, id, tag, buffer, chunk) {
|
3076
|
+
{
|
3077
|
+
switch (tag) {
|
3078
|
+
case 65
|
3079
|
+
/* "A" */
|
3080
|
+
:
|
3081
|
+
// We must always clone to extract it into a separate buffer instead of just a view.
|
3082
|
+
resolveBuffer(response, id, mergeBuffer(buffer, chunk).buffer);
|
3083
|
+
return;
|
3084
|
+
|
3085
|
+
case 79
|
3086
|
+
/* "O" */
|
3087
|
+
:
|
3088
|
+
resolveTypedArray(response, id, buffer, chunk, Int8Array, 1);
|
3089
|
+
return;
|
3090
|
+
|
3091
|
+
case 111
|
3092
|
+
/* "o" */
|
3093
|
+
:
|
3094
|
+
resolveBuffer(response, id, buffer.length === 0 ? chunk : mergeBuffer(buffer, chunk));
|
3095
|
+
return;
|
3096
|
+
|
3097
|
+
case 85
|
3098
|
+
/* "U" */
|
3099
|
+
:
|
3100
|
+
resolveTypedArray(response, id, buffer, chunk, Uint8ClampedArray, 1);
|
3101
|
+
return;
|
3102
|
+
|
3103
|
+
case 83
|
3104
|
+
/* "S" */
|
3105
|
+
:
|
3106
|
+
resolveTypedArray(response, id, buffer, chunk, Int16Array, 2);
|
3107
|
+
return;
|
3108
|
+
|
3109
|
+
case 115
|
3110
|
+
/* "s" */
|
3111
|
+
:
|
3112
|
+
resolveTypedArray(response, id, buffer, chunk, Uint16Array, 2);
|
3113
|
+
return;
|
3114
|
+
|
3115
|
+
case 76
|
3116
|
+
/* "L" */
|
3117
|
+
:
|
3118
|
+
resolveTypedArray(response, id, buffer, chunk, Int32Array, 4);
|
3119
|
+
return;
|
3120
|
+
|
3121
|
+
case 108
|
3122
|
+
/* "l" */
|
3123
|
+
:
|
3124
|
+
resolveTypedArray(response, id, buffer, chunk, Uint32Array, 4);
|
3125
|
+
return;
|
3126
|
+
|
3127
|
+
case 71
|
3128
|
+
/* "G" */
|
3129
|
+
:
|
3130
|
+
resolveTypedArray(response, id, buffer, chunk, Float32Array, 4);
|
3131
|
+
return;
|
3132
|
+
|
3133
|
+
case 103
|
3134
|
+
/* "g" */
|
3135
|
+
:
|
3136
|
+
resolveTypedArray(response, id, buffer, chunk, Float64Array, 8);
|
3137
|
+
return;
|
3138
|
+
|
3139
|
+
case 77
|
3140
|
+
/* "M" */
|
3141
|
+
:
|
3142
|
+
resolveTypedArray(response, id, buffer, chunk, BigInt64Array, 8);
|
3143
|
+
return;
|
3144
|
+
|
3145
|
+
case 109
|
3146
|
+
/* "m" */
|
3147
|
+
:
|
3148
|
+
resolveTypedArray(response, id, buffer, chunk, BigUint64Array, 8);
|
3149
|
+
return;
|
3150
|
+
|
3151
|
+
case 86
|
3152
|
+
/* "V" */
|
3153
|
+
:
|
3154
|
+
resolveTypedArray(response, id, buffer, chunk, DataView, 1);
|
3155
|
+
return;
|
3156
|
+
}
|
3157
|
+
}
|
2342
3158
|
|
2343
3159
|
var stringDecoder = response._stringDecoder;
|
2344
3160
|
var row = '';
|
@@ -2413,26 +3229,56 @@ function processFullRow(response, id, tag, buffer, chunk) {
|
|
2413
3229
|
case 82
|
2414
3230
|
/* "R" */
|
2415
3231
|
:
|
3232
|
+
{
|
3233
|
+
{
|
3234
|
+
startReadableStream(response, id, undefined);
|
3235
|
+
return;
|
3236
|
+
}
|
3237
|
+
}
|
2416
3238
|
// Fallthrough
|
2417
3239
|
|
2418
3240
|
case 114
|
2419
3241
|
/* "r" */
|
2420
3242
|
:
|
3243
|
+
{
|
3244
|
+
{
|
3245
|
+
startReadableStream(response, id, 'bytes');
|
3246
|
+
return;
|
3247
|
+
}
|
3248
|
+
}
|
2421
3249
|
// Fallthrough
|
2422
3250
|
|
2423
3251
|
case 88
|
2424
3252
|
/* "X" */
|
2425
3253
|
:
|
3254
|
+
{
|
3255
|
+
{
|
3256
|
+
startAsyncIterable(response, id, false);
|
3257
|
+
return;
|
3258
|
+
}
|
3259
|
+
}
|
2426
3260
|
// Fallthrough
|
2427
3261
|
|
2428
3262
|
case 120
|
2429
3263
|
/* "x" */
|
2430
3264
|
:
|
3265
|
+
{
|
3266
|
+
{
|
3267
|
+
startAsyncIterable(response, id, true);
|
3268
|
+
return;
|
3269
|
+
}
|
3270
|
+
}
|
2431
3271
|
// Fallthrough
|
2432
3272
|
|
2433
3273
|
case 67
|
2434
3274
|
/* "C" */
|
2435
3275
|
:
|
3276
|
+
{
|
3277
|
+
{
|
3278
|
+
stopStream(response, id, row);
|
3279
|
+
return;
|
3280
|
+
}
|
3281
|
+
}
|
2436
3282
|
// Fallthrough
|
2437
3283
|
|
2438
3284
|
case 80
|
@@ -2485,7 +3331,31 @@ function processBinaryChunk(response, chunk) {
|
|
2485
3331
|
|
2486
3332
|
if (resolvedRowTag === 84
|
2487
3333
|
/* "T" */
|
2488
|
-
||
|
3334
|
+
|| (resolvedRowTag === 65
|
3335
|
+
/* "A" */
|
3336
|
+
|| resolvedRowTag === 79
|
3337
|
+
/* "O" */
|
3338
|
+
|| resolvedRowTag === 111
|
3339
|
+
/* "o" */
|
3340
|
+
|| resolvedRowTag === 85
|
3341
|
+
/* "U" */
|
3342
|
+
|| resolvedRowTag === 83
|
3343
|
+
/* "S" */
|
3344
|
+
|| resolvedRowTag === 115
|
3345
|
+
/* "s" */
|
3346
|
+
|| resolvedRowTag === 76
|
3347
|
+
/* "L" */
|
3348
|
+
|| resolvedRowTag === 108
|
3349
|
+
/* "l" */
|
3350
|
+
|| resolvedRowTag === 71
|
3351
|
+
/* "G" */
|
3352
|
+
|| resolvedRowTag === 103
|
3353
|
+
/* "g" */
|
3354
|
+
|| resolvedRowTag === 77
|
3355
|
+
/* "M" */
|
3356
|
+
|| resolvedRowTag === 109
|
3357
|
+
/* "m" */
|
3358
|
+
|| resolvedRowTag === 86)
|
2489
3359
|
/* "V" */
|
2490
3360
|
) {
|
2491
3361
|
rowTag = resolvedRowTag;
|