react-server-dom-webpack 19.0.0-canary-cf5ab8b8b2-20240425 → 19.0.0-rc-915b914b3a-20240515
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 +941 -73
- package/cjs/react-server-dom-webpack-client.browser.production.js +722 -229
- package/cjs/react-server-dom-webpack-client.edge.development.js +941 -73
- package/cjs/react-server-dom-webpack-client.edge.production.js +722 -229
- package/cjs/react-server-dom-webpack-client.node.development.js +940 -72
- package/cjs/react-server-dom-webpack-client.node.production.js +707 -219
- package/cjs/react-server-dom-webpack-client.node.unbundled.development.js +940 -72
- package/cjs/react-server-dom-webpack-client.node.unbundled.production.js +707 -219
- package/cjs/react-server-dom-webpack-server.browser.development.js +1335 -235
- package/cjs/react-server-dom-webpack-server.browser.production.js +865 -202
- package/cjs/react-server-dom-webpack-server.edge.development.js +1341 -233
- package/cjs/react-server-dom-webpack-server.edge.production.js +865 -202
- package/cjs/react-server-dom-webpack-server.node.development.js +1294 -237
- package/cjs/react-server-dom-webpack-server.node.production.js +860 -223
- package/cjs/react-server-dom-webpack-server.node.unbundled.development.js +1294 -237
- package/cjs/react-server-dom-webpack-server.node.unbundled.production.js +860 -223
- 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,12 +1163,12 @@ 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
|
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
|
989
1170
|
|
990
|
-
_data.append(formFieldPrefix + _lazyId,
|
1171
|
+
_data.append(formFieldPrefix + _lazyId, _partJSON2);
|
991
1172
|
|
992
1173
|
pendingParts--;
|
993
1174
|
|
@@ -1028,12 +1209,12 @@ function processReply(root, formFieldPrefix, temporaryReferences, resolve, rejec
|
|
1028
1209
|
|
1029
1210
|
_thenable.then(function (partValue) {
|
1030
1211
|
try {
|
1031
|
-
var
|
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
|
1035
1216
|
|
1036
|
-
_data2.append(formFieldPrefix + promiseId,
|
1217
|
+
_data2.append(formFieldPrefix + promiseId, _partJSON3);
|
1037
1218
|
|
1038
1219
|
pendingParts--;
|
1039
1220
|
|
@@ -1043,15 +1224,43 @@ function processReply(root, formFieldPrefix, temporaryReferences, resolve, rejec
|
|
1043
1224
|
} catch (reason) {
|
1044
1225
|
reject(reason);
|
1045
1226
|
}
|
1046
|
-
},
|
1047
|
-
|
1048
|
-
|
1049
|
-
reject(reason);
|
1050
|
-
});
|
1227
|
+
}, // In the future we could consider serializing this as an error
|
1228
|
+
// that throws on the server instead.
|
1229
|
+
reject);
|
1051
1230
|
|
1052
1231
|
return serializePromiseID(promiseId);
|
1053
1232
|
}
|
1054
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
|
+
|
1055
1264
|
if (isArray(value)) {
|
1056
1265
|
// $FlowFixMe[incompatible-return]
|
1057
1266
|
return value;
|
@@ -1078,29 +1287,117 @@ function processReply(root, formFieldPrefix, temporaryReferences, resolve, rejec
|
|
1078
1287
|
}
|
1079
1288
|
|
1080
1289
|
if (value instanceof Map) {
|
1081
|
-
var
|
1290
|
+
var mapId = nextPartId++;
|
1291
|
+
|
1292
|
+
var _partJSON4 = serializeModel(Array.from(value), mapId);
|
1082
1293
|
|
1083
1294
|
if (formData === null) {
|
1084
1295
|
formData = new FormData();
|
1085
1296
|
}
|
1086
1297
|
|
1087
|
-
|
1088
|
-
formData.append(formFieldPrefix + mapId, _partJSON3);
|
1298
|
+
formData.append(formFieldPrefix + mapId, _partJSON4);
|
1089
1299
|
return serializeMapID(mapId);
|
1090
1300
|
}
|
1091
1301
|
|
1092
1302
|
if (value instanceof Set) {
|
1093
|
-
var
|
1303
|
+
var setId = nextPartId++;
|
1304
|
+
|
1305
|
+
var _partJSON5 = serializeModel(Array.from(value), setId);
|
1094
1306
|
|
1095
1307
|
if (formData === null) {
|
1096
1308
|
formData = new FormData();
|
1097
1309
|
}
|
1098
1310
|
|
1099
|
-
|
1100
|
-
formData.append(formFieldPrefix + setId, _partJSON4);
|
1311
|
+
formData.append(formFieldPrefix + setId, _partJSON5);
|
1101
1312
|
return serializeSetID(setId);
|
1102
1313
|
}
|
1103
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
|
+
|
1104
1401
|
var iteratorFn = getIteratorFn(value);
|
1105
1402
|
|
1106
1403
|
if (iteratorFn) {
|
@@ -1108,18 +1405,33 @@ function processReply(root, formFieldPrefix, temporaryReferences, resolve, rejec
|
|
1108
1405
|
|
1109
1406
|
if (iterator === value) {
|
1110
1407
|
// Iterator, not Iterable
|
1111
|
-
var
|
1408
|
+
var iteratorId = nextPartId++;
|
1409
|
+
|
1410
|
+
var _partJSON6 = serializeModel(Array.from(iterator), iteratorId);
|
1112
1411
|
|
1113
1412
|
if (formData === null) {
|
1114
1413
|
formData = new FormData();
|
1115
1414
|
}
|
1116
1415
|
|
1117
|
-
|
1118
|
-
formData.append(formFieldPrefix + iteratorId, _partJSON5);
|
1416
|
+
formData.append(formFieldPrefix + iteratorId, _partJSON6);
|
1119
1417
|
return serializeIteratorID(iteratorId);
|
1120
1418
|
}
|
1121
1419
|
|
1122
1420
|
return Array.from(iterator);
|
1421
|
+
}
|
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
|
+
}
|
1123
1435
|
} // Verify that this is a simple plain object.
|
1124
1436
|
|
1125
1437
|
|
@@ -1128,10 +1440,11 @@ function processReply(root, formFieldPrefix, temporaryReferences, resolve, rejec
|
|
1128
1440
|
if (proto !== ObjectPrototype && (proto === null || getPrototypeOf(proto) !== null)) {
|
1129
1441
|
if (temporaryReferences === undefined) {
|
1130
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.');
|
1131
|
-
} // 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.
|
1132
1445
|
|
1133
1446
|
|
1134
|
-
return
|
1447
|
+
return serializeTemporaryReferenceMarker();
|
1135
1448
|
}
|
1136
1449
|
|
1137
1450
|
{
|
@@ -1200,19 +1513,41 @@ function processReply(root, formFieldPrefix, temporaryReferences, resolve, rejec
|
|
1200
1513
|
return serializeServerReferenceID(_refId);
|
1201
1514
|
}
|
1202
1515
|
|
1203
|
-
if (temporaryReferences
|
1204
|
-
|
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
|
+
}
|
1205
1529
|
}
|
1206
1530
|
|
1207
|
-
|
1531
|
+
throw new Error('Client Functions cannot be passed directly to Server Functions. ' + 'Only Functions passed from the Server can be passed back again.');
|
1208
1532
|
}
|
1209
1533
|
|
1210
1534
|
if (typeof value === 'symbol') {
|
1211
|
-
if (temporaryReferences
|
1212
|
-
|
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
|
+
}
|
1213
1548
|
}
|
1214
1549
|
|
1215
|
-
|
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) ));
|
1216
1551
|
}
|
1217
1552
|
|
1218
1553
|
if (typeof value === 'bigint') {
|
@@ -1220,10 +1555,25 @@ function processReply(root, formFieldPrefix, temporaryReferences, resolve, rejec
|
|
1220
1555
|
}
|
1221
1556
|
|
1222
1557
|
throw new Error("Type " + typeof value + " is not supported as an argument to a Server Function.");
|
1223
|
-
}
|
1558
|
+
}
|
1559
|
+
|
1560
|
+
function serializeModel(model, id) {
|
1561
|
+
if (typeof model === 'object' && model !== null) {
|
1562
|
+
var reference = serializeByValueID(id);
|
1563
|
+
writtenObjects.set(model, reference);
|
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.
|
1224
1572
|
|
1573
|
+
return JSON.stringify(model, resolveToJSON);
|
1574
|
+
}
|
1225
1575
|
|
1226
|
-
var json =
|
1576
|
+
var json = serializeModel(root, 0);
|
1227
1577
|
|
1228
1578
|
if (formData === null) {
|
1229
1579
|
// If it's a simple data structure, we just use plain JSON.
|
@@ -1649,6 +1999,14 @@ function wakeChunkIfInitialized(chunk, resolveListeners, rejectListeners) {
|
|
1649
1999
|
|
1650
2000
|
function triggerErrorOnChunk(chunk, error) {
|
1651
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
|
+
}
|
1652
2010
|
|
1653
2011
|
return;
|
1654
2012
|
}
|
@@ -1678,8 +2036,48 @@ function createInitializedTextChunk(response, value) {
|
|
1678
2036
|
return new Chunk(INITIALIZED, value, null, response);
|
1679
2037
|
}
|
1680
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
|
+
|
1681
2072
|
function resolveModelChunk(chunk, value) {
|
1682
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
|
+
}
|
1683
2081
|
|
1684
2082
|
return;
|
1685
2083
|
}
|
@@ -1798,7 +2196,8 @@ function nullRefGetter() {
|
|
1798
2196
|
}
|
1799
2197
|
}
|
1800
2198
|
|
1801
|
-
function createElement(type, key, props, owner
|
2199
|
+
function createElement(type, key, props, owner, // DEV-only
|
2200
|
+
stack) // DEV-only
|
1802
2201
|
{
|
1803
2202
|
var element;
|
1804
2203
|
|
@@ -1836,6 +2235,10 @@ function createElement(type, key, props, owner) // DEV-only
|
|
1836
2235
|
writable: true,
|
1837
2236
|
value: null
|
1838
2237
|
});
|
2238
|
+
// _debugInfo later. We could move it into _store which remains mutable.
|
2239
|
+
|
2240
|
+
|
2241
|
+
Object.freeze(element.props);
|
1839
2242
|
}
|
1840
2243
|
|
1841
2244
|
return element;
|
@@ -1869,7 +2272,7 @@ function getChunk(response, id) {
|
|
1869
2272
|
return chunk;
|
1870
2273
|
}
|
1871
2274
|
|
1872
|
-
function createModelResolver(chunk, parentObject, key, cyclic, response, map) {
|
2275
|
+
function createModelResolver(chunk, parentObject, key, cyclic, response, map, path) {
|
1873
2276
|
var blocked;
|
1874
2277
|
|
1875
2278
|
if (initializingChunkBlockedModel) {
|
@@ -1886,6 +2289,10 @@ function createModelResolver(chunk, parentObject, key, cyclic, response, map) {
|
|
1886
2289
|
}
|
1887
2290
|
|
1888
2291
|
return function (value) {
|
2292
|
+
for (var i = 1; i < path.length; i++) {
|
2293
|
+
value = value[path[i]];
|
2294
|
+
}
|
2295
|
+
|
1889
2296
|
parentObject[key] = map(response, value); // If this is the root object for a model reference, where `blocked.value`
|
1890
2297
|
// is a stale `null`, the resolved value can be used directly.
|
1891
2298
|
|
@@ -1946,7 +2353,9 @@ function createServerReferenceProxy(response, metaData) {
|
|
1946
2353
|
return proxy;
|
1947
2354
|
}
|
1948
2355
|
|
1949
|
-
function getOutlinedModel(response,
|
2356
|
+
function getOutlinedModel(response, reference, parentObject, key, map) {
|
2357
|
+
var path = reference.split(':');
|
2358
|
+
var id = parseInt(path[0], 16);
|
1950
2359
|
var chunk = getChunk(response, id);
|
1951
2360
|
|
1952
2361
|
switch (chunk.status) {
|
@@ -1962,7 +2371,13 @@ function getOutlinedModel(response, id, parentObject, key, map) {
|
|
1962
2371
|
|
1963
2372
|
switch (chunk.status) {
|
1964
2373
|
case INITIALIZED:
|
1965
|
-
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);
|
1966
2381
|
|
1967
2382
|
if (chunk._debugInfo) {
|
1968
2383
|
// If we have a direct reference to an object that was rendered by a synchronous
|
@@ -1990,7 +2405,7 @@ function getOutlinedModel(response, id, parentObject, key, map) {
|
|
1990
2405
|
case BLOCKED:
|
1991
2406
|
case CYCLIC:
|
1992
2407
|
var parentChunk = initializingChunk;
|
1993
|
-
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));
|
1994
2409
|
return null;
|
1995
2410
|
|
1996
2411
|
default:
|
@@ -2006,6 +2421,12 @@ function createSet(response, model) {
|
|
2006
2421
|
return new Set(model);
|
2007
2422
|
}
|
2008
2423
|
|
2424
|
+
function createBlob(response, model) {
|
2425
|
+
return new Blob(model.slice(1), {
|
2426
|
+
type: model[0]
|
2427
|
+
});
|
2428
|
+
}
|
2429
|
+
|
2009
2430
|
function createFormData(response, model) {
|
2010
2431
|
var formData = new FormData();
|
2011
2432
|
|
@@ -2073,61 +2494,63 @@ function parseModelString(response, parentObject, key, value) {
|
|
2073
2494
|
case 'F':
|
2074
2495
|
{
|
2075
2496
|
// Server Reference
|
2076
|
-
var
|
2077
|
-
|
2078
|
-
return getOutlinedModel(response, _id2, parentObject, key, createServerReferenceProxy);
|
2497
|
+
var ref = value.slice(2);
|
2498
|
+
return getOutlinedModel(response, ref, parentObject, key, createServerReferenceProxy);
|
2079
2499
|
}
|
2080
2500
|
|
2081
2501
|
case 'T':
|
2082
2502
|
{
|
2083
2503
|
// Temporary Reference
|
2084
|
-
var
|
2085
|
-
|
2504
|
+
var reference = '$' + value.slice(2);
|
2086
2505
|
var temporaryReferences = response._tempRefs;
|
2087
2506
|
|
2088
2507
|
if (temporaryReferences == null) {
|
2089
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.');
|
2090
2509
|
}
|
2091
2510
|
|
2092
|
-
return readTemporaryReference(temporaryReferences,
|
2511
|
+
return readTemporaryReference(temporaryReferences, reference);
|
2093
2512
|
}
|
2094
2513
|
|
2095
2514
|
case 'Q':
|
2096
2515
|
{
|
2097
2516
|
// Map
|
2098
|
-
var
|
2517
|
+
var _ref = value.slice(2);
|
2099
2518
|
|
2100
|
-
return getOutlinedModel(response,
|
2519
|
+
return getOutlinedModel(response, _ref, parentObject, key, createMap);
|
2101
2520
|
}
|
2102
2521
|
|
2103
2522
|
case 'W':
|
2104
2523
|
{
|
2105
2524
|
// Set
|
2106
|
-
var
|
2525
|
+
var _ref2 = value.slice(2);
|
2107
2526
|
|
2108
|
-
return getOutlinedModel(response,
|
2527
|
+
return getOutlinedModel(response, _ref2, parentObject, key, createSet);
|
2109
2528
|
}
|
2110
2529
|
|
2111
2530
|
case 'B':
|
2112
2531
|
{
|
2532
|
+
// Blob
|
2533
|
+
{
|
2534
|
+
var _ref3 = value.slice(2);
|
2113
2535
|
|
2114
|
-
|
2536
|
+
return getOutlinedModel(response, _ref3, parentObject, key, createBlob);
|
2537
|
+
}
|
2115
2538
|
}
|
2116
2539
|
|
2117
2540
|
case 'K':
|
2118
2541
|
{
|
2119
2542
|
// FormData
|
2120
|
-
var
|
2543
|
+
var _ref4 = value.slice(2);
|
2121
2544
|
|
2122
|
-
return getOutlinedModel(response,
|
2545
|
+
return getOutlinedModel(response, _ref4, parentObject, key, createFormData);
|
2123
2546
|
}
|
2124
2547
|
|
2125
2548
|
case 'i':
|
2126
2549
|
{
|
2127
2550
|
// Iterator
|
2128
|
-
var
|
2551
|
+
var _ref5 = value.slice(2);
|
2129
2552
|
|
2130
|
-
return getOutlinedModel(response,
|
2553
|
+
return getOutlinedModel(response, _ref5, parentObject, key, extractIterator);
|
2131
2554
|
}
|
2132
2555
|
|
2133
2556
|
case 'I':
|
@@ -2191,9 +2614,9 @@ function parseModelString(response, parentObject, key, value) {
|
|
2191
2614
|
default:
|
2192
2615
|
{
|
2193
2616
|
// We assume that anything else is a reference ID.
|
2194
|
-
var
|
2617
|
+
var _ref6 = value.slice(1);
|
2195
2618
|
|
2196
|
-
return getOutlinedModel(response,
|
2619
|
+
return getOutlinedModel(response, _ref6, parentObject, key, createModel);
|
2197
2620
|
}
|
2198
2621
|
}
|
2199
2622
|
}
|
@@ -2254,9 +2677,41 @@ function resolveModel(response, id, model) {
|
|
2254
2677
|
function resolveText(response, id, text) {
|
2255
2678
|
var chunks = response._chunks;
|
2256
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
|
+
|
2257
2693
|
chunks.set(id, createInitializedTextChunk(response, text));
|
2258
2694
|
}
|
2259
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
|
+
|
2260
2715
|
function resolveModule(response, id, model) {
|
2261
2716
|
var chunks = response._chunks;
|
2262
2717
|
var chunk = chunks.get(id);
|
@@ -2299,6 +2754,245 @@ function resolveModule(response, id, model) {
|
|
2299
2754
|
}
|
2300
2755
|
}
|
2301
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
|
+
|
2302
2996
|
function resolveErrorDev(response, id, digest, message, stack) {
|
2303
2997
|
|
2304
2998
|
|
@@ -2340,7 +3034,127 @@ function resolveConsoleEntry(response, value) {
|
|
2340
3034
|
printToConsole(methodName, args, env);
|
2341
3035
|
}
|
2342
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
|
+
|
2343
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
|
+
}
|
2344
3158
|
|
2345
3159
|
var stringDecoder = response._stringDecoder;
|
2346
3160
|
var row = '';
|
@@ -2415,26 +3229,56 @@ function processFullRow(response, id, tag, buffer, chunk) {
|
|
2415
3229
|
case 82
|
2416
3230
|
/* "R" */
|
2417
3231
|
:
|
3232
|
+
{
|
3233
|
+
{
|
3234
|
+
startReadableStream(response, id, undefined);
|
3235
|
+
return;
|
3236
|
+
}
|
3237
|
+
}
|
2418
3238
|
// Fallthrough
|
2419
3239
|
|
2420
3240
|
case 114
|
2421
3241
|
/* "r" */
|
2422
3242
|
:
|
3243
|
+
{
|
3244
|
+
{
|
3245
|
+
startReadableStream(response, id, 'bytes');
|
3246
|
+
return;
|
3247
|
+
}
|
3248
|
+
}
|
2423
3249
|
// Fallthrough
|
2424
3250
|
|
2425
3251
|
case 88
|
2426
3252
|
/* "X" */
|
2427
3253
|
:
|
3254
|
+
{
|
3255
|
+
{
|
3256
|
+
startAsyncIterable(response, id, false);
|
3257
|
+
return;
|
3258
|
+
}
|
3259
|
+
}
|
2428
3260
|
// Fallthrough
|
2429
3261
|
|
2430
3262
|
case 120
|
2431
3263
|
/* "x" */
|
2432
3264
|
:
|
3265
|
+
{
|
3266
|
+
{
|
3267
|
+
startAsyncIterable(response, id, true);
|
3268
|
+
return;
|
3269
|
+
}
|
3270
|
+
}
|
2433
3271
|
// Fallthrough
|
2434
3272
|
|
2435
3273
|
case 67
|
2436
3274
|
/* "C" */
|
2437
3275
|
:
|
3276
|
+
{
|
3277
|
+
{
|
3278
|
+
stopStream(response, id, row);
|
3279
|
+
return;
|
3280
|
+
}
|
3281
|
+
}
|
2438
3282
|
// Fallthrough
|
2439
3283
|
|
2440
3284
|
case 80
|
@@ -2487,7 +3331,31 @@ function processBinaryChunk(response, chunk) {
|
|
2487
3331
|
|
2488
3332
|
if (resolvedRowTag === 84
|
2489
3333
|
/* "T" */
|
2490
|
-
||
|
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)
|
2491
3359
|
/* "V" */
|
2492
3360
|
) {
|
2493
3361
|
rowTag = resolvedRowTag;
|