react-server-dom-webpack 19.0.0-canary-cb151849e1-20240424 → 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
@@ -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();
|
@@ -794,22 +806,13 @@ function describeObjectForErrorMessage(objectOrArray, expandedName) {
|
|
794
806
|
}
|
795
807
|
|
796
808
|
function createTemporaryReferenceSet() {
|
797
|
-
return
|
809
|
+
return new Map();
|
798
810
|
}
|
799
|
-
function writeTemporaryReference(set, object) {
|
800
|
-
|
801
|
-
// object. This ensures that we always generate a deterministic encoding of
|
802
|
-
// each slot in the reply for cacheability.
|
803
|
-
var newId = set.length;
|
804
|
-
set.push(object);
|
805
|
-
return newId;
|
811
|
+
function writeTemporaryReference(set, reference, object) {
|
812
|
+
set.set(reference, object);
|
806
813
|
}
|
807
|
-
function readTemporaryReference(set,
|
808
|
-
|
809
|
-
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.');
|
810
|
-
}
|
811
|
-
|
812
|
-
return set[id];
|
814
|
+
function readTemporaryReference(set, reference) {
|
815
|
+
return set.get(reference);
|
813
816
|
}
|
814
817
|
|
815
818
|
var ObjectPrototype = Object.prototype;
|
@@ -828,8 +831,8 @@ function serializeServerReferenceID(id) {
|
|
828
831
|
return '$F' + id.toString(16);
|
829
832
|
}
|
830
833
|
|
831
|
-
function
|
832
|
-
return '$T'
|
834
|
+
function serializeTemporaryReferenceMarker() {
|
835
|
+
return '$T';
|
833
836
|
}
|
834
837
|
|
835
838
|
function serializeFormDataReference(id) {
|
@@ -877,6 +880,10 @@ function serializeSetID(id) {
|
|
877
880
|
return '$W' + id.toString(16);
|
878
881
|
}
|
879
882
|
|
883
|
+
function serializeBlobID(id) {
|
884
|
+
return '$B' + id.toString(16);
|
885
|
+
}
|
886
|
+
|
880
887
|
function serializeIteratorID(id) {
|
881
888
|
return '$i' + id.toString(16);
|
882
889
|
}
|
@@ -895,6 +902,170 @@ function processReply(root, formFieldPrefix, temporaryReferences, resolve, rejec
|
|
895
902
|
var nextPartId = 1;
|
896
903
|
var pendingParts = 0;
|
897
904
|
var formData = null;
|
905
|
+
var writtenObjects = new WeakMap();
|
906
|
+
var modelRoot = root;
|
907
|
+
|
908
|
+
function serializeTypedArray(tag, typedArray) {
|
909
|
+
var blob = new Blob([// We should be able to pass the buffer straight through but Node < 18 treat
|
910
|
+
// multi-byte array blobs differently so we first convert it to single-byte.
|
911
|
+
new Uint8Array(typedArray.buffer, typedArray.byteOffset, typedArray.byteLength)]);
|
912
|
+
var blobId = nextPartId++;
|
913
|
+
|
914
|
+
if (formData === null) {
|
915
|
+
formData = new FormData();
|
916
|
+
}
|
917
|
+
|
918
|
+
formData.append(formFieldPrefix + blobId, blob);
|
919
|
+
return '$' + tag + blobId.toString(16);
|
920
|
+
}
|
921
|
+
|
922
|
+
function serializeBinaryReader(reader) {
|
923
|
+
if (formData === null) {
|
924
|
+
// Upgrade to use FormData to allow us to stream this value.
|
925
|
+
formData = new FormData();
|
926
|
+
}
|
927
|
+
|
928
|
+
var data = formData;
|
929
|
+
pendingParts++;
|
930
|
+
var streamId = nextPartId++;
|
931
|
+
var buffer = [];
|
932
|
+
|
933
|
+
function progress(entry) {
|
934
|
+
if (entry.done) {
|
935
|
+
var blobId = nextPartId++; // eslint-disable-next-line react-internal/safe-string-coercion
|
936
|
+
|
937
|
+
data.append(formFieldPrefix + blobId, new Blob(buffer)); // eslint-disable-next-line react-internal/safe-string-coercion
|
938
|
+
|
939
|
+
data.append(formFieldPrefix + streamId, '"$o' + blobId.toString(16) + '"'); // eslint-disable-next-line react-internal/safe-string-coercion
|
940
|
+
|
941
|
+
data.append(formFieldPrefix + streamId, 'C'); // Close signal
|
942
|
+
|
943
|
+
pendingParts--;
|
944
|
+
|
945
|
+
if (pendingParts === 0) {
|
946
|
+
resolve(data);
|
947
|
+
}
|
948
|
+
} else {
|
949
|
+
buffer.push(entry.value);
|
950
|
+
reader.read(new Uint8Array(1024)).then(progress, reject);
|
951
|
+
}
|
952
|
+
}
|
953
|
+
|
954
|
+
reader.read(new Uint8Array(1024)).then(progress, reject);
|
955
|
+
return '$r' + streamId.toString(16);
|
956
|
+
}
|
957
|
+
|
958
|
+
function serializeReader(reader) {
|
959
|
+
if (formData === null) {
|
960
|
+
// Upgrade to use FormData to allow us to stream this value.
|
961
|
+
formData = new FormData();
|
962
|
+
}
|
963
|
+
|
964
|
+
var data = formData;
|
965
|
+
pendingParts++;
|
966
|
+
var streamId = nextPartId++;
|
967
|
+
|
968
|
+
function progress(entry) {
|
969
|
+
if (entry.done) {
|
970
|
+
// eslint-disable-next-line react-internal/safe-string-coercion
|
971
|
+
data.append(formFieldPrefix + streamId, 'C'); // Close signal
|
972
|
+
|
973
|
+
pendingParts--;
|
974
|
+
|
975
|
+
if (pendingParts === 0) {
|
976
|
+
resolve(data);
|
977
|
+
}
|
978
|
+
} else {
|
979
|
+
try {
|
980
|
+
// $FlowFixMe[incompatible-type]: While plain JSON can return undefined we never do here.
|
981
|
+
var partJSON = JSON.stringify(entry.value, resolveToJSON); // eslint-disable-next-line react-internal/safe-string-coercion
|
982
|
+
|
983
|
+
data.append(formFieldPrefix + streamId, partJSON);
|
984
|
+
reader.read().then(progress, reject);
|
985
|
+
} catch (x) {
|
986
|
+
reject(x);
|
987
|
+
}
|
988
|
+
}
|
989
|
+
}
|
990
|
+
|
991
|
+
reader.read().then(progress, reject);
|
992
|
+
return '$R' + streamId.toString(16);
|
993
|
+
}
|
994
|
+
|
995
|
+
function serializeReadableStream(stream) {
|
996
|
+
// Detect if this is a BYOB stream. BYOB streams should be able to be read as bytes on the
|
997
|
+
// receiving side. For binary streams, we serialize them as plain Blobs.
|
998
|
+
var binaryReader;
|
999
|
+
|
1000
|
+
try {
|
1001
|
+
// $FlowFixMe[extra-arg]: This argument is accepted.
|
1002
|
+
binaryReader = stream.getReader({
|
1003
|
+
mode: 'byob'
|
1004
|
+
});
|
1005
|
+
} catch (x) {
|
1006
|
+
return serializeReader(stream.getReader());
|
1007
|
+
}
|
1008
|
+
|
1009
|
+
return serializeBinaryReader(binaryReader);
|
1010
|
+
}
|
1011
|
+
|
1012
|
+
function serializeAsyncIterable(iterable, iterator) {
|
1013
|
+
if (formData === null) {
|
1014
|
+
// Upgrade to use FormData to allow us to stream this value.
|
1015
|
+
formData = new FormData();
|
1016
|
+
}
|
1017
|
+
|
1018
|
+
var data = formData;
|
1019
|
+
pendingParts++;
|
1020
|
+
var streamId = nextPartId++; // Generators/Iterators are Iterables but they're also their own iterator
|
1021
|
+
// functions. If that's the case, we treat them as single-shot. Otherwise,
|
1022
|
+
// we assume that this iterable might be a multi-shot and allow it to be
|
1023
|
+
// iterated more than once on the receiving server.
|
1024
|
+
|
1025
|
+
var isIterator = iterable === iterator; // There's a race condition between when the stream is aborted and when the promise
|
1026
|
+
// resolves so we track whether we already aborted it to avoid writing twice.
|
1027
|
+
|
1028
|
+
function progress(entry) {
|
1029
|
+
if (entry.done) {
|
1030
|
+
if (entry.value === undefined) {
|
1031
|
+
// eslint-disable-next-line react-internal/safe-string-coercion
|
1032
|
+
data.append(formFieldPrefix + streamId, 'C'); // Close signal
|
1033
|
+
} else {
|
1034
|
+
// Unlike streams, the last value may not be undefined. If it's not
|
1035
|
+
// we outline it and encode a reference to it in the closing instruction.
|
1036
|
+
try {
|
1037
|
+
// $FlowFixMe[incompatible-type]: While plain JSON can return undefined we never do here.
|
1038
|
+
var partJSON = JSON.stringify(entry.value, resolveToJSON);
|
1039
|
+
data.append(formFieldPrefix + streamId, 'C' + partJSON); // Close signal
|
1040
|
+
} catch (x) {
|
1041
|
+
reject(x);
|
1042
|
+
return;
|
1043
|
+
}
|
1044
|
+
}
|
1045
|
+
|
1046
|
+
pendingParts--;
|
1047
|
+
|
1048
|
+
if (pendingParts === 0) {
|
1049
|
+
resolve(data);
|
1050
|
+
}
|
1051
|
+
} else {
|
1052
|
+
try {
|
1053
|
+
// $FlowFixMe[incompatible-type]: While plain JSON can return undefined we never do here.
|
1054
|
+
var _partJSON = JSON.stringify(entry.value, resolveToJSON); // eslint-disable-next-line react-internal/safe-string-coercion
|
1055
|
+
|
1056
|
+
|
1057
|
+
data.append(formFieldPrefix + streamId, _partJSON);
|
1058
|
+
iterator.next().then(progress, reject);
|
1059
|
+
} catch (x) {
|
1060
|
+
reject(x);
|
1061
|
+
return;
|
1062
|
+
}
|
1063
|
+
}
|
1064
|
+
}
|
1065
|
+
|
1066
|
+
iterator.next().then(progress, reject);
|
1067
|
+
return '$' + (isIterator ? 'x' : 'X') + streamId.toString(16);
|
1068
|
+
}
|
898
1069
|
|
899
1070
|
function resolveToJSON(key, value) {
|
900
1071
|
var parent = this; // Make sure that `parent[key]` wasn't JSONified before `value` was passed to us
|
@@ -920,11 +1091,21 @@ function processReply(root, formFieldPrefix, temporaryReferences, resolve, rejec
|
|
920
1091
|
switch (value.$$typeof) {
|
921
1092
|
case REACT_ELEMENT_TYPE:
|
922
1093
|
{
|
923
|
-
if (temporaryReferences
|
924
|
-
|
1094
|
+
if (temporaryReferences !== undefined && key.indexOf(':') === -1) {
|
1095
|
+
// TODO: If the property name contains a colon, we don't dedupe. Escape instead.
|
1096
|
+
var parentReference = writtenObjects.get(parent);
|
1097
|
+
|
1098
|
+
if (parentReference !== undefined) {
|
1099
|
+
// If the parent has a reference, we can refer to this object indirectly
|
1100
|
+
// through the property name inside that parent.
|
1101
|
+
var reference = parentReference + ':' + key; // Store this object so that the server can refer to it later in responses.
|
1102
|
+
|
1103
|
+
writeTemporaryReference(temporaryReferences, reference, value);
|
1104
|
+
return serializeTemporaryReferenceMarker();
|
1105
|
+
}
|
925
1106
|
}
|
926
1107
|
|
927
|
-
|
1108
|
+
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) ));
|
928
1109
|
}
|
929
1110
|
|
930
1111
|
case REACT_LAZY_TYPE:
|
@@ -946,7 +1127,7 @@ function processReply(root, formFieldPrefix, temporaryReferences, resolve, rejec
|
|
946
1127
|
// because it ensures a more deterministic encoding.
|
947
1128
|
|
948
1129
|
var lazyId = nextPartId++;
|
949
|
-
var partJSON =
|
1130
|
+
var partJSON = serializeModel(resolvedModel, lazyId); // $FlowFixMe[incompatible-type] We know it's not null because we assigned it above.
|
950
1131
|
|
951
1132
|
var data = formData; // eslint-disable-next-line react-internal/safe-string-coercion
|
952
1133
|
|
@@ -965,12 +1146,12 @@ function processReply(root, formFieldPrefix, temporaryReferences, resolve, rejec
|
|
965
1146
|
// While the first promise resolved, its value isn't necessarily what we'll
|
966
1147
|
// resolve into because we might suspend again.
|
967
1148
|
try {
|
968
|
-
var
|
1149
|
+
var _partJSON2 = serializeModel(value, _lazyId); // $FlowFixMe[incompatible-type] We know it's not null because we assigned it above.
|
969
1150
|
|
970
1151
|
|
971
1152
|
var _data = formData; // eslint-disable-next-line react-internal/safe-string-coercion
|
972
1153
|
|
973
|
-
_data.append(formFieldPrefix + _lazyId,
|
1154
|
+
_data.append(formFieldPrefix + _lazyId, _partJSON2);
|
974
1155
|
|
975
1156
|
pendingParts--;
|
976
1157
|
|
@@ -1011,12 +1192,12 @@ function processReply(root, formFieldPrefix, temporaryReferences, resolve, rejec
|
|
1011
1192
|
|
1012
1193
|
_thenable.then(function (partValue) {
|
1013
1194
|
try {
|
1014
|
-
var
|
1195
|
+
var _partJSON3 = serializeModel(partValue, promiseId); // $FlowFixMe[incompatible-type] We know it's not null because we assigned it above.
|
1015
1196
|
|
1016
1197
|
|
1017
1198
|
var _data2 = formData; // eslint-disable-next-line react-internal/safe-string-coercion
|
1018
1199
|
|
1019
|
-
_data2.append(formFieldPrefix + promiseId,
|
1200
|
+
_data2.append(formFieldPrefix + promiseId, _partJSON3);
|
1020
1201
|
|
1021
1202
|
pendingParts--;
|
1022
1203
|
|
@@ -1026,15 +1207,43 @@ function processReply(root, formFieldPrefix, temporaryReferences, resolve, rejec
|
|
1026
1207
|
} catch (reason) {
|
1027
1208
|
reject(reason);
|
1028
1209
|
}
|
1029
|
-
},
|
1030
|
-
|
1031
|
-
|
1032
|
-
reject(reason);
|
1033
|
-
});
|
1210
|
+
}, // In the future we could consider serializing this as an error
|
1211
|
+
// that throws on the server instead.
|
1212
|
+
reject);
|
1034
1213
|
|
1035
1214
|
return serializePromiseID(promiseId);
|
1036
1215
|
}
|
1037
1216
|
|
1217
|
+
var existingReference = writtenObjects.get(value);
|
1218
|
+
|
1219
|
+
if (existingReference !== undefined) {
|
1220
|
+
if (modelRoot === value) {
|
1221
|
+
// This is the ID we're currently emitting so we need to write it
|
1222
|
+
// once but if we discover it again, we refer to it by id.
|
1223
|
+
modelRoot = null;
|
1224
|
+
} else {
|
1225
|
+
// We've already emitted this as an outlined object, so we can
|
1226
|
+
// just refer to that by its existing ID.
|
1227
|
+
return existingReference;
|
1228
|
+
}
|
1229
|
+
} else if (key.indexOf(':') === -1) {
|
1230
|
+
// TODO: If the property name contains a colon, we don't dedupe. Escape instead.
|
1231
|
+
var _parentReference = writtenObjects.get(parent);
|
1232
|
+
|
1233
|
+
if (_parentReference !== undefined) {
|
1234
|
+
// If the parent has a reference, we can refer to this object indirectly
|
1235
|
+
// through the property name inside that parent.
|
1236
|
+
var _reference = _parentReference + ':' + key;
|
1237
|
+
|
1238
|
+
writtenObjects.set(value, _reference);
|
1239
|
+
|
1240
|
+
if (temporaryReferences !== undefined) {
|
1241
|
+
// Store this object so that the server can refer to it later in responses.
|
1242
|
+
writeTemporaryReference(temporaryReferences, _reference, value);
|
1243
|
+
}
|
1244
|
+
}
|
1245
|
+
}
|
1246
|
+
|
1038
1247
|
if (isArray(value)) {
|
1039
1248
|
// $FlowFixMe[incompatible-return]
|
1040
1249
|
return value;
|
@@ -1061,29 +1270,117 @@ function processReply(root, formFieldPrefix, temporaryReferences, resolve, rejec
|
|
1061
1270
|
}
|
1062
1271
|
|
1063
1272
|
if (value instanceof Map) {
|
1064
|
-
var
|
1273
|
+
var mapId = nextPartId++;
|
1274
|
+
|
1275
|
+
var _partJSON4 = serializeModel(Array.from(value), mapId);
|
1065
1276
|
|
1066
1277
|
if (formData === null) {
|
1067
1278
|
formData = new FormData();
|
1068
1279
|
}
|
1069
1280
|
|
1070
|
-
|
1071
|
-
formData.append(formFieldPrefix + mapId, _partJSON3);
|
1281
|
+
formData.append(formFieldPrefix + mapId, _partJSON4);
|
1072
1282
|
return serializeMapID(mapId);
|
1073
1283
|
}
|
1074
1284
|
|
1075
1285
|
if (value instanceof Set) {
|
1076
|
-
var
|
1286
|
+
var setId = nextPartId++;
|
1287
|
+
|
1288
|
+
var _partJSON5 = serializeModel(Array.from(value), setId);
|
1077
1289
|
|
1078
1290
|
if (formData === null) {
|
1079
1291
|
formData = new FormData();
|
1080
1292
|
}
|
1081
1293
|
|
1082
|
-
|
1083
|
-
formData.append(formFieldPrefix + setId, _partJSON4);
|
1294
|
+
formData.append(formFieldPrefix + setId, _partJSON5);
|
1084
1295
|
return serializeSetID(setId);
|
1085
1296
|
}
|
1086
1297
|
|
1298
|
+
{
|
1299
|
+
if (value instanceof ArrayBuffer) {
|
1300
|
+
var blob = new Blob([value]);
|
1301
|
+
var blobId = nextPartId++;
|
1302
|
+
|
1303
|
+
if (formData === null) {
|
1304
|
+
formData = new FormData();
|
1305
|
+
}
|
1306
|
+
|
1307
|
+
formData.append(formFieldPrefix + blobId, blob);
|
1308
|
+
return '$' + 'A' + blobId.toString(16);
|
1309
|
+
}
|
1310
|
+
|
1311
|
+
if (value instanceof Int8Array) {
|
1312
|
+
// char
|
1313
|
+
return serializeTypedArray('O', value);
|
1314
|
+
}
|
1315
|
+
|
1316
|
+
if (value instanceof Uint8Array) {
|
1317
|
+
// unsigned char
|
1318
|
+
return serializeTypedArray('o', value);
|
1319
|
+
}
|
1320
|
+
|
1321
|
+
if (value instanceof Uint8ClampedArray) {
|
1322
|
+
// unsigned clamped char
|
1323
|
+
return serializeTypedArray('U', value);
|
1324
|
+
}
|
1325
|
+
|
1326
|
+
if (value instanceof Int16Array) {
|
1327
|
+
// sort
|
1328
|
+
return serializeTypedArray('S', value);
|
1329
|
+
}
|
1330
|
+
|
1331
|
+
if (value instanceof Uint16Array) {
|
1332
|
+
// unsigned short
|
1333
|
+
return serializeTypedArray('s', value);
|
1334
|
+
}
|
1335
|
+
|
1336
|
+
if (value instanceof Int32Array) {
|
1337
|
+
// long
|
1338
|
+
return serializeTypedArray('L', value);
|
1339
|
+
}
|
1340
|
+
|
1341
|
+
if (value instanceof Uint32Array) {
|
1342
|
+
// unsigned long
|
1343
|
+
return serializeTypedArray('l', value);
|
1344
|
+
}
|
1345
|
+
|
1346
|
+
if (value instanceof Float32Array) {
|
1347
|
+
// float
|
1348
|
+
return serializeTypedArray('G', value);
|
1349
|
+
}
|
1350
|
+
|
1351
|
+
if (value instanceof Float64Array) {
|
1352
|
+
// double
|
1353
|
+
return serializeTypedArray('g', value);
|
1354
|
+
}
|
1355
|
+
|
1356
|
+
if (value instanceof BigInt64Array) {
|
1357
|
+
// number
|
1358
|
+
return serializeTypedArray('M', value);
|
1359
|
+
}
|
1360
|
+
|
1361
|
+
if (value instanceof BigUint64Array) {
|
1362
|
+
// unsigned number
|
1363
|
+
// We use "m" instead of "n" since JSON can start with "null"
|
1364
|
+
return serializeTypedArray('m', value);
|
1365
|
+
}
|
1366
|
+
|
1367
|
+
if (value instanceof DataView) {
|
1368
|
+
return serializeTypedArray('V', value);
|
1369
|
+
} // TODO: Blob is not available in old Node/browsers. Remove the typeof check later.
|
1370
|
+
|
1371
|
+
|
1372
|
+
if (typeof Blob === 'function' && value instanceof Blob) {
|
1373
|
+
if (formData === null) {
|
1374
|
+
formData = new FormData();
|
1375
|
+
}
|
1376
|
+
|
1377
|
+
var _blobId = nextPartId++;
|
1378
|
+
|
1379
|
+
formData.append(formFieldPrefix + _blobId, value);
|
1380
|
+
return serializeBlobID(_blobId);
|
1381
|
+
}
|
1382
|
+
}
|
1383
|
+
|
1087
1384
|
var iteratorFn = getIteratorFn(value);
|
1088
1385
|
|
1089
1386
|
if (iteratorFn) {
|
@@ -1091,18 +1388,33 @@ function processReply(root, formFieldPrefix, temporaryReferences, resolve, rejec
|
|
1091
1388
|
|
1092
1389
|
if (iterator === value) {
|
1093
1390
|
// Iterator, not Iterable
|
1094
|
-
var
|
1391
|
+
var iteratorId = nextPartId++;
|
1392
|
+
|
1393
|
+
var _partJSON6 = serializeModel(Array.from(iterator), iteratorId);
|
1095
1394
|
|
1096
1395
|
if (formData === null) {
|
1097
1396
|
formData = new FormData();
|
1098
1397
|
}
|
1099
1398
|
|
1100
|
-
|
1101
|
-
formData.append(formFieldPrefix + iteratorId, _partJSON5);
|
1399
|
+
formData.append(formFieldPrefix + iteratorId, _partJSON6);
|
1102
1400
|
return serializeIteratorID(iteratorId);
|
1103
1401
|
}
|
1104
1402
|
|
1105
1403
|
return Array.from(iterator);
|
1404
|
+
}
|
1405
|
+
|
1406
|
+
{
|
1407
|
+
// TODO: ReadableStream is not available in old Node. Remove the typeof check later.
|
1408
|
+
if (typeof ReadableStream === 'function' && value instanceof ReadableStream) {
|
1409
|
+
return serializeReadableStream(value);
|
1410
|
+
}
|
1411
|
+
|
1412
|
+
var getAsyncIterator = value[ASYNC_ITERATOR];
|
1413
|
+
|
1414
|
+
if (typeof getAsyncIterator === 'function') {
|
1415
|
+
// We treat AsyncIterables as a Fragment and as such we might need to key them.
|
1416
|
+
return serializeAsyncIterable(value, getAsyncIterator.call(value));
|
1417
|
+
}
|
1106
1418
|
} // Verify that this is a simple plain object.
|
1107
1419
|
|
1108
1420
|
|
@@ -1111,10 +1423,11 @@ function processReply(root, formFieldPrefix, temporaryReferences, resolve, rejec
|
|
1111
1423
|
if (proto !== ObjectPrototype && (proto === null || getPrototypeOf(proto) !== null)) {
|
1112
1424
|
if (temporaryReferences === undefined) {
|
1113
1425
|
throw new Error('Only plain objects, and a few built-ins, can be passed to Server Actions. ' + 'Classes or null prototypes are not supported.');
|
1114
|
-
} // We
|
1426
|
+
} // We will have written this object to the temporary reference set above
|
1427
|
+
// so we can replace it with a marker to refer to this slot later.
|
1115
1428
|
|
1116
1429
|
|
1117
|
-
return
|
1430
|
+
return serializeTemporaryReferenceMarker();
|
1118
1431
|
}
|
1119
1432
|
|
1120
1433
|
{
|
@@ -1183,19 +1496,41 @@ function processReply(root, formFieldPrefix, temporaryReferences, resolve, rejec
|
|
1183
1496
|
return serializeServerReferenceID(_refId);
|
1184
1497
|
}
|
1185
1498
|
|
1186
|
-
if (temporaryReferences
|
1187
|
-
|
1499
|
+
if (temporaryReferences !== undefined && key.indexOf(':') === -1) {
|
1500
|
+
// TODO: If the property name contains a colon, we don't dedupe. Escape instead.
|
1501
|
+
var _parentReference2 = writtenObjects.get(parent);
|
1502
|
+
|
1503
|
+
if (_parentReference2 !== undefined) {
|
1504
|
+
// If the parent has a reference, we can refer to this object indirectly
|
1505
|
+
// through the property name inside that parent.
|
1506
|
+
var _reference2 = _parentReference2 + ':' + key; // Store this object so that the server can refer to it later in responses.
|
1507
|
+
|
1508
|
+
|
1509
|
+
writeTemporaryReference(temporaryReferences, _reference2, value);
|
1510
|
+
return serializeTemporaryReferenceMarker();
|
1511
|
+
}
|
1188
1512
|
}
|
1189
1513
|
|
1190
|
-
|
1514
|
+
throw new Error('Client Functions cannot be passed directly to Server Functions. ' + 'Only Functions passed from the Server can be passed back again.');
|
1191
1515
|
}
|
1192
1516
|
|
1193
1517
|
if (typeof value === 'symbol') {
|
1194
|
-
if (temporaryReferences
|
1195
|
-
|
1518
|
+
if (temporaryReferences !== undefined && key.indexOf(':') === -1) {
|
1519
|
+
// TODO: If the property name contains a colon, we don't dedupe. Escape instead.
|
1520
|
+
var _parentReference3 = writtenObjects.get(parent);
|
1521
|
+
|
1522
|
+
if (_parentReference3 !== 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 _reference3 = _parentReference3 + ':' + key; // Store this object so that the server can refer to it later in responses.
|
1526
|
+
|
1527
|
+
|
1528
|
+
writeTemporaryReference(temporaryReferences, _reference3, value);
|
1529
|
+
return serializeTemporaryReferenceMarker();
|
1530
|
+
}
|
1196
1531
|
}
|
1197
1532
|
|
1198
|
-
|
1533
|
+
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) ));
|
1199
1534
|
}
|
1200
1535
|
|
1201
1536
|
if (typeof value === 'bigint') {
|
@@ -1203,10 +1538,25 @@ function processReply(root, formFieldPrefix, temporaryReferences, resolve, rejec
|
|
1203
1538
|
}
|
1204
1539
|
|
1205
1540
|
throw new Error("Type " + typeof value + " is not supported as an argument to a Server Function.");
|
1206
|
-
}
|
1541
|
+
}
|
1542
|
+
|
1543
|
+
function serializeModel(model, id) {
|
1544
|
+
if (typeof model === 'object' && model !== null) {
|
1545
|
+
var reference = serializeByValueID(id);
|
1546
|
+
writtenObjects.set(model, reference);
|
1207
1547
|
|
1548
|
+
if (temporaryReferences !== undefined) {
|
1549
|
+
// Store this object so that the server can refer to it later in responses.
|
1550
|
+
writeTemporaryReference(temporaryReferences, reference, model);
|
1551
|
+
}
|
1552
|
+
}
|
1553
|
+
|
1554
|
+
modelRoot = model; // $FlowFixMe[incompatible-return] it's not going to be undefined because we'll encode it.
|
1555
|
+
|
1556
|
+
return JSON.stringify(model, resolveToJSON);
|
1557
|
+
}
|
1208
1558
|
|
1209
|
-
var json =
|
1559
|
+
var json = serializeModel(root, 0);
|
1210
1560
|
|
1211
1561
|
if (formData === null) {
|
1212
1562
|
// If it's a simple data structure, we just use plain JSON.
|
@@ -1398,6 +1748,14 @@ function wakeChunkIfInitialized(chunk, resolveListeners, rejectListeners) {
|
|
1398
1748
|
|
1399
1749
|
function triggerErrorOnChunk(chunk, error) {
|
1400
1750
|
if (chunk.status !== PENDING && chunk.status !== BLOCKED) {
|
1751
|
+
{
|
1752
|
+
// If we get more data to an already resolved ID, we assume that it's
|
1753
|
+
// a stream chunk since any other row shouldn't have more than one entry.
|
1754
|
+
var streamChunk = chunk;
|
1755
|
+
var controller = streamChunk.reason; // $FlowFixMe[incompatible-call]: The error method should accept mixed.
|
1756
|
+
|
1757
|
+
controller.error(error);
|
1758
|
+
}
|
1401
1759
|
|
1402
1760
|
return;
|
1403
1761
|
}
|
@@ -1427,8 +1785,48 @@ function createInitializedTextChunk(response, value) {
|
|
1427
1785
|
return new Chunk(INITIALIZED, value, null, response);
|
1428
1786
|
}
|
1429
1787
|
|
1788
|
+
function createInitializedBufferChunk(response, value) {
|
1789
|
+
// $FlowFixMe[invalid-constructor] Flow doesn't support functions as constructors
|
1790
|
+
return new Chunk(INITIALIZED, value, null, response);
|
1791
|
+
}
|
1792
|
+
|
1793
|
+
function createInitializedIteratorResultChunk(response, value, done) {
|
1794
|
+
// $FlowFixMe[invalid-constructor] Flow doesn't support functions as constructors
|
1795
|
+
return new Chunk(INITIALIZED, {
|
1796
|
+
done: done,
|
1797
|
+
value: value
|
1798
|
+
}, null, response);
|
1799
|
+
}
|
1800
|
+
|
1801
|
+
function createInitializedStreamChunk(response, value, controller) {
|
1802
|
+
// We use the reason field to stash the controller since we already have that
|
1803
|
+
// field. It's a bit of a hack but efficient.
|
1804
|
+
// $FlowFixMe[invalid-constructor] Flow doesn't support functions as constructors
|
1805
|
+
return new Chunk(INITIALIZED, value, controller, response);
|
1806
|
+
}
|
1807
|
+
|
1808
|
+
function createResolvedIteratorResultChunk(response, value, done) {
|
1809
|
+
// To reuse code as much code as possible we add the wrapper element as part of the JSON.
|
1810
|
+
var iteratorResultJSON = (done ? '{"done":true,"value":' : '{"done":false,"value":') + value + '}'; // $FlowFixMe[invalid-constructor] Flow doesn't support functions as constructors
|
1811
|
+
|
1812
|
+
return new Chunk(RESOLVED_MODEL, iteratorResultJSON, null, response);
|
1813
|
+
}
|
1814
|
+
|
1815
|
+
function resolveIteratorResultChunk(chunk, value, done) {
|
1816
|
+
// To reuse code as much code as possible we add the wrapper element as part of the JSON.
|
1817
|
+
var iteratorResultJSON = (done ? '{"done":true,"value":' : '{"done":false,"value":') + value + '}';
|
1818
|
+
resolveModelChunk(chunk, iteratorResultJSON);
|
1819
|
+
}
|
1820
|
+
|
1430
1821
|
function resolveModelChunk(chunk, value) {
|
1431
1822
|
if (chunk.status !== PENDING) {
|
1823
|
+
{
|
1824
|
+
// If we get more data to an already resolved ID, we assume that it's
|
1825
|
+
// a stream chunk since any other row shouldn't have more than one entry.
|
1826
|
+
var streamChunk = chunk;
|
1827
|
+
var controller = streamChunk.reason;
|
1828
|
+
controller.enqueueModel(value);
|
1829
|
+
}
|
1432
1830
|
|
1433
1831
|
return;
|
1434
1832
|
}
|
@@ -1547,7 +1945,8 @@ function nullRefGetter() {
|
|
1547
1945
|
}
|
1548
1946
|
}
|
1549
1947
|
|
1550
|
-
function createElement(type, key, props, owner
|
1948
|
+
function createElement(type, key, props, owner, // DEV-only
|
1949
|
+
stack) // DEV-only
|
1551
1950
|
{
|
1552
1951
|
var element;
|
1553
1952
|
|
@@ -1585,6 +1984,10 @@ function createElement(type, key, props, owner) // DEV-only
|
|
1585
1984
|
writable: true,
|
1586
1985
|
value: null
|
1587
1986
|
});
|
1987
|
+
// _debugInfo later. We could move it into _store which remains mutable.
|
1988
|
+
|
1989
|
+
|
1990
|
+
Object.freeze(element.props);
|
1588
1991
|
}
|
1589
1992
|
|
1590
1993
|
return element;
|
@@ -1618,7 +2021,7 @@ function getChunk(response, id) {
|
|
1618
2021
|
return chunk;
|
1619
2022
|
}
|
1620
2023
|
|
1621
|
-
function createModelResolver(chunk, parentObject, key, cyclic, response, map) {
|
2024
|
+
function createModelResolver(chunk, parentObject, key, cyclic, response, map, path) {
|
1622
2025
|
var blocked;
|
1623
2026
|
|
1624
2027
|
if (initializingChunkBlockedModel) {
|
@@ -1635,6 +2038,10 @@ function createModelResolver(chunk, parentObject, key, cyclic, response, map) {
|
|
1635
2038
|
}
|
1636
2039
|
|
1637
2040
|
return function (value) {
|
2041
|
+
for (var i = 1; i < path.length; i++) {
|
2042
|
+
value = value[path[i]];
|
2043
|
+
}
|
2044
|
+
|
1638
2045
|
parentObject[key] = map(response, value); // If this is the root object for a model reference, where `blocked.value`
|
1639
2046
|
// is a stale `null`, the resolved value can be used directly.
|
1640
2047
|
|
@@ -1695,7 +2102,9 @@ function createServerReferenceProxy(response, metaData) {
|
|
1695
2102
|
return proxy;
|
1696
2103
|
}
|
1697
2104
|
|
1698
|
-
function getOutlinedModel(response,
|
2105
|
+
function getOutlinedModel(response, reference, parentObject, key, map) {
|
2106
|
+
var path = reference.split(':');
|
2107
|
+
var id = parseInt(path[0], 16);
|
1699
2108
|
var chunk = getChunk(response, id);
|
1700
2109
|
|
1701
2110
|
switch (chunk.status) {
|
@@ -1711,7 +2120,13 @@ function getOutlinedModel(response, id, parentObject, key, map) {
|
|
1711
2120
|
|
1712
2121
|
switch (chunk.status) {
|
1713
2122
|
case INITIALIZED:
|
1714
|
-
var
|
2123
|
+
var value = chunk.value;
|
2124
|
+
|
2125
|
+
for (var i = 1; i < path.length; i++) {
|
2126
|
+
value = value[path[i]];
|
2127
|
+
}
|
2128
|
+
|
2129
|
+
var chunkValue = map(response, value);
|
1715
2130
|
|
1716
2131
|
if (chunk._debugInfo) {
|
1717
2132
|
// If we have a direct reference to an object that was rendered by a synchronous
|
@@ -1739,7 +2154,7 @@ function getOutlinedModel(response, id, parentObject, key, map) {
|
|
1739
2154
|
case BLOCKED:
|
1740
2155
|
case CYCLIC:
|
1741
2156
|
var parentChunk = initializingChunk;
|
1742
|
-
chunk.then(createModelResolver(parentChunk, parentObject, key, chunk.status === CYCLIC, response, map), createModelReject(parentChunk));
|
2157
|
+
chunk.then(createModelResolver(parentChunk, parentObject, key, chunk.status === CYCLIC, response, map, path), createModelReject(parentChunk));
|
1743
2158
|
return null;
|
1744
2159
|
|
1745
2160
|
default:
|
@@ -1755,6 +2170,12 @@ function createSet(response, model) {
|
|
1755
2170
|
return new Set(model);
|
1756
2171
|
}
|
1757
2172
|
|
2173
|
+
function createBlob(response, model) {
|
2174
|
+
return new Blob(model.slice(1), {
|
2175
|
+
type: model[0]
|
2176
|
+
});
|
2177
|
+
}
|
2178
|
+
|
1758
2179
|
function createFormData(response, model) {
|
1759
2180
|
var formData = new FormData();
|
1760
2181
|
|
@@ -1822,61 +2243,63 @@ function parseModelString(response, parentObject, key, value) {
|
|
1822
2243
|
case 'F':
|
1823
2244
|
{
|
1824
2245
|
// Server Reference
|
1825
|
-
var
|
1826
|
-
|
1827
|
-
return getOutlinedModel(response, _id2, parentObject, key, createServerReferenceProxy);
|
2246
|
+
var ref = value.slice(2);
|
2247
|
+
return getOutlinedModel(response, ref, parentObject, key, createServerReferenceProxy);
|
1828
2248
|
}
|
1829
2249
|
|
1830
2250
|
case 'T':
|
1831
2251
|
{
|
1832
2252
|
// Temporary Reference
|
1833
|
-
var
|
1834
|
-
|
2253
|
+
var reference = '$' + value.slice(2);
|
1835
2254
|
var temporaryReferences = response._tempRefs;
|
1836
2255
|
|
1837
2256
|
if (temporaryReferences == null) {
|
1838
2257
|
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.');
|
1839
2258
|
}
|
1840
2259
|
|
1841
|
-
return readTemporaryReference(temporaryReferences,
|
2260
|
+
return readTemporaryReference(temporaryReferences, reference);
|
1842
2261
|
}
|
1843
2262
|
|
1844
2263
|
case 'Q':
|
1845
2264
|
{
|
1846
2265
|
// Map
|
1847
|
-
var
|
2266
|
+
var _ref = value.slice(2);
|
1848
2267
|
|
1849
|
-
return getOutlinedModel(response,
|
2268
|
+
return getOutlinedModel(response, _ref, parentObject, key, createMap);
|
1850
2269
|
}
|
1851
2270
|
|
1852
2271
|
case 'W':
|
1853
2272
|
{
|
1854
2273
|
// Set
|
1855
|
-
var
|
2274
|
+
var _ref2 = value.slice(2);
|
1856
2275
|
|
1857
|
-
return getOutlinedModel(response,
|
2276
|
+
return getOutlinedModel(response, _ref2, parentObject, key, createSet);
|
1858
2277
|
}
|
1859
2278
|
|
1860
2279
|
case 'B':
|
1861
2280
|
{
|
2281
|
+
// Blob
|
2282
|
+
{
|
2283
|
+
var _ref3 = value.slice(2);
|
1862
2284
|
|
1863
|
-
|
2285
|
+
return getOutlinedModel(response, _ref3, parentObject, key, createBlob);
|
2286
|
+
}
|
1864
2287
|
}
|
1865
2288
|
|
1866
2289
|
case 'K':
|
1867
2290
|
{
|
1868
2291
|
// FormData
|
1869
|
-
var
|
2292
|
+
var _ref4 = value.slice(2);
|
1870
2293
|
|
1871
|
-
return getOutlinedModel(response,
|
2294
|
+
return getOutlinedModel(response, _ref4, parentObject, key, createFormData);
|
1872
2295
|
}
|
1873
2296
|
|
1874
2297
|
case 'i':
|
1875
2298
|
{
|
1876
2299
|
// Iterator
|
1877
|
-
var
|
2300
|
+
var _ref5 = value.slice(2);
|
1878
2301
|
|
1879
|
-
return getOutlinedModel(response,
|
2302
|
+
return getOutlinedModel(response, _ref5, parentObject, key, extractIterator);
|
1880
2303
|
}
|
1881
2304
|
|
1882
2305
|
case 'I':
|
@@ -1940,9 +2363,9 @@ function parseModelString(response, parentObject, key, value) {
|
|
1940
2363
|
default:
|
1941
2364
|
{
|
1942
2365
|
// We assume that anything else is a reference ID.
|
1943
|
-
var
|
2366
|
+
var _ref6 = value.slice(1);
|
1944
2367
|
|
1945
|
-
return getOutlinedModel(response,
|
2368
|
+
return getOutlinedModel(response, _ref6, parentObject, key, createModel);
|
1946
2369
|
}
|
1947
2370
|
}
|
1948
2371
|
}
|
@@ -2003,9 +2426,41 @@ function resolveModel(response, id, model) {
|
|
2003
2426
|
function resolveText(response, id, text) {
|
2004
2427
|
var chunks = response._chunks;
|
2005
2428
|
|
2429
|
+
{
|
2430
|
+
var chunk = chunks.get(id);
|
2431
|
+
|
2432
|
+
if (chunk && chunk.status !== PENDING) {
|
2433
|
+
// If we get more data to an already resolved ID, we assume that it's
|
2434
|
+
// a stream chunk since any other row shouldn't have more than one entry.
|
2435
|
+
var streamChunk = chunk;
|
2436
|
+
var controller = streamChunk.reason;
|
2437
|
+
controller.enqueueValue(text);
|
2438
|
+
return;
|
2439
|
+
}
|
2440
|
+
}
|
2441
|
+
|
2006
2442
|
chunks.set(id, createInitializedTextChunk(response, text));
|
2007
2443
|
}
|
2008
2444
|
|
2445
|
+
function resolveBuffer(response, id, buffer) {
|
2446
|
+
var chunks = response._chunks;
|
2447
|
+
|
2448
|
+
{
|
2449
|
+
var chunk = chunks.get(id);
|
2450
|
+
|
2451
|
+
if (chunk && chunk.status !== PENDING) {
|
2452
|
+
// If we get more data to an already resolved ID, we assume that it's
|
2453
|
+
// a stream chunk since any other row shouldn't have more than one entry.
|
2454
|
+
var streamChunk = chunk;
|
2455
|
+
var controller = streamChunk.reason;
|
2456
|
+
controller.enqueueValue(buffer);
|
2457
|
+
return;
|
2458
|
+
}
|
2459
|
+
}
|
2460
|
+
|
2461
|
+
chunks.set(id, createInitializedBufferChunk(response, buffer));
|
2462
|
+
}
|
2463
|
+
|
2009
2464
|
function resolveModule(response, id, model) {
|
2010
2465
|
var chunks = response._chunks;
|
2011
2466
|
var chunk = chunks.get(id);
|
@@ -2047,6 +2502,245 @@ function resolveModule(response, id, model) {
|
|
2047
2502
|
}
|
2048
2503
|
}
|
2049
2504
|
|
2505
|
+
function resolveStream(response, id, stream, controller) {
|
2506
|
+
var chunks = response._chunks;
|
2507
|
+
var chunk = chunks.get(id);
|
2508
|
+
|
2509
|
+
if (!chunk) {
|
2510
|
+
chunks.set(id, createInitializedStreamChunk(response, stream, controller));
|
2511
|
+
return;
|
2512
|
+
}
|
2513
|
+
|
2514
|
+
if (chunk.status !== PENDING) {
|
2515
|
+
// We already resolved. We didn't expect to see this.
|
2516
|
+
return;
|
2517
|
+
}
|
2518
|
+
|
2519
|
+
var resolveListeners = chunk.value;
|
2520
|
+
var resolvedChunk = chunk;
|
2521
|
+
resolvedChunk.status = INITIALIZED;
|
2522
|
+
resolvedChunk.value = stream;
|
2523
|
+
resolvedChunk.reason = controller;
|
2524
|
+
|
2525
|
+
if (resolveListeners !== null) {
|
2526
|
+
wakeChunk(resolveListeners, chunk.value);
|
2527
|
+
}
|
2528
|
+
}
|
2529
|
+
|
2530
|
+
function startReadableStream(response, id, type) {
|
2531
|
+
var controller = null;
|
2532
|
+
var stream = new ReadableStream({
|
2533
|
+
type: type,
|
2534
|
+
start: function (c) {
|
2535
|
+
controller = c;
|
2536
|
+
}
|
2537
|
+
});
|
2538
|
+
var previousBlockedChunk = null;
|
2539
|
+
var flightController = {
|
2540
|
+
enqueueValue: function (value) {
|
2541
|
+
if (previousBlockedChunk === null) {
|
2542
|
+
controller.enqueue(value);
|
2543
|
+
} else {
|
2544
|
+
// We're still waiting on a previous chunk so we can't enqueue quite yet.
|
2545
|
+
previousBlockedChunk.then(function () {
|
2546
|
+
controller.enqueue(value);
|
2547
|
+
});
|
2548
|
+
}
|
2549
|
+
},
|
2550
|
+
enqueueModel: function (json) {
|
2551
|
+
if (previousBlockedChunk === null) {
|
2552
|
+
// If we're not blocked on any other chunks, we can try to eagerly initialize
|
2553
|
+
// this as a fast-path to avoid awaiting them.
|
2554
|
+
var chunk = createResolvedModelChunk(response, json);
|
2555
|
+
initializeModelChunk(chunk);
|
2556
|
+
var initializedChunk = chunk;
|
2557
|
+
|
2558
|
+
if (initializedChunk.status === INITIALIZED) {
|
2559
|
+
controller.enqueue(initializedChunk.value);
|
2560
|
+
} else {
|
2561
|
+
chunk.then(function (v) {
|
2562
|
+
return controller.enqueue(v);
|
2563
|
+
}, function (e) {
|
2564
|
+
return controller.error(e);
|
2565
|
+
});
|
2566
|
+
previousBlockedChunk = chunk;
|
2567
|
+
}
|
2568
|
+
} else {
|
2569
|
+
// We're still waiting on a previous chunk so we can't enqueue quite yet.
|
2570
|
+
var blockedChunk = previousBlockedChunk;
|
2571
|
+
|
2572
|
+
var _chunk2 = createPendingChunk(response);
|
2573
|
+
|
2574
|
+
_chunk2.then(function (v) {
|
2575
|
+
return controller.enqueue(v);
|
2576
|
+
}, function (e) {
|
2577
|
+
return controller.error(e);
|
2578
|
+
});
|
2579
|
+
|
2580
|
+
previousBlockedChunk = _chunk2;
|
2581
|
+
blockedChunk.then(function () {
|
2582
|
+
if (previousBlockedChunk === _chunk2) {
|
2583
|
+
// We were still the last chunk so we can now clear the queue and return
|
2584
|
+
// to synchronous emitting.
|
2585
|
+
previousBlockedChunk = null;
|
2586
|
+
}
|
2587
|
+
|
2588
|
+
resolveModelChunk(_chunk2, json);
|
2589
|
+
});
|
2590
|
+
}
|
2591
|
+
},
|
2592
|
+
close: function (json) {
|
2593
|
+
if (previousBlockedChunk === null) {
|
2594
|
+
controller.close();
|
2595
|
+
} else {
|
2596
|
+
var blockedChunk = previousBlockedChunk; // We shouldn't get any more enqueues after this so we can set it back to null.
|
2597
|
+
|
2598
|
+
previousBlockedChunk = null;
|
2599
|
+
blockedChunk.then(function () {
|
2600
|
+
return controller.close();
|
2601
|
+
});
|
2602
|
+
}
|
2603
|
+
},
|
2604
|
+
error: function (error) {
|
2605
|
+
if (previousBlockedChunk === null) {
|
2606
|
+
// $FlowFixMe[incompatible-call]
|
2607
|
+
controller.error(error);
|
2608
|
+
} else {
|
2609
|
+
var blockedChunk = previousBlockedChunk; // We shouldn't get any more enqueues after this so we can set it back to null.
|
2610
|
+
|
2611
|
+
previousBlockedChunk = null;
|
2612
|
+
blockedChunk.then(function () {
|
2613
|
+
return controller.error(error);
|
2614
|
+
});
|
2615
|
+
}
|
2616
|
+
}
|
2617
|
+
};
|
2618
|
+
resolveStream(response, id, stream, flightController);
|
2619
|
+
}
|
2620
|
+
|
2621
|
+
function asyncIterator() {
|
2622
|
+
// Self referencing iterator.
|
2623
|
+
return this;
|
2624
|
+
}
|
2625
|
+
|
2626
|
+
function createIterator(next) {
|
2627
|
+
var iterator = {
|
2628
|
+
next: next // TODO: Add return/throw as options for aborting.
|
2629
|
+
|
2630
|
+
}; // TODO: The iterator could inherit the AsyncIterator prototype which is not exposed as
|
2631
|
+
// a global but exists as a prototype of an AsyncGenerator. However, it's not needed
|
2632
|
+
// to satisfy the iterable protocol.
|
2633
|
+
|
2634
|
+
iterator[ASYNC_ITERATOR] = asyncIterator;
|
2635
|
+
return iterator;
|
2636
|
+
}
|
2637
|
+
|
2638
|
+
function startAsyncIterable(response, id, iterator) {
|
2639
|
+
var buffer = [];
|
2640
|
+
var closed = false;
|
2641
|
+
var nextWriteIndex = 0;
|
2642
|
+
var flightController = {
|
2643
|
+
enqueueValue: function (value) {
|
2644
|
+
if (nextWriteIndex === buffer.length) {
|
2645
|
+
buffer[nextWriteIndex] = createInitializedIteratorResultChunk(response, value, false);
|
2646
|
+
} else {
|
2647
|
+
var chunk = buffer[nextWriteIndex];
|
2648
|
+
var resolveListeners = chunk.value;
|
2649
|
+
var rejectListeners = chunk.reason;
|
2650
|
+
var initializedChunk = chunk;
|
2651
|
+
initializedChunk.status = INITIALIZED;
|
2652
|
+
initializedChunk.value = {
|
2653
|
+
done: false,
|
2654
|
+
value: value
|
2655
|
+
};
|
2656
|
+
|
2657
|
+
if (resolveListeners !== null) {
|
2658
|
+
wakeChunkIfInitialized(chunk, resolveListeners, rejectListeners);
|
2659
|
+
}
|
2660
|
+
}
|
2661
|
+
|
2662
|
+
nextWriteIndex++;
|
2663
|
+
},
|
2664
|
+
enqueueModel: function (value) {
|
2665
|
+
if (nextWriteIndex === buffer.length) {
|
2666
|
+
buffer[nextWriteIndex] = createResolvedIteratorResultChunk(response, value, false);
|
2667
|
+
} else {
|
2668
|
+
resolveIteratorResultChunk(buffer[nextWriteIndex], value, false);
|
2669
|
+
}
|
2670
|
+
|
2671
|
+
nextWriteIndex++;
|
2672
|
+
},
|
2673
|
+
close: function (value) {
|
2674
|
+
closed = true;
|
2675
|
+
|
2676
|
+
if (nextWriteIndex === buffer.length) {
|
2677
|
+
buffer[nextWriteIndex] = createResolvedIteratorResultChunk(response, value, true);
|
2678
|
+
} else {
|
2679
|
+
resolveIteratorResultChunk(buffer[nextWriteIndex], value, true);
|
2680
|
+
}
|
2681
|
+
|
2682
|
+
nextWriteIndex++;
|
2683
|
+
|
2684
|
+
while (nextWriteIndex < buffer.length) {
|
2685
|
+
// In generators, any extra reads from the iterator have the value undefined.
|
2686
|
+
resolveIteratorResultChunk(buffer[nextWriteIndex++], '"$undefined"', true);
|
2687
|
+
}
|
2688
|
+
},
|
2689
|
+
error: function (error) {
|
2690
|
+
closed = true;
|
2691
|
+
|
2692
|
+
if (nextWriteIndex === buffer.length) {
|
2693
|
+
buffer[nextWriteIndex] = createPendingChunk(response);
|
2694
|
+
}
|
2695
|
+
|
2696
|
+
while (nextWriteIndex < buffer.length) {
|
2697
|
+
triggerErrorOnChunk(buffer[nextWriteIndex++], error);
|
2698
|
+
}
|
2699
|
+
}
|
2700
|
+
};
|
2701
|
+
|
2702
|
+
var iterable = _defineProperty({}, ASYNC_ITERATOR, function () {
|
2703
|
+
var nextReadIndex = 0;
|
2704
|
+
return createIterator(function (arg) {
|
2705
|
+
if (arg !== undefined) {
|
2706
|
+
throw new Error('Values cannot be passed to next() of AsyncIterables passed to Client Components.');
|
2707
|
+
}
|
2708
|
+
|
2709
|
+
if (nextReadIndex === buffer.length) {
|
2710
|
+
if (closed) {
|
2711
|
+
// $FlowFixMe[invalid-constructor] Flow doesn't support functions as constructors
|
2712
|
+
return new Chunk(INITIALIZED, {
|
2713
|
+
done: true,
|
2714
|
+
value: undefined
|
2715
|
+
}, null, response);
|
2716
|
+
}
|
2717
|
+
|
2718
|
+
buffer[nextReadIndex] = createPendingChunk(response);
|
2719
|
+
}
|
2720
|
+
|
2721
|
+
return buffer[nextReadIndex++];
|
2722
|
+
});
|
2723
|
+
}); // TODO: If it's a single shot iterator we can optimize memory by cleaning up the buffer after
|
2724
|
+
// reading through the end, but currently we favor code size over this optimization.
|
2725
|
+
|
2726
|
+
|
2727
|
+
resolveStream(response, id, iterator ? iterable[ASYNC_ITERATOR]() : iterable, flightController);
|
2728
|
+
}
|
2729
|
+
|
2730
|
+
function stopStream(response, id, row) {
|
2731
|
+
var chunks = response._chunks;
|
2732
|
+
var chunk = chunks.get(id);
|
2733
|
+
|
2734
|
+
if (!chunk || chunk.status !== INITIALIZED) {
|
2735
|
+
// We didn't expect not to have an existing stream;
|
2736
|
+
return;
|
2737
|
+
}
|
2738
|
+
|
2739
|
+
var streamChunk = chunk;
|
2740
|
+
var controller = streamChunk.reason;
|
2741
|
+
controller.close(row === '' ? '"$undefined"' : row);
|
2742
|
+
}
|
2743
|
+
|
2050
2744
|
function resolveErrorDev(response, id, digest, message, stack) {
|
2051
2745
|
|
2052
2746
|
|
@@ -2088,7 +2782,127 @@ function resolveConsoleEntry(response, value) {
|
|
2088
2782
|
printToConsole(methodName, args, env);
|
2089
2783
|
}
|
2090
2784
|
|
2785
|
+
function mergeBuffer(buffer, lastChunk) {
|
2786
|
+
var l = buffer.length; // Count the bytes we'll need
|
2787
|
+
|
2788
|
+
var byteLength = lastChunk.length;
|
2789
|
+
|
2790
|
+
for (var i = 0; i < l; i++) {
|
2791
|
+
byteLength += buffer[i].byteLength;
|
2792
|
+
} // Allocate enough contiguous space
|
2793
|
+
|
2794
|
+
|
2795
|
+
var result = new Uint8Array(byteLength);
|
2796
|
+
var offset = 0; // Copy all the buffers into it.
|
2797
|
+
|
2798
|
+
for (var _i = 0; _i < l; _i++) {
|
2799
|
+
var chunk = buffer[_i];
|
2800
|
+
result.set(chunk, offset);
|
2801
|
+
offset += chunk.byteLength;
|
2802
|
+
}
|
2803
|
+
|
2804
|
+
result.set(lastChunk, offset);
|
2805
|
+
return result;
|
2806
|
+
}
|
2807
|
+
|
2808
|
+
function resolveTypedArray(response, id, buffer, lastChunk, constructor, bytesPerElement) {
|
2809
|
+
// If the view fits into one original buffer, we just reuse that buffer instead of
|
2810
|
+
// copying it out to a separate copy. This means that it's not always possible to
|
2811
|
+
// transfer these values to other threads without copying first since they may
|
2812
|
+
// share array buffer. For this to work, it must also have bytes aligned to a
|
2813
|
+
// multiple of a size of the type.
|
2814
|
+
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
|
2815
|
+
// we should convert it instead. In practice big endian isn't really Web compatible so it's
|
2816
|
+
// somewhat safe to assume that browsers aren't going to run it, but maybe there's some SSR
|
2817
|
+
// server that's affected.
|
2818
|
+
|
2819
|
+
var view = new constructor(chunk.buffer, chunk.byteOffset, chunk.byteLength / bytesPerElement);
|
2820
|
+
resolveBuffer(response, id, view);
|
2821
|
+
}
|
2822
|
+
|
2091
2823
|
function processFullRow(response, id, tag, buffer, chunk) {
|
2824
|
+
{
|
2825
|
+
switch (tag) {
|
2826
|
+
case 65
|
2827
|
+
/* "A" */
|
2828
|
+
:
|
2829
|
+
// We must always clone to extract it into a separate buffer instead of just a view.
|
2830
|
+
resolveBuffer(response, id, mergeBuffer(buffer, chunk).buffer);
|
2831
|
+
return;
|
2832
|
+
|
2833
|
+
case 79
|
2834
|
+
/* "O" */
|
2835
|
+
:
|
2836
|
+
resolveTypedArray(response, id, buffer, chunk, Int8Array, 1);
|
2837
|
+
return;
|
2838
|
+
|
2839
|
+
case 111
|
2840
|
+
/* "o" */
|
2841
|
+
:
|
2842
|
+
resolveBuffer(response, id, buffer.length === 0 ? chunk : mergeBuffer(buffer, chunk));
|
2843
|
+
return;
|
2844
|
+
|
2845
|
+
case 85
|
2846
|
+
/* "U" */
|
2847
|
+
:
|
2848
|
+
resolveTypedArray(response, id, buffer, chunk, Uint8ClampedArray, 1);
|
2849
|
+
return;
|
2850
|
+
|
2851
|
+
case 83
|
2852
|
+
/* "S" */
|
2853
|
+
:
|
2854
|
+
resolveTypedArray(response, id, buffer, chunk, Int16Array, 2);
|
2855
|
+
return;
|
2856
|
+
|
2857
|
+
case 115
|
2858
|
+
/* "s" */
|
2859
|
+
:
|
2860
|
+
resolveTypedArray(response, id, buffer, chunk, Uint16Array, 2);
|
2861
|
+
return;
|
2862
|
+
|
2863
|
+
case 76
|
2864
|
+
/* "L" */
|
2865
|
+
:
|
2866
|
+
resolveTypedArray(response, id, buffer, chunk, Int32Array, 4);
|
2867
|
+
return;
|
2868
|
+
|
2869
|
+
case 108
|
2870
|
+
/* "l" */
|
2871
|
+
:
|
2872
|
+
resolveTypedArray(response, id, buffer, chunk, Uint32Array, 4);
|
2873
|
+
return;
|
2874
|
+
|
2875
|
+
case 71
|
2876
|
+
/* "G" */
|
2877
|
+
:
|
2878
|
+
resolveTypedArray(response, id, buffer, chunk, Float32Array, 4);
|
2879
|
+
return;
|
2880
|
+
|
2881
|
+
case 103
|
2882
|
+
/* "g" */
|
2883
|
+
:
|
2884
|
+
resolveTypedArray(response, id, buffer, chunk, Float64Array, 8);
|
2885
|
+
return;
|
2886
|
+
|
2887
|
+
case 77
|
2888
|
+
/* "M" */
|
2889
|
+
:
|
2890
|
+
resolveTypedArray(response, id, buffer, chunk, BigInt64Array, 8);
|
2891
|
+
return;
|
2892
|
+
|
2893
|
+
case 109
|
2894
|
+
/* "m" */
|
2895
|
+
:
|
2896
|
+
resolveTypedArray(response, id, buffer, chunk, BigUint64Array, 8);
|
2897
|
+
return;
|
2898
|
+
|
2899
|
+
case 86
|
2900
|
+
/* "V" */
|
2901
|
+
:
|
2902
|
+
resolveTypedArray(response, id, buffer, chunk, DataView, 1);
|
2903
|
+
return;
|
2904
|
+
}
|
2905
|
+
}
|
2092
2906
|
|
2093
2907
|
var stringDecoder = response._stringDecoder;
|
2094
2908
|
var row = '';
|
@@ -2163,26 +2977,56 @@ function processFullRow(response, id, tag, buffer, chunk) {
|
|
2163
2977
|
case 82
|
2164
2978
|
/* "R" */
|
2165
2979
|
:
|
2980
|
+
{
|
2981
|
+
{
|
2982
|
+
startReadableStream(response, id, undefined);
|
2983
|
+
return;
|
2984
|
+
}
|
2985
|
+
}
|
2166
2986
|
// Fallthrough
|
2167
2987
|
|
2168
2988
|
case 114
|
2169
2989
|
/* "r" */
|
2170
2990
|
:
|
2991
|
+
{
|
2992
|
+
{
|
2993
|
+
startReadableStream(response, id, 'bytes');
|
2994
|
+
return;
|
2995
|
+
}
|
2996
|
+
}
|
2171
2997
|
// Fallthrough
|
2172
2998
|
|
2173
2999
|
case 88
|
2174
3000
|
/* "X" */
|
2175
3001
|
:
|
3002
|
+
{
|
3003
|
+
{
|
3004
|
+
startAsyncIterable(response, id, false);
|
3005
|
+
return;
|
3006
|
+
}
|
3007
|
+
}
|
2176
3008
|
// Fallthrough
|
2177
3009
|
|
2178
3010
|
case 120
|
2179
3011
|
/* "x" */
|
2180
3012
|
:
|
3013
|
+
{
|
3014
|
+
{
|
3015
|
+
startAsyncIterable(response, id, true);
|
3016
|
+
return;
|
3017
|
+
}
|
3018
|
+
}
|
2181
3019
|
// Fallthrough
|
2182
3020
|
|
2183
3021
|
case 67
|
2184
3022
|
/* "C" */
|
2185
3023
|
:
|
3024
|
+
{
|
3025
|
+
{
|
3026
|
+
stopStream(response, id, row);
|
3027
|
+
return;
|
3028
|
+
}
|
3029
|
+
}
|
2186
3030
|
// Fallthrough
|
2187
3031
|
|
2188
3032
|
case 80
|
@@ -2235,7 +3079,31 @@ function processBinaryChunk(response, chunk) {
|
|
2235
3079
|
|
2236
3080
|
if (resolvedRowTag === 84
|
2237
3081
|
/* "T" */
|
2238
|
-
||
|
3082
|
+
|| (resolvedRowTag === 65
|
3083
|
+
/* "A" */
|
3084
|
+
|| resolvedRowTag === 79
|
3085
|
+
/* "O" */
|
3086
|
+
|| resolvedRowTag === 111
|
3087
|
+
/* "o" */
|
3088
|
+
|| resolvedRowTag === 85
|
3089
|
+
/* "U" */
|
3090
|
+
|| resolvedRowTag === 83
|
3091
|
+
/* "S" */
|
3092
|
+
|| resolvedRowTag === 115
|
3093
|
+
/* "s" */
|
3094
|
+
|| resolvedRowTag === 76
|
3095
|
+
/* "L" */
|
3096
|
+
|| resolvedRowTag === 108
|
3097
|
+
/* "l" */
|
3098
|
+
|| resolvedRowTag === 71
|
3099
|
+
/* "G" */
|
3100
|
+
|| resolvedRowTag === 103
|
3101
|
+
/* "g" */
|
3102
|
+
|| resolvedRowTag === 77
|
3103
|
+
/* "M" */
|
3104
|
+
|| resolvedRowTag === 109
|
3105
|
+
/* "m" */
|
3106
|
+
|| resolvedRowTag === 86)
|
2239
3107
|
/* "V" */
|
2240
3108
|
) {
|
2241
3109
|
rowTag = resolvedRowTag;
|