react-server-dom-webpack 19.0.0-canary-cf5ab8b8b2-20240425 → 19.0.0-rc-3f1436cca1-20240516
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cjs/react-server-dom-webpack-client.browser.development.js +941 -73
- package/cjs/react-server-dom-webpack-client.browser.production.js +722 -229
- package/cjs/react-server-dom-webpack-client.edge.development.js +941 -73
- package/cjs/react-server-dom-webpack-client.edge.production.js +722 -229
- package/cjs/react-server-dom-webpack-client.node.development.js +940 -72
- package/cjs/react-server-dom-webpack-client.node.production.js +707 -219
- package/cjs/react-server-dom-webpack-client.node.unbundled.development.js +940 -72
- package/cjs/react-server-dom-webpack-client.node.unbundled.production.js +707 -219
- package/cjs/react-server-dom-webpack-server.browser.development.js +1335 -235
- package/cjs/react-server-dom-webpack-server.browser.production.js +865 -202
- package/cjs/react-server-dom-webpack-server.edge.development.js +1341 -233
- package/cjs/react-server-dom-webpack-server.edge.production.js +865 -202
- package/cjs/react-server-dom-webpack-server.node.development.js +1294 -237
- package/cjs/react-server-dom-webpack-server.node.production.js +860 -223
- package/cjs/react-server-dom-webpack-server.node.unbundled.development.js +1294 -237
- package/cjs/react-server-dom-webpack-server.node.unbundled.production.js +860 -223
- package/package.json +3 -3
@@ -18,8 +18,20 @@ var util = require('util');
|
|
18
18
|
var ReactDOM = require('react-dom');
|
19
19
|
var React = require('react');
|
20
20
|
|
21
|
-
|
22
|
-
|
21
|
+
function _defineProperty(obj, key, value) {
|
22
|
+
if (key in obj) {
|
23
|
+
Object.defineProperty(obj, key, {
|
24
|
+
value: value,
|
25
|
+
enumerable: true,
|
26
|
+
configurable: true,
|
27
|
+
writable: true
|
28
|
+
});
|
29
|
+
} else {
|
30
|
+
obj[key] = value;
|
31
|
+
}
|
32
|
+
|
33
|
+
return obj;
|
34
|
+
}
|
23
35
|
|
24
36
|
function createStringDecoder() {
|
25
37
|
return new util.TextDecoder();
|
@@ -766,20 +778,11 @@ function describeObjectForErrorMessage(objectOrArray, expandedName) {
|
|
766
778
|
return '\n ' + str;
|
767
779
|
}
|
768
780
|
|
769
|
-
function writeTemporaryReference(set, object) {
|
770
|
-
|
771
|
-
// object. This ensures that we always generate a deterministic encoding of
|
772
|
-
// each slot in the reply for cacheability.
|
773
|
-
var newId = set.length;
|
774
|
-
set.push(object);
|
775
|
-
return newId;
|
781
|
+
function writeTemporaryReference(set, reference, object) {
|
782
|
+
set.set(reference, object);
|
776
783
|
}
|
777
|
-
function readTemporaryReference(set,
|
778
|
-
|
779
|
-
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.');
|
780
|
-
}
|
781
|
-
|
782
|
-
return set[id];
|
784
|
+
function readTemporaryReference(set, reference) {
|
785
|
+
return set.get(reference);
|
783
786
|
}
|
784
787
|
|
785
788
|
var ObjectPrototype = Object.prototype;
|
@@ -798,8 +801,8 @@ function serializeServerReferenceID(id) {
|
|
798
801
|
return '$F' + id.toString(16);
|
799
802
|
}
|
800
803
|
|
801
|
-
function
|
802
|
-
return '$T'
|
804
|
+
function serializeTemporaryReferenceMarker() {
|
805
|
+
return '$T';
|
803
806
|
}
|
804
807
|
|
805
808
|
function serializeFormDataReference(id) {
|
@@ -847,6 +850,10 @@ function serializeSetID(id) {
|
|
847
850
|
return '$W' + id.toString(16);
|
848
851
|
}
|
849
852
|
|
853
|
+
function serializeBlobID(id) {
|
854
|
+
return '$B' + id.toString(16);
|
855
|
+
}
|
856
|
+
|
850
857
|
function serializeIteratorID(id) {
|
851
858
|
return '$i' + id.toString(16);
|
852
859
|
}
|
@@ -865,6 +872,170 @@ function processReply(root, formFieldPrefix, temporaryReferences, resolve, rejec
|
|
865
872
|
var nextPartId = 1;
|
866
873
|
var pendingParts = 0;
|
867
874
|
var formData = null;
|
875
|
+
var writtenObjects = new WeakMap();
|
876
|
+
var modelRoot = root;
|
877
|
+
|
878
|
+
function serializeTypedArray(tag, typedArray) {
|
879
|
+
var blob = new Blob([// We should be able to pass the buffer straight through but Node < 18 treat
|
880
|
+
// multi-byte array blobs differently so we first convert it to single-byte.
|
881
|
+
new Uint8Array(typedArray.buffer, typedArray.byteOffset, typedArray.byteLength)]);
|
882
|
+
var blobId = nextPartId++;
|
883
|
+
|
884
|
+
if (formData === null) {
|
885
|
+
formData = new FormData();
|
886
|
+
}
|
887
|
+
|
888
|
+
formData.append(formFieldPrefix + blobId, blob);
|
889
|
+
return '$' + tag + blobId.toString(16);
|
890
|
+
}
|
891
|
+
|
892
|
+
function serializeBinaryReader(reader) {
|
893
|
+
if (formData === null) {
|
894
|
+
// Upgrade to use FormData to allow us to stream this value.
|
895
|
+
formData = new FormData();
|
896
|
+
}
|
897
|
+
|
898
|
+
var data = formData;
|
899
|
+
pendingParts++;
|
900
|
+
var streamId = nextPartId++;
|
901
|
+
var buffer = [];
|
902
|
+
|
903
|
+
function progress(entry) {
|
904
|
+
if (entry.done) {
|
905
|
+
var blobId = nextPartId++; // eslint-disable-next-line react-internal/safe-string-coercion
|
906
|
+
|
907
|
+
data.append(formFieldPrefix + blobId, new Blob(buffer)); // eslint-disable-next-line react-internal/safe-string-coercion
|
908
|
+
|
909
|
+
data.append(formFieldPrefix + streamId, '"$o' + blobId.toString(16) + '"'); // eslint-disable-next-line react-internal/safe-string-coercion
|
910
|
+
|
911
|
+
data.append(formFieldPrefix + streamId, 'C'); // Close signal
|
912
|
+
|
913
|
+
pendingParts--;
|
914
|
+
|
915
|
+
if (pendingParts === 0) {
|
916
|
+
resolve(data);
|
917
|
+
}
|
918
|
+
} else {
|
919
|
+
buffer.push(entry.value);
|
920
|
+
reader.read(new Uint8Array(1024)).then(progress, reject);
|
921
|
+
}
|
922
|
+
}
|
923
|
+
|
924
|
+
reader.read(new Uint8Array(1024)).then(progress, reject);
|
925
|
+
return '$r' + streamId.toString(16);
|
926
|
+
}
|
927
|
+
|
928
|
+
function serializeReader(reader) {
|
929
|
+
if (formData === null) {
|
930
|
+
// Upgrade to use FormData to allow us to stream this value.
|
931
|
+
formData = new FormData();
|
932
|
+
}
|
933
|
+
|
934
|
+
var data = formData;
|
935
|
+
pendingParts++;
|
936
|
+
var streamId = nextPartId++;
|
937
|
+
|
938
|
+
function progress(entry) {
|
939
|
+
if (entry.done) {
|
940
|
+
// eslint-disable-next-line react-internal/safe-string-coercion
|
941
|
+
data.append(formFieldPrefix + streamId, 'C'); // Close signal
|
942
|
+
|
943
|
+
pendingParts--;
|
944
|
+
|
945
|
+
if (pendingParts === 0) {
|
946
|
+
resolve(data);
|
947
|
+
}
|
948
|
+
} else {
|
949
|
+
try {
|
950
|
+
// $FlowFixMe[incompatible-type]: While plain JSON can return undefined we never do here.
|
951
|
+
var partJSON = JSON.stringify(entry.value, resolveToJSON); // eslint-disable-next-line react-internal/safe-string-coercion
|
952
|
+
|
953
|
+
data.append(formFieldPrefix + streamId, partJSON);
|
954
|
+
reader.read().then(progress, reject);
|
955
|
+
} catch (x) {
|
956
|
+
reject(x);
|
957
|
+
}
|
958
|
+
}
|
959
|
+
}
|
960
|
+
|
961
|
+
reader.read().then(progress, reject);
|
962
|
+
return '$R' + streamId.toString(16);
|
963
|
+
}
|
964
|
+
|
965
|
+
function serializeReadableStream(stream) {
|
966
|
+
// Detect if this is a BYOB stream. BYOB streams should be able to be read as bytes on the
|
967
|
+
// receiving side. For binary streams, we serialize them as plain Blobs.
|
968
|
+
var binaryReader;
|
969
|
+
|
970
|
+
try {
|
971
|
+
// $FlowFixMe[extra-arg]: This argument is accepted.
|
972
|
+
binaryReader = stream.getReader({
|
973
|
+
mode: 'byob'
|
974
|
+
});
|
975
|
+
} catch (x) {
|
976
|
+
return serializeReader(stream.getReader());
|
977
|
+
}
|
978
|
+
|
979
|
+
return serializeBinaryReader(binaryReader);
|
980
|
+
}
|
981
|
+
|
982
|
+
function serializeAsyncIterable(iterable, iterator) {
|
983
|
+
if (formData === null) {
|
984
|
+
// Upgrade to use FormData to allow us to stream this value.
|
985
|
+
formData = new FormData();
|
986
|
+
}
|
987
|
+
|
988
|
+
var data = formData;
|
989
|
+
pendingParts++;
|
990
|
+
var streamId = nextPartId++; // Generators/Iterators are Iterables but they're also their own iterator
|
991
|
+
// functions. If that's the case, we treat them as single-shot. Otherwise,
|
992
|
+
// we assume that this iterable might be a multi-shot and allow it to be
|
993
|
+
// iterated more than once on the receiving server.
|
994
|
+
|
995
|
+
var isIterator = iterable === iterator; // There's a race condition between when the stream is aborted and when the promise
|
996
|
+
// resolves so we track whether we already aborted it to avoid writing twice.
|
997
|
+
|
998
|
+
function progress(entry) {
|
999
|
+
if (entry.done) {
|
1000
|
+
if (entry.value === undefined) {
|
1001
|
+
// eslint-disable-next-line react-internal/safe-string-coercion
|
1002
|
+
data.append(formFieldPrefix + streamId, 'C'); // Close signal
|
1003
|
+
} else {
|
1004
|
+
// Unlike streams, the last value may not be undefined. If it's not
|
1005
|
+
// we outline it and encode a reference to it in the closing instruction.
|
1006
|
+
try {
|
1007
|
+
// $FlowFixMe[incompatible-type]: While plain JSON can return undefined we never do here.
|
1008
|
+
var partJSON = JSON.stringify(entry.value, resolveToJSON);
|
1009
|
+
data.append(formFieldPrefix + streamId, 'C' + partJSON); // Close signal
|
1010
|
+
} catch (x) {
|
1011
|
+
reject(x);
|
1012
|
+
return;
|
1013
|
+
}
|
1014
|
+
}
|
1015
|
+
|
1016
|
+
pendingParts--;
|
1017
|
+
|
1018
|
+
if (pendingParts === 0) {
|
1019
|
+
resolve(data);
|
1020
|
+
}
|
1021
|
+
} else {
|
1022
|
+
try {
|
1023
|
+
// $FlowFixMe[incompatible-type]: While plain JSON can return undefined we never do here.
|
1024
|
+
var _partJSON = JSON.stringify(entry.value, resolveToJSON); // eslint-disable-next-line react-internal/safe-string-coercion
|
1025
|
+
|
1026
|
+
|
1027
|
+
data.append(formFieldPrefix + streamId, _partJSON);
|
1028
|
+
iterator.next().then(progress, reject);
|
1029
|
+
} catch (x) {
|
1030
|
+
reject(x);
|
1031
|
+
return;
|
1032
|
+
}
|
1033
|
+
}
|
1034
|
+
}
|
1035
|
+
|
1036
|
+
iterator.next().then(progress, reject);
|
1037
|
+
return '$' + (isIterator ? 'x' : 'X') + streamId.toString(16);
|
1038
|
+
}
|
868
1039
|
|
869
1040
|
function resolveToJSON(key, value) {
|
870
1041
|
var parent = this; // Make sure that `parent[key]` wasn't JSONified before `value` was passed to us
|
@@ -890,11 +1061,21 @@ function processReply(root, formFieldPrefix, temporaryReferences, resolve, rejec
|
|
890
1061
|
switch (value.$$typeof) {
|
891
1062
|
case REACT_ELEMENT_TYPE:
|
892
1063
|
{
|
893
|
-
if (temporaryReferences
|
894
|
-
|
1064
|
+
if (temporaryReferences !== undefined && key.indexOf(':') === -1) {
|
1065
|
+
// TODO: If the property name contains a colon, we don't dedupe. Escape instead.
|
1066
|
+
var parentReference = writtenObjects.get(parent);
|
1067
|
+
|
1068
|
+
if (parentReference !== undefined) {
|
1069
|
+
// If the parent has a reference, we can refer to this object indirectly
|
1070
|
+
// through the property name inside that parent.
|
1071
|
+
var reference = parentReference + ':' + key; // Store this object so that the server can refer to it later in responses.
|
1072
|
+
|
1073
|
+
writeTemporaryReference(temporaryReferences, reference, value);
|
1074
|
+
return serializeTemporaryReferenceMarker();
|
1075
|
+
}
|
895
1076
|
}
|
896
1077
|
|
897
|
-
|
1078
|
+
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) ));
|
898
1079
|
}
|
899
1080
|
|
900
1081
|
case REACT_LAZY_TYPE:
|
@@ -916,7 +1097,7 @@ function processReply(root, formFieldPrefix, temporaryReferences, resolve, rejec
|
|
916
1097
|
// because it ensures a more deterministic encoding.
|
917
1098
|
|
918
1099
|
var lazyId = nextPartId++;
|
919
|
-
var partJSON =
|
1100
|
+
var partJSON = serializeModel(resolvedModel, lazyId); // $FlowFixMe[incompatible-type] We know it's not null because we assigned it above.
|
920
1101
|
|
921
1102
|
var data = formData; // eslint-disable-next-line react-internal/safe-string-coercion
|
922
1103
|
|
@@ -935,12 +1116,12 @@ function processReply(root, formFieldPrefix, temporaryReferences, resolve, rejec
|
|
935
1116
|
// While the first promise resolved, its value isn't necessarily what we'll
|
936
1117
|
// resolve into because we might suspend again.
|
937
1118
|
try {
|
938
|
-
var
|
1119
|
+
var _partJSON2 = serializeModel(value, _lazyId); // $FlowFixMe[incompatible-type] We know it's not null because we assigned it above.
|
939
1120
|
|
940
1121
|
|
941
1122
|
var _data = formData; // eslint-disable-next-line react-internal/safe-string-coercion
|
942
1123
|
|
943
|
-
_data.append(formFieldPrefix + _lazyId,
|
1124
|
+
_data.append(formFieldPrefix + _lazyId, _partJSON2);
|
944
1125
|
|
945
1126
|
pendingParts--;
|
946
1127
|
|
@@ -981,12 +1162,12 @@ function processReply(root, formFieldPrefix, temporaryReferences, resolve, rejec
|
|
981
1162
|
|
982
1163
|
_thenable.then(function (partValue) {
|
983
1164
|
try {
|
984
|
-
var
|
1165
|
+
var _partJSON3 = serializeModel(partValue, promiseId); // $FlowFixMe[incompatible-type] We know it's not null because we assigned it above.
|
985
1166
|
|
986
1167
|
|
987
1168
|
var _data2 = formData; // eslint-disable-next-line react-internal/safe-string-coercion
|
988
1169
|
|
989
|
-
_data2.append(formFieldPrefix + promiseId,
|
1170
|
+
_data2.append(formFieldPrefix + promiseId, _partJSON3);
|
990
1171
|
|
991
1172
|
pendingParts--;
|
992
1173
|
|
@@ -996,15 +1177,43 @@ function processReply(root, formFieldPrefix, temporaryReferences, resolve, rejec
|
|
996
1177
|
} catch (reason) {
|
997
1178
|
reject(reason);
|
998
1179
|
}
|
999
|
-
},
|
1000
|
-
|
1001
|
-
|
1002
|
-
reject(reason);
|
1003
|
-
});
|
1180
|
+
}, // In the future we could consider serializing this as an error
|
1181
|
+
// that throws on the server instead.
|
1182
|
+
reject);
|
1004
1183
|
|
1005
1184
|
return serializePromiseID(promiseId);
|
1006
1185
|
}
|
1007
1186
|
|
1187
|
+
var existingReference = writtenObjects.get(value);
|
1188
|
+
|
1189
|
+
if (existingReference !== undefined) {
|
1190
|
+
if (modelRoot === value) {
|
1191
|
+
// This is the ID we're currently emitting so we need to write it
|
1192
|
+
// once but if we discover it again, we refer to it by id.
|
1193
|
+
modelRoot = null;
|
1194
|
+
} else {
|
1195
|
+
// We've already emitted this as an outlined object, so we can
|
1196
|
+
// just refer to that by its existing ID.
|
1197
|
+
return existingReference;
|
1198
|
+
}
|
1199
|
+
} else if (key.indexOf(':') === -1) {
|
1200
|
+
// TODO: If the property name contains a colon, we don't dedupe. Escape instead.
|
1201
|
+
var _parentReference = writtenObjects.get(parent);
|
1202
|
+
|
1203
|
+
if (_parentReference !== undefined) {
|
1204
|
+
// If the parent has a reference, we can refer to this object indirectly
|
1205
|
+
// through the property name inside that parent.
|
1206
|
+
var _reference = _parentReference + ':' + key;
|
1207
|
+
|
1208
|
+
writtenObjects.set(value, _reference);
|
1209
|
+
|
1210
|
+
if (temporaryReferences !== undefined) {
|
1211
|
+
// Store this object so that the server can refer to it later in responses.
|
1212
|
+
writeTemporaryReference(temporaryReferences, _reference, value);
|
1213
|
+
}
|
1214
|
+
}
|
1215
|
+
}
|
1216
|
+
|
1008
1217
|
if (isArray(value)) {
|
1009
1218
|
// $FlowFixMe[incompatible-return]
|
1010
1219
|
return value;
|
@@ -1031,29 +1240,117 @@ function processReply(root, formFieldPrefix, temporaryReferences, resolve, rejec
|
|
1031
1240
|
}
|
1032
1241
|
|
1033
1242
|
if (value instanceof Map) {
|
1034
|
-
var
|
1243
|
+
var mapId = nextPartId++;
|
1244
|
+
|
1245
|
+
var _partJSON4 = serializeModel(Array.from(value), mapId);
|
1035
1246
|
|
1036
1247
|
if (formData === null) {
|
1037
1248
|
formData = new FormData();
|
1038
1249
|
}
|
1039
1250
|
|
1040
|
-
|
1041
|
-
formData.append(formFieldPrefix + mapId, _partJSON3);
|
1251
|
+
formData.append(formFieldPrefix + mapId, _partJSON4);
|
1042
1252
|
return serializeMapID(mapId);
|
1043
1253
|
}
|
1044
1254
|
|
1045
1255
|
if (value instanceof Set) {
|
1046
|
-
var
|
1256
|
+
var setId = nextPartId++;
|
1257
|
+
|
1258
|
+
var _partJSON5 = serializeModel(Array.from(value), setId);
|
1047
1259
|
|
1048
1260
|
if (formData === null) {
|
1049
1261
|
formData = new FormData();
|
1050
1262
|
}
|
1051
1263
|
|
1052
|
-
|
1053
|
-
formData.append(formFieldPrefix + setId, _partJSON4);
|
1264
|
+
formData.append(formFieldPrefix + setId, _partJSON5);
|
1054
1265
|
return serializeSetID(setId);
|
1055
1266
|
}
|
1056
1267
|
|
1268
|
+
{
|
1269
|
+
if (value instanceof ArrayBuffer) {
|
1270
|
+
var blob = new Blob([value]);
|
1271
|
+
var blobId = nextPartId++;
|
1272
|
+
|
1273
|
+
if (formData === null) {
|
1274
|
+
formData = new FormData();
|
1275
|
+
}
|
1276
|
+
|
1277
|
+
formData.append(formFieldPrefix + blobId, blob);
|
1278
|
+
return '$' + 'A' + blobId.toString(16);
|
1279
|
+
}
|
1280
|
+
|
1281
|
+
if (value instanceof Int8Array) {
|
1282
|
+
// char
|
1283
|
+
return serializeTypedArray('O', value);
|
1284
|
+
}
|
1285
|
+
|
1286
|
+
if (value instanceof Uint8Array) {
|
1287
|
+
// unsigned char
|
1288
|
+
return serializeTypedArray('o', value);
|
1289
|
+
}
|
1290
|
+
|
1291
|
+
if (value instanceof Uint8ClampedArray) {
|
1292
|
+
// unsigned clamped char
|
1293
|
+
return serializeTypedArray('U', value);
|
1294
|
+
}
|
1295
|
+
|
1296
|
+
if (value instanceof Int16Array) {
|
1297
|
+
// sort
|
1298
|
+
return serializeTypedArray('S', value);
|
1299
|
+
}
|
1300
|
+
|
1301
|
+
if (value instanceof Uint16Array) {
|
1302
|
+
// unsigned short
|
1303
|
+
return serializeTypedArray('s', value);
|
1304
|
+
}
|
1305
|
+
|
1306
|
+
if (value instanceof Int32Array) {
|
1307
|
+
// long
|
1308
|
+
return serializeTypedArray('L', value);
|
1309
|
+
}
|
1310
|
+
|
1311
|
+
if (value instanceof Uint32Array) {
|
1312
|
+
// unsigned long
|
1313
|
+
return serializeTypedArray('l', value);
|
1314
|
+
}
|
1315
|
+
|
1316
|
+
if (value instanceof Float32Array) {
|
1317
|
+
// float
|
1318
|
+
return serializeTypedArray('G', value);
|
1319
|
+
}
|
1320
|
+
|
1321
|
+
if (value instanceof Float64Array) {
|
1322
|
+
// double
|
1323
|
+
return serializeTypedArray('g', value);
|
1324
|
+
}
|
1325
|
+
|
1326
|
+
if (value instanceof BigInt64Array) {
|
1327
|
+
// number
|
1328
|
+
return serializeTypedArray('M', value);
|
1329
|
+
}
|
1330
|
+
|
1331
|
+
if (value instanceof BigUint64Array) {
|
1332
|
+
// unsigned number
|
1333
|
+
// We use "m" instead of "n" since JSON can start with "null"
|
1334
|
+
return serializeTypedArray('m', value);
|
1335
|
+
}
|
1336
|
+
|
1337
|
+
if (value instanceof DataView) {
|
1338
|
+
return serializeTypedArray('V', value);
|
1339
|
+
} // TODO: Blob is not available in old Node/browsers. Remove the typeof check later.
|
1340
|
+
|
1341
|
+
|
1342
|
+
if (typeof Blob === 'function' && value instanceof Blob) {
|
1343
|
+
if (formData === null) {
|
1344
|
+
formData = new FormData();
|
1345
|
+
}
|
1346
|
+
|
1347
|
+
var _blobId = nextPartId++;
|
1348
|
+
|
1349
|
+
formData.append(formFieldPrefix + _blobId, value);
|
1350
|
+
return serializeBlobID(_blobId);
|
1351
|
+
}
|
1352
|
+
}
|
1353
|
+
|
1057
1354
|
var iteratorFn = getIteratorFn(value);
|
1058
1355
|
|
1059
1356
|
if (iteratorFn) {
|
@@ -1061,18 +1358,33 @@ function processReply(root, formFieldPrefix, temporaryReferences, resolve, rejec
|
|
1061
1358
|
|
1062
1359
|
if (iterator === value) {
|
1063
1360
|
// Iterator, not Iterable
|
1064
|
-
var
|
1361
|
+
var iteratorId = nextPartId++;
|
1362
|
+
|
1363
|
+
var _partJSON6 = serializeModel(Array.from(iterator), iteratorId);
|
1065
1364
|
|
1066
1365
|
if (formData === null) {
|
1067
1366
|
formData = new FormData();
|
1068
1367
|
}
|
1069
1368
|
|
1070
|
-
|
1071
|
-
formData.append(formFieldPrefix + iteratorId, _partJSON5);
|
1369
|
+
formData.append(formFieldPrefix + iteratorId, _partJSON6);
|
1072
1370
|
return serializeIteratorID(iteratorId);
|
1073
1371
|
}
|
1074
1372
|
|
1075
1373
|
return Array.from(iterator);
|
1374
|
+
}
|
1375
|
+
|
1376
|
+
{
|
1377
|
+
// TODO: ReadableStream is not available in old Node. Remove the typeof check later.
|
1378
|
+
if (typeof ReadableStream === 'function' && value instanceof ReadableStream) {
|
1379
|
+
return serializeReadableStream(value);
|
1380
|
+
}
|
1381
|
+
|
1382
|
+
var getAsyncIterator = value[ASYNC_ITERATOR];
|
1383
|
+
|
1384
|
+
if (typeof getAsyncIterator === 'function') {
|
1385
|
+
// We treat AsyncIterables as a Fragment and as such we might need to key them.
|
1386
|
+
return serializeAsyncIterable(value, getAsyncIterator.call(value));
|
1387
|
+
}
|
1076
1388
|
} // Verify that this is a simple plain object.
|
1077
1389
|
|
1078
1390
|
|
@@ -1081,10 +1393,11 @@ function processReply(root, formFieldPrefix, temporaryReferences, resolve, rejec
|
|
1081
1393
|
if (proto !== ObjectPrototype && (proto === null || getPrototypeOf(proto) !== null)) {
|
1082
1394
|
if (temporaryReferences === undefined) {
|
1083
1395
|
throw new Error('Only plain objects, and a few built-ins, can be passed to Server Actions. ' + 'Classes or null prototypes are not supported.');
|
1084
|
-
} // We
|
1396
|
+
} // We will have written this object to the temporary reference set above
|
1397
|
+
// so we can replace it with a marker to refer to this slot later.
|
1085
1398
|
|
1086
1399
|
|
1087
|
-
return
|
1400
|
+
return serializeTemporaryReferenceMarker();
|
1088
1401
|
}
|
1089
1402
|
|
1090
1403
|
{
|
@@ -1153,19 +1466,41 @@ function processReply(root, formFieldPrefix, temporaryReferences, resolve, rejec
|
|
1153
1466
|
return serializeServerReferenceID(_refId);
|
1154
1467
|
}
|
1155
1468
|
|
1156
|
-
if (temporaryReferences
|
1157
|
-
|
1469
|
+
if (temporaryReferences !== undefined && key.indexOf(':') === -1) {
|
1470
|
+
// TODO: If the property name contains a colon, we don't dedupe. Escape instead.
|
1471
|
+
var _parentReference2 = writtenObjects.get(parent);
|
1472
|
+
|
1473
|
+
if (_parentReference2 !== undefined) {
|
1474
|
+
// If the parent has a reference, we can refer to this object indirectly
|
1475
|
+
// through the property name inside that parent.
|
1476
|
+
var _reference2 = _parentReference2 + ':' + key; // Store this object so that the server can refer to it later in responses.
|
1477
|
+
|
1478
|
+
|
1479
|
+
writeTemporaryReference(temporaryReferences, _reference2, value);
|
1480
|
+
return serializeTemporaryReferenceMarker();
|
1481
|
+
}
|
1158
1482
|
}
|
1159
1483
|
|
1160
|
-
|
1484
|
+
throw new Error('Client Functions cannot be passed directly to Server Functions. ' + 'Only Functions passed from the Server can be passed back again.');
|
1161
1485
|
}
|
1162
1486
|
|
1163
1487
|
if (typeof value === 'symbol') {
|
1164
|
-
if (temporaryReferences
|
1165
|
-
|
1488
|
+
if (temporaryReferences !== undefined && key.indexOf(':') === -1) {
|
1489
|
+
// TODO: If the property name contains a colon, we don't dedupe. Escape instead.
|
1490
|
+
var _parentReference3 = writtenObjects.get(parent);
|
1491
|
+
|
1492
|
+
if (_parentReference3 !== undefined) {
|
1493
|
+
// If the parent has a reference, we can refer to this object indirectly
|
1494
|
+
// through the property name inside that parent.
|
1495
|
+
var _reference3 = _parentReference3 + ':' + key; // Store this object so that the server can refer to it later in responses.
|
1496
|
+
|
1497
|
+
|
1498
|
+
writeTemporaryReference(temporaryReferences, _reference3, value);
|
1499
|
+
return serializeTemporaryReferenceMarker();
|
1500
|
+
}
|
1166
1501
|
}
|
1167
1502
|
|
1168
|
-
|
1503
|
+
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) ));
|
1169
1504
|
}
|
1170
1505
|
|
1171
1506
|
if (typeof value === 'bigint') {
|
@@ -1173,10 +1508,25 @@ function processReply(root, formFieldPrefix, temporaryReferences, resolve, rejec
|
|
1173
1508
|
}
|
1174
1509
|
|
1175
1510
|
throw new Error("Type " + typeof value + " is not supported as an argument to a Server Function.");
|
1176
|
-
}
|
1511
|
+
}
|
1512
|
+
|
1513
|
+
function serializeModel(model, id) {
|
1514
|
+
if (typeof model === 'object' && model !== null) {
|
1515
|
+
var reference = serializeByValueID(id);
|
1516
|
+
writtenObjects.set(model, reference);
|
1517
|
+
|
1518
|
+
if (temporaryReferences !== undefined) {
|
1519
|
+
// Store this object so that the server can refer to it later in responses.
|
1520
|
+
writeTemporaryReference(temporaryReferences, reference, model);
|
1521
|
+
}
|
1522
|
+
}
|
1523
|
+
|
1524
|
+
modelRoot = model; // $FlowFixMe[incompatible-return] it's not going to be undefined because we'll encode it.
|
1177
1525
|
|
1526
|
+
return JSON.stringify(model, resolveToJSON);
|
1527
|
+
}
|
1178
1528
|
|
1179
|
-
var json =
|
1529
|
+
var json = serializeModel(root, 0);
|
1180
1530
|
|
1181
1531
|
if (formData === null) {
|
1182
1532
|
// If it's a simple data structure, we just use plain JSON.
|
@@ -1602,6 +1952,14 @@ function wakeChunkIfInitialized(chunk, resolveListeners, rejectListeners) {
|
|
1602
1952
|
|
1603
1953
|
function triggerErrorOnChunk(chunk, error) {
|
1604
1954
|
if (chunk.status !== PENDING && chunk.status !== BLOCKED) {
|
1955
|
+
{
|
1956
|
+
// If we get more data to an already resolved ID, we assume that it's
|
1957
|
+
// a stream chunk since any other row shouldn't have more than one entry.
|
1958
|
+
var streamChunk = chunk;
|
1959
|
+
var controller = streamChunk.reason; // $FlowFixMe[incompatible-call]: The error method should accept mixed.
|
1960
|
+
|
1961
|
+
controller.error(error);
|
1962
|
+
}
|
1605
1963
|
|
1606
1964
|
return;
|
1607
1965
|
}
|
@@ -1631,8 +1989,48 @@ function createInitializedTextChunk(response, value) {
|
|
1631
1989
|
return new Chunk(INITIALIZED, value, null, response);
|
1632
1990
|
}
|
1633
1991
|
|
1992
|
+
function createInitializedBufferChunk(response, value) {
|
1993
|
+
// $FlowFixMe[invalid-constructor] Flow doesn't support functions as constructors
|
1994
|
+
return new Chunk(INITIALIZED, value, null, response);
|
1995
|
+
}
|
1996
|
+
|
1997
|
+
function createInitializedIteratorResultChunk(response, value, done) {
|
1998
|
+
// $FlowFixMe[invalid-constructor] Flow doesn't support functions as constructors
|
1999
|
+
return new Chunk(INITIALIZED, {
|
2000
|
+
done: done,
|
2001
|
+
value: value
|
2002
|
+
}, null, response);
|
2003
|
+
}
|
2004
|
+
|
2005
|
+
function createInitializedStreamChunk(response, value, controller) {
|
2006
|
+
// We use the reason field to stash the controller since we already have that
|
2007
|
+
// field. It's a bit of a hack but efficient.
|
2008
|
+
// $FlowFixMe[invalid-constructor] Flow doesn't support functions as constructors
|
2009
|
+
return new Chunk(INITIALIZED, value, controller, response);
|
2010
|
+
}
|
2011
|
+
|
2012
|
+
function createResolvedIteratorResultChunk(response, value, done) {
|
2013
|
+
// To reuse code as much code as possible we add the wrapper element as part of the JSON.
|
2014
|
+
var iteratorResultJSON = (done ? '{"done":true,"value":' : '{"done":false,"value":') + value + '}'; // $FlowFixMe[invalid-constructor] Flow doesn't support functions as constructors
|
2015
|
+
|
2016
|
+
return new Chunk(RESOLVED_MODEL, iteratorResultJSON, null, response);
|
2017
|
+
}
|
2018
|
+
|
2019
|
+
function resolveIteratorResultChunk(chunk, value, done) {
|
2020
|
+
// To reuse code as much code as possible we add the wrapper element as part of the JSON.
|
2021
|
+
var iteratorResultJSON = (done ? '{"done":true,"value":' : '{"done":false,"value":') + value + '}';
|
2022
|
+
resolveModelChunk(chunk, iteratorResultJSON);
|
2023
|
+
}
|
2024
|
+
|
1634
2025
|
function resolveModelChunk(chunk, value) {
|
1635
2026
|
if (chunk.status !== PENDING) {
|
2027
|
+
{
|
2028
|
+
// If we get more data to an already resolved ID, we assume that it's
|
2029
|
+
// a stream chunk since any other row shouldn't have more than one entry.
|
2030
|
+
var streamChunk = chunk;
|
2031
|
+
var controller = streamChunk.reason;
|
2032
|
+
controller.enqueueModel(value);
|
2033
|
+
}
|
1636
2034
|
|
1637
2035
|
return;
|
1638
2036
|
}
|
@@ -1751,7 +2149,8 @@ function nullRefGetter() {
|
|
1751
2149
|
}
|
1752
2150
|
}
|
1753
2151
|
|
1754
|
-
function createElement(type, key, props, owner
|
2152
|
+
function createElement(type, key, props, owner, // DEV-only
|
2153
|
+
stack) // DEV-only
|
1755
2154
|
{
|
1756
2155
|
var element;
|
1757
2156
|
|
@@ -1789,6 +2188,10 @@ function createElement(type, key, props, owner) // DEV-only
|
|
1789
2188
|
writable: true,
|
1790
2189
|
value: null
|
1791
2190
|
});
|
2191
|
+
// _debugInfo later. We could move it into _store which remains mutable.
|
2192
|
+
|
2193
|
+
|
2194
|
+
Object.freeze(element.props);
|
1792
2195
|
}
|
1793
2196
|
|
1794
2197
|
return element;
|
@@ -1822,7 +2225,7 @@ function getChunk(response, id) {
|
|
1822
2225
|
return chunk;
|
1823
2226
|
}
|
1824
2227
|
|
1825
|
-
function createModelResolver(chunk, parentObject, key, cyclic, response, map) {
|
2228
|
+
function createModelResolver(chunk, parentObject, key, cyclic, response, map, path) {
|
1826
2229
|
var blocked;
|
1827
2230
|
|
1828
2231
|
if (initializingChunkBlockedModel) {
|
@@ -1839,6 +2242,10 @@ function createModelResolver(chunk, parentObject, key, cyclic, response, map) {
|
|
1839
2242
|
}
|
1840
2243
|
|
1841
2244
|
return function (value) {
|
2245
|
+
for (var i = 1; i < path.length; i++) {
|
2246
|
+
value = value[path[i]];
|
2247
|
+
}
|
2248
|
+
|
1842
2249
|
parentObject[key] = map(response, value); // If this is the root object for a model reference, where `blocked.value`
|
1843
2250
|
// is a stale `null`, the resolved value can be used directly.
|
1844
2251
|
|
@@ -1899,7 +2306,9 @@ function createServerReferenceProxy(response, metaData) {
|
|
1899
2306
|
return proxy;
|
1900
2307
|
}
|
1901
2308
|
|
1902
|
-
function getOutlinedModel(response,
|
2309
|
+
function getOutlinedModel(response, reference, parentObject, key, map) {
|
2310
|
+
var path = reference.split(':');
|
2311
|
+
var id = parseInt(path[0], 16);
|
1903
2312
|
var chunk = getChunk(response, id);
|
1904
2313
|
|
1905
2314
|
switch (chunk.status) {
|
@@ -1915,7 +2324,13 @@ function getOutlinedModel(response, id, parentObject, key, map) {
|
|
1915
2324
|
|
1916
2325
|
switch (chunk.status) {
|
1917
2326
|
case INITIALIZED:
|
1918
|
-
var
|
2327
|
+
var value = chunk.value;
|
2328
|
+
|
2329
|
+
for (var i = 1; i < path.length; i++) {
|
2330
|
+
value = value[path[i]];
|
2331
|
+
}
|
2332
|
+
|
2333
|
+
var chunkValue = map(response, value);
|
1919
2334
|
|
1920
2335
|
if (chunk._debugInfo) {
|
1921
2336
|
// If we have a direct reference to an object that was rendered by a synchronous
|
@@ -1943,7 +2358,7 @@ function getOutlinedModel(response, id, parentObject, key, map) {
|
|
1943
2358
|
case BLOCKED:
|
1944
2359
|
case CYCLIC:
|
1945
2360
|
var parentChunk = initializingChunk;
|
1946
|
-
chunk.then(createModelResolver(parentChunk, parentObject, key, chunk.status === CYCLIC, response, map), createModelReject(parentChunk));
|
2361
|
+
chunk.then(createModelResolver(parentChunk, parentObject, key, chunk.status === CYCLIC, response, map, path), createModelReject(parentChunk));
|
1947
2362
|
return null;
|
1948
2363
|
|
1949
2364
|
default:
|
@@ -1959,6 +2374,12 @@ function createSet(response, model) {
|
|
1959
2374
|
return new Set(model);
|
1960
2375
|
}
|
1961
2376
|
|
2377
|
+
function createBlob(response, model) {
|
2378
|
+
return new Blob(model.slice(1), {
|
2379
|
+
type: model[0]
|
2380
|
+
});
|
2381
|
+
}
|
2382
|
+
|
1962
2383
|
function createFormData(response, model) {
|
1963
2384
|
var formData = new FormData();
|
1964
2385
|
|
@@ -2026,61 +2447,63 @@ function parseModelString(response, parentObject, key, value) {
|
|
2026
2447
|
case 'F':
|
2027
2448
|
{
|
2028
2449
|
// Server Reference
|
2029
|
-
var
|
2030
|
-
|
2031
|
-
return getOutlinedModel(response, _id2, parentObject, key, createServerReferenceProxy);
|
2450
|
+
var ref = value.slice(2);
|
2451
|
+
return getOutlinedModel(response, ref, parentObject, key, createServerReferenceProxy);
|
2032
2452
|
}
|
2033
2453
|
|
2034
2454
|
case 'T':
|
2035
2455
|
{
|
2036
2456
|
// Temporary Reference
|
2037
|
-
var
|
2038
|
-
|
2457
|
+
var reference = '$' + value.slice(2);
|
2039
2458
|
var temporaryReferences = response._tempRefs;
|
2040
2459
|
|
2041
2460
|
if (temporaryReferences == null) {
|
2042
2461
|
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.');
|
2043
2462
|
}
|
2044
2463
|
|
2045
|
-
return readTemporaryReference(temporaryReferences,
|
2464
|
+
return readTemporaryReference(temporaryReferences, reference);
|
2046
2465
|
}
|
2047
2466
|
|
2048
2467
|
case 'Q':
|
2049
2468
|
{
|
2050
2469
|
// Map
|
2051
|
-
var
|
2470
|
+
var _ref = value.slice(2);
|
2052
2471
|
|
2053
|
-
return getOutlinedModel(response,
|
2472
|
+
return getOutlinedModel(response, _ref, parentObject, key, createMap);
|
2054
2473
|
}
|
2055
2474
|
|
2056
2475
|
case 'W':
|
2057
2476
|
{
|
2058
2477
|
// Set
|
2059
|
-
var
|
2478
|
+
var _ref2 = value.slice(2);
|
2060
2479
|
|
2061
|
-
return getOutlinedModel(response,
|
2480
|
+
return getOutlinedModel(response, _ref2, parentObject, key, createSet);
|
2062
2481
|
}
|
2063
2482
|
|
2064
2483
|
case 'B':
|
2065
2484
|
{
|
2485
|
+
// Blob
|
2486
|
+
{
|
2487
|
+
var _ref3 = value.slice(2);
|
2066
2488
|
|
2067
|
-
|
2489
|
+
return getOutlinedModel(response, _ref3, parentObject, key, createBlob);
|
2490
|
+
}
|
2068
2491
|
}
|
2069
2492
|
|
2070
2493
|
case 'K':
|
2071
2494
|
{
|
2072
2495
|
// FormData
|
2073
|
-
var
|
2496
|
+
var _ref4 = value.slice(2);
|
2074
2497
|
|
2075
|
-
return getOutlinedModel(response,
|
2498
|
+
return getOutlinedModel(response, _ref4, parentObject, key, createFormData);
|
2076
2499
|
}
|
2077
2500
|
|
2078
2501
|
case 'i':
|
2079
2502
|
{
|
2080
2503
|
// Iterator
|
2081
|
-
var
|
2504
|
+
var _ref5 = value.slice(2);
|
2082
2505
|
|
2083
|
-
return getOutlinedModel(response,
|
2506
|
+
return getOutlinedModel(response, _ref5, parentObject, key, extractIterator);
|
2084
2507
|
}
|
2085
2508
|
|
2086
2509
|
case 'I':
|
@@ -2144,9 +2567,9 @@ function parseModelString(response, parentObject, key, value) {
|
|
2144
2567
|
default:
|
2145
2568
|
{
|
2146
2569
|
// We assume that anything else is a reference ID.
|
2147
|
-
var
|
2570
|
+
var _ref6 = value.slice(1);
|
2148
2571
|
|
2149
|
-
return getOutlinedModel(response,
|
2572
|
+
return getOutlinedModel(response, _ref6, parentObject, key, createModel);
|
2150
2573
|
}
|
2151
2574
|
}
|
2152
2575
|
}
|
@@ -2207,9 +2630,41 @@ function resolveModel(response, id, model) {
|
|
2207
2630
|
function resolveText(response, id, text) {
|
2208
2631
|
var chunks = response._chunks;
|
2209
2632
|
|
2633
|
+
{
|
2634
|
+
var chunk = chunks.get(id);
|
2635
|
+
|
2636
|
+
if (chunk && chunk.status !== PENDING) {
|
2637
|
+
// If we get more data to an already resolved ID, we assume that it's
|
2638
|
+
// a stream chunk since any other row shouldn't have more than one entry.
|
2639
|
+
var streamChunk = chunk;
|
2640
|
+
var controller = streamChunk.reason;
|
2641
|
+
controller.enqueueValue(text);
|
2642
|
+
return;
|
2643
|
+
}
|
2644
|
+
}
|
2645
|
+
|
2210
2646
|
chunks.set(id, createInitializedTextChunk(response, text));
|
2211
2647
|
}
|
2212
2648
|
|
2649
|
+
function resolveBuffer(response, id, buffer) {
|
2650
|
+
var chunks = response._chunks;
|
2651
|
+
|
2652
|
+
{
|
2653
|
+
var chunk = chunks.get(id);
|
2654
|
+
|
2655
|
+
if (chunk && chunk.status !== PENDING) {
|
2656
|
+
// If we get more data to an already resolved ID, we assume that it's
|
2657
|
+
// a stream chunk since any other row shouldn't have more than one entry.
|
2658
|
+
var streamChunk = chunk;
|
2659
|
+
var controller = streamChunk.reason;
|
2660
|
+
controller.enqueueValue(buffer);
|
2661
|
+
return;
|
2662
|
+
}
|
2663
|
+
}
|
2664
|
+
|
2665
|
+
chunks.set(id, createInitializedBufferChunk(response, buffer));
|
2666
|
+
}
|
2667
|
+
|
2213
2668
|
function resolveModule(response, id, model) {
|
2214
2669
|
var chunks = response._chunks;
|
2215
2670
|
var chunk = chunks.get(id);
|
@@ -2252,6 +2707,245 @@ function resolveModule(response, id, model) {
|
|
2252
2707
|
}
|
2253
2708
|
}
|
2254
2709
|
|
2710
|
+
function resolveStream(response, id, stream, controller) {
|
2711
|
+
var chunks = response._chunks;
|
2712
|
+
var chunk = chunks.get(id);
|
2713
|
+
|
2714
|
+
if (!chunk) {
|
2715
|
+
chunks.set(id, createInitializedStreamChunk(response, stream, controller));
|
2716
|
+
return;
|
2717
|
+
}
|
2718
|
+
|
2719
|
+
if (chunk.status !== PENDING) {
|
2720
|
+
// We already resolved. We didn't expect to see this.
|
2721
|
+
return;
|
2722
|
+
}
|
2723
|
+
|
2724
|
+
var resolveListeners = chunk.value;
|
2725
|
+
var resolvedChunk = chunk;
|
2726
|
+
resolvedChunk.status = INITIALIZED;
|
2727
|
+
resolvedChunk.value = stream;
|
2728
|
+
resolvedChunk.reason = controller;
|
2729
|
+
|
2730
|
+
if (resolveListeners !== null) {
|
2731
|
+
wakeChunk(resolveListeners, chunk.value);
|
2732
|
+
}
|
2733
|
+
}
|
2734
|
+
|
2735
|
+
function startReadableStream(response, id, type) {
|
2736
|
+
var controller = null;
|
2737
|
+
var stream = new ReadableStream({
|
2738
|
+
type: type,
|
2739
|
+
start: function (c) {
|
2740
|
+
controller = c;
|
2741
|
+
}
|
2742
|
+
});
|
2743
|
+
var previousBlockedChunk = null;
|
2744
|
+
var flightController = {
|
2745
|
+
enqueueValue: function (value) {
|
2746
|
+
if (previousBlockedChunk === null) {
|
2747
|
+
controller.enqueue(value);
|
2748
|
+
} else {
|
2749
|
+
// We're still waiting on a previous chunk so we can't enqueue quite yet.
|
2750
|
+
previousBlockedChunk.then(function () {
|
2751
|
+
controller.enqueue(value);
|
2752
|
+
});
|
2753
|
+
}
|
2754
|
+
},
|
2755
|
+
enqueueModel: function (json) {
|
2756
|
+
if (previousBlockedChunk === null) {
|
2757
|
+
// If we're not blocked on any other chunks, we can try to eagerly initialize
|
2758
|
+
// this as a fast-path to avoid awaiting them.
|
2759
|
+
var chunk = createResolvedModelChunk(response, json);
|
2760
|
+
initializeModelChunk(chunk);
|
2761
|
+
var initializedChunk = chunk;
|
2762
|
+
|
2763
|
+
if (initializedChunk.status === INITIALIZED) {
|
2764
|
+
controller.enqueue(initializedChunk.value);
|
2765
|
+
} else {
|
2766
|
+
chunk.then(function (v) {
|
2767
|
+
return controller.enqueue(v);
|
2768
|
+
}, function (e) {
|
2769
|
+
return controller.error(e);
|
2770
|
+
});
|
2771
|
+
previousBlockedChunk = chunk;
|
2772
|
+
}
|
2773
|
+
} else {
|
2774
|
+
// We're still waiting on a previous chunk so we can't enqueue quite yet.
|
2775
|
+
var blockedChunk = previousBlockedChunk;
|
2776
|
+
|
2777
|
+
var _chunk2 = createPendingChunk(response);
|
2778
|
+
|
2779
|
+
_chunk2.then(function (v) {
|
2780
|
+
return controller.enqueue(v);
|
2781
|
+
}, function (e) {
|
2782
|
+
return controller.error(e);
|
2783
|
+
});
|
2784
|
+
|
2785
|
+
previousBlockedChunk = _chunk2;
|
2786
|
+
blockedChunk.then(function () {
|
2787
|
+
if (previousBlockedChunk === _chunk2) {
|
2788
|
+
// We were still the last chunk so we can now clear the queue and return
|
2789
|
+
// to synchronous emitting.
|
2790
|
+
previousBlockedChunk = null;
|
2791
|
+
}
|
2792
|
+
|
2793
|
+
resolveModelChunk(_chunk2, json);
|
2794
|
+
});
|
2795
|
+
}
|
2796
|
+
},
|
2797
|
+
close: function (json) {
|
2798
|
+
if (previousBlockedChunk === null) {
|
2799
|
+
controller.close();
|
2800
|
+
} else {
|
2801
|
+
var blockedChunk = previousBlockedChunk; // We shouldn't get any more enqueues after this so we can set it back to null.
|
2802
|
+
|
2803
|
+
previousBlockedChunk = null;
|
2804
|
+
blockedChunk.then(function () {
|
2805
|
+
return controller.close();
|
2806
|
+
});
|
2807
|
+
}
|
2808
|
+
},
|
2809
|
+
error: function (error) {
|
2810
|
+
if (previousBlockedChunk === null) {
|
2811
|
+
// $FlowFixMe[incompatible-call]
|
2812
|
+
controller.error(error);
|
2813
|
+
} else {
|
2814
|
+
var blockedChunk = previousBlockedChunk; // We shouldn't get any more enqueues after this so we can set it back to null.
|
2815
|
+
|
2816
|
+
previousBlockedChunk = null;
|
2817
|
+
blockedChunk.then(function () {
|
2818
|
+
return controller.error(error);
|
2819
|
+
});
|
2820
|
+
}
|
2821
|
+
}
|
2822
|
+
};
|
2823
|
+
resolveStream(response, id, stream, flightController);
|
2824
|
+
}
|
2825
|
+
|
2826
|
+
function asyncIterator() {
|
2827
|
+
// Self referencing iterator.
|
2828
|
+
return this;
|
2829
|
+
}
|
2830
|
+
|
2831
|
+
function createIterator(next) {
|
2832
|
+
var iterator = {
|
2833
|
+
next: next // TODO: Add return/throw as options for aborting.
|
2834
|
+
|
2835
|
+
}; // TODO: The iterator could inherit the AsyncIterator prototype which is not exposed as
|
2836
|
+
// a global but exists as a prototype of an AsyncGenerator. However, it's not needed
|
2837
|
+
// to satisfy the iterable protocol.
|
2838
|
+
|
2839
|
+
iterator[ASYNC_ITERATOR] = asyncIterator;
|
2840
|
+
return iterator;
|
2841
|
+
}
|
2842
|
+
|
2843
|
+
function startAsyncIterable(response, id, iterator) {
|
2844
|
+
var buffer = [];
|
2845
|
+
var closed = false;
|
2846
|
+
var nextWriteIndex = 0;
|
2847
|
+
var flightController = {
|
2848
|
+
enqueueValue: function (value) {
|
2849
|
+
if (nextWriteIndex === buffer.length) {
|
2850
|
+
buffer[nextWriteIndex] = createInitializedIteratorResultChunk(response, value, false);
|
2851
|
+
} else {
|
2852
|
+
var chunk = buffer[nextWriteIndex];
|
2853
|
+
var resolveListeners = chunk.value;
|
2854
|
+
var rejectListeners = chunk.reason;
|
2855
|
+
var initializedChunk = chunk;
|
2856
|
+
initializedChunk.status = INITIALIZED;
|
2857
|
+
initializedChunk.value = {
|
2858
|
+
done: false,
|
2859
|
+
value: value
|
2860
|
+
};
|
2861
|
+
|
2862
|
+
if (resolveListeners !== null) {
|
2863
|
+
wakeChunkIfInitialized(chunk, resolveListeners, rejectListeners);
|
2864
|
+
}
|
2865
|
+
}
|
2866
|
+
|
2867
|
+
nextWriteIndex++;
|
2868
|
+
},
|
2869
|
+
enqueueModel: function (value) {
|
2870
|
+
if (nextWriteIndex === buffer.length) {
|
2871
|
+
buffer[nextWriteIndex] = createResolvedIteratorResultChunk(response, value, false);
|
2872
|
+
} else {
|
2873
|
+
resolveIteratorResultChunk(buffer[nextWriteIndex], value, false);
|
2874
|
+
}
|
2875
|
+
|
2876
|
+
nextWriteIndex++;
|
2877
|
+
},
|
2878
|
+
close: function (value) {
|
2879
|
+
closed = true;
|
2880
|
+
|
2881
|
+
if (nextWriteIndex === buffer.length) {
|
2882
|
+
buffer[nextWriteIndex] = createResolvedIteratorResultChunk(response, value, true);
|
2883
|
+
} else {
|
2884
|
+
resolveIteratorResultChunk(buffer[nextWriteIndex], value, true);
|
2885
|
+
}
|
2886
|
+
|
2887
|
+
nextWriteIndex++;
|
2888
|
+
|
2889
|
+
while (nextWriteIndex < buffer.length) {
|
2890
|
+
// In generators, any extra reads from the iterator have the value undefined.
|
2891
|
+
resolveIteratorResultChunk(buffer[nextWriteIndex++], '"$undefined"', true);
|
2892
|
+
}
|
2893
|
+
},
|
2894
|
+
error: function (error) {
|
2895
|
+
closed = true;
|
2896
|
+
|
2897
|
+
if (nextWriteIndex === buffer.length) {
|
2898
|
+
buffer[nextWriteIndex] = createPendingChunk(response);
|
2899
|
+
}
|
2900
|
+
|
2901
|
+
while (nextWriteIndex < buffer.length) {
|
2902
|
+
triggerErrorOnChunk(buffer[nextWriteIndex++], error);
|
2903
|
+
}
|
2904
|
+
}
|
2905
|
+
};
|
2906
|
+
|
2907
|
+
var iterable = _defineProperty({}, ASYNC_ITERATOR, function () {
|
2908
|
+
var nextReadIndex = 0;
|
2909
|
+
return createIterator(function (arg) {
|
2910
|
+
if (arg !== undefined) {
|
2911
|
+
throw new Error('Values cannot be passed to next() of AsyncIterables passed to Client Components.');
|
2912
|
+
}
|
2913
|
+
|
2914
|
+
if (nextReadIndex === buffer.length) {
|
2915
|
+
if (closed) {
|
2916
|
+
// $FlowFixMe[invalid-constructor] Flow doesn't support functions as constructors
|
2917
|
+
return new Chunk(INITIALIZED, {
|
2918
|
+
done: true,
|
2919
|
+
value: undefined
|
2920
|
+
}, null, response);
|
2921
|
+
}
|
2922
|
+
|
2923
|
+
buffer[nextReadIndex] = createPendingChunk(response);
|
2924
|
+
}
|
2925
|
+
|
2926
|
+
return buffer[nextReadIndex++];
|
2927
|
+
});
|
2928
|
+
}); // TODO: If it's a single shot iterator we can optimize memory by cleaning up the buffer after
|
2929
|
+
// reading through the end, but currently we favor code size over this optimization.
|
2930
|
+
|
2931
|
+
|
2932
|
+
resolveStream(response, id, iterator ? iterable[ASYNC_ITERATOR]() : iterable, flightController);
|
2933
|
+
}
|
2934
|
+
|
2935
|
+
function stopStream(response, id, row) {
|
2936
|
+
var chunks = response._chunks;
|
2937
|
+
var chunk = chunks.get(id);
|
2938
|
+
|
2939
|
+
if (!chunk || chunk.status !== INITIALIZED) {
|
2940
|
+
// We didn't expect not to have an existing stream;
|
2941
|
+
return;
|
2942
|
+
}
|
2943
|
+
|
2944
|
+
var streamChunk = chunk;
|
2945
|
+
var controller = streamChunk.reason;
|
2946
|
+
controller.close(row === '' ? '"$undefined"' : row);
|
2947
|
+
}
|
2948
|
+
|
2255
2949
|
function resolveErrorDev(response, id, digest, message, stack) {
|
2256
2950
|
|
2257
2951
|
|
@@ -2293,7 +2987,127 @@ function resolveConsoleEntry(response, value) {
|
|
2293
2987
|
printToConsole(methodName, args, env);
|
2294
2988
|
}
|
2295
2989
|
|
2990
|
+
function mergeBuffer(buffer, lastChunk) {
|
2991
|
+
var l = buffer.length; // Count the bytes we'll need
|
2992
|
+
|
2993
|
+
var byteLength = lastChunk.length;
|
2994
|
+
|
2995
|
+
for (var i = 0; i < l; i++) {
|
2996
|
+
byteLength += buffer[i].byteLength;
|
2997
|
+
} // Allocate enough contiguous space
|
2998
|
+
|
2999
|
+
|
3000
|
+
var result = new Uint8Array(byteLength);
|
3001
|
+
var offset = 0; // Copy all the buffers into it.
|
3002
|
+
|
3003
|
+
for (var _i = 0; _i < l; _i++) {
|
3004
|
+
var chunk = buffer[_i];
|
3005
|
+
result.set(chunk, offset);
|
3006
|
+
offset += chunk.byteLength;
|
3007
|
+
}
|
3008
|
+
|
3009
|
+
result.set(lastChunk, offset);
|
3010
|
+
return result;
|
3011
|
+
}
|
3012
|
+
|
3013
|
+
function resolveTypedArray(response, id, buffer, lastChunk, constructor, bytesPerElement) {
|
3014
|
+
// If the view fits into one original buffer, we just reuse that buffer instead of
|
3015
|
+
// copying it out to a separate copy. This means that it's not always possible to
|
3016
|
+
// transfer these values to other threads without copying first since they may
|
3017
|
+
// share array buffer. For this to work, it must also have bytes aligned to a
|
3018
|
+
// multiple of a size of the type.
|
3019
|
+
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
|
3020
|
+
// we should convert it instead. In practice big endian isn't really Web compatible so it's
|
3021
|
+
// somewhat safe to assume that browsers aren't going to run it, but maybe there's some SSR
|
3022
|
+
// server that's affected.
|
3023
|
+
|
3024
|
+
var view = new constructor(chunk.buffer, chunk.byteOffset, chunk.byteLength / bytesPerElement);
|
3025
|
+
resolveBuffer(response, id, view);
|
3026
|
+
}
|
3027
|
+
|
2296
3028
|
function processFullRow(response, id, tag, buffer, chunk) {
|
3029
|
+
{
|
3030
|
+
switch (tag) {
|
3031
|
+
case 65
|
3032
|
+
/* "A" */
|
3033
|
+
:
|
3034
|
+
// We must always clone to extract it into a separate buffer instead of just a view.
|
3035
|
+
resolveBuffer(response, id, mergeBuffer(buffer, chunk).buffer);
|
3036
|
+
return;
|
3037
|
+
|
3038
|
+
case 79
|
3039
|
+
/* "O" */
|
3040
|
+
:
|
3041
|
+
resolveTypedArray(response, id, buffer, chunk, Int8Array, 1);
|
3042
|
+
return;
|
3043
|
+
|
3044
|
+
case 111
|
3045
|
+
/* "o" */
|
3046
|
+
:
|
3047
|
+
resolveBuffer(response, id, buffer.length === 0 ? chunk : mergeBuffer(buffer, chunk));
|
3048
|
+
return;
|
3049
|
+
|
3050
|
+
case 85
|
3051
|
+
/* "U" */
|
3052
|
+
:
|
3053
|
+
resolveTypedArray(response, id, buffer, chunk, Uint8ClampedArray, 1);
|
3054
|
+
return;
|
3055
|
+
|
3056
|
+
case 83
|
3057
|
+
/* "S" */
|
3058
|
+
:
|
3059
|
+
resolveTypedArray(response, id, buffer, chunk, Int16Array, 2);
|
3060
|
+
return;
|
3061
|
+
|
3062
|
+
case 115
|
3063
|
+
/* "s" */
|
3064
|
+
:
|
3065
|
+
resolveTypedArray(response, id, buffer, chunk, Uint16Array, 2);
|
3066
|
+
return;
|
3067
|
+
|
3068
|
+
case 76
|
3069
|
+
/* "L" */
|
3070
|
+
:
|
3071
|
+
resolveTypedArray(response, id, buffer, chunk, Int32Array, 4);
|
3072
|
+
return;
|
3073
|
+
|
3074
|
+
case 108
|
3075
|
+
/* "l" */
|
3076
|
+
:
|
3077
|
+
resolveTypedArray(response, id, buffer, chunk, Uint32Array, 4);
|
3078
|
+
return;
|
3079
|
+
|
3080
|
+
case 71
|
3081
|
+
/* "G" */
|
3082
|
+
:
|
3083
|
+
resolveTypedArray(response, id, buffer, chunk, Float32Array, 4);
|
3084
|
+
return;
|
3085
|
+
|
3086
|
+
case 103
|
3087
|
+
/* "g" */
|
3088
|
+
:
|
3089
|
+
resolveTypedArray(response, id, buffer, chunk, Float64Array, 8);
|
3090
|
+
return;
|
3091
|
+
|
3092
|
+
case 77
|
3093
|
+
/* "M" */
|
3094
|
+
:
|
3095
|
+
resolveTypedArray(response, id, buffer, chunk, BigInt64Array, 8);
|
3096
|
+
return;
|
3097
|
+
|
3098
|
+
case 109
|
3099
|
+
/* "m" */
|
3100
|
+
:
|
3101
|
+
resolveTypedArray(response, id, buffer, chunk, BigUint64Array, 8);
|
3102
|
+
return;
|
3103
|
+
|
3104
|
+
case 86
|
3105
|
+
/* "V" */
|
3106
|
+
:
|
3107
|
+
resolveTypedArray(response, id, buffer, chunk, DataView, 1);
|
3108
|
+
return;
|
3109
|
+
}
|
3110
|
+
}
|
2297
3111
|
|
2298
3112
|
var stringDecoder = response._stringDecoder;
|
2299
3113
|
var row = '';
|
@@ -2368,26 +3182,56 @@ function processFullRow(response, id, tag, buffer, chunk) {
|
|
2368
3182
|
case 82
|
2369
3183
|
/* "R" */
|
2370
3184
|
:
|
3185
|
+
{
|
3186
|
+
{
|
3187
|
+
startReadableStream(response, id, undefined);
|
3188
|
+
return;
|
3189
|
+
}
|
3190
|
+
}
|
2371
3191
|
// Fallthrough
|
2372
3192
|
|
2373
3193
|
case 114
|
2374
3194
|
/* "r" */
|
2375
3195
|
:
|
3196
|
+
{
|
3197
|
+
{
|
3198
|
+
startReadableStream(response, id, 'bytes');
|
3199
|
+
return;
|
3200
|
+
}
|
3201
|
+
}
|
2376
3202
|
// Fallthrough
|
2377
3203
|
|
2378
3204
|
case 88
|
2379
3205
|
/* "X" */
|
2380
3206
|
:
|
3207
|
+
{
|
3208
|
+
{
|
3209
|
+
startAsyncIterable(response, id, false);
|
3210
|
+
return;
|
3211
|
+
}
|
3212
|
+
}
|
2381
3213
|
// Fallthrough
|
2382
3214
|
|
2383
3215
|
case 120
|
2384
3216
|
/* "x" */
|
2385
3217
|
:
|
3218
|
+
{
|
3219
|
+
{
|
3220
|
+
startAsyncIterable(response, id, true);
|
3221
|
+
return;
|
3222
|
+
}
|
3223
|
+
}
|
2386
3224
|
// Fallthrough
|
2387
3225
|
|
2388
3226
|
case 67
|
2389
3227
|
/* "C" */
|
2390
3228
|
:
|
3229
|
+
{
|
3230
|
+
{
|
3231
|
+
stopStream(response, id, row);
|
3232
|
+
return;
|
3233
|
+
}
|
3234
|
+
}
|
2391
3235
|
// Fallthrough
|
2392
3236
|
|
2393
3237
|
case 80
|
@@ -2440,7 +3284,31 @@ function processBinaryChunk(response, chunk) {
|
|
2440
3284
|
|
2441
3285
|
if (resolvedRowTag === 84
|
2442
3286
|
/* "T" */
|
2443
|
-
||
|
3287
|
+
|| (resolvedRowTag === 65
|
3288
|
+
/* "A" */
|
3289
|
+
|| resolvedRowTag === 79
|
3290
|
+
/* "O" */
|
3291
|
+
|| resolvedRowTag === 111
|
3292
|
+
/* "o" */
|
3293
|
+
|| resolvedRowTag === 85
|
3294
|
+
/* "U" */
|
3295
|
+
|| resolvedRowTag === 83
|
3296
|
+
/* "S" */
|
3297
|
+
|| resolvedRowTag === 115
|
3298
|
+
/* "s" */
|
3299
|
+
|| resolvedRowTag === 76
|
3300
|
+
/* "L" */
|
3301
|
+
|| resolvedRowTag === 108
|
3302
|
+
/* "l" */
|
3303
|
+
|| resolvedRowTag === 71
|
3304
|
+
/* "G" */
|
3305
|
+
|| resolvedRowTag === 103
|
3306
|
+
/* "g" */
|
3307
|
+
|| resolvedRowTag === 77
|
3308
|
+
/* "M" */
|
3309
|
+
|| resolvedRowTag === 109
|
3310
|
+
/* "m" */
|
3311
|
+
|| resolvedRowTag === 86)
|
2444
3312
|
/* "V" */
|
2445
3313
|
) {
|
2446
3314
|
rowTag = resolvedRowTag;
|