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