react-server-dom-webpack 19.0.0-beta-04b058868c-20240508 → 19.0.0-beta-9d76c954cf-20240510
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cjs/react-server-dom-webpack-client.browser.development.js +933 -63
- package/cjs/react-server-dom-webpack-client.browser.production.js +715 -217
- package/cjs/react-server-dom-webpack-client.edge.development.js +933 -63
- package/cjs/react-server-dom-webpack-client.edge.production.js +715 -217
- package/cjs/react-server-dom-webpack-client.node.development.js +932 -62
- package/cjs/react-server-dom-webpack-client.node.production.js +700 -207
- package/cjs/react-server-dom-webpack-client.node.unbundled.development.js +932 -62
- package/cjs/react-server-dom-webpack-client.node.unbundled.production.js +700 -207
- package/cjs/react-server-dom-webpack-server.browser.development.js +1279 -199
- package/cjs/react-server-dom-webpack-server.browser.production.js +808 -162
- package/cjs/react-server-dom-webpack-server.edge.development.js +1280 -200
- package/cjs/react-server-dom-webpack-server.edge.production.js +808 -162
- package/cjs/react-server-dom-webpack-server.node.development.js +1235 -204
- package/cjs/react-server-dom-webpack-server.node.production.js +803 -183
- package/cjs/react-server-dom-webpack-server.node.unbundled.development.js +1235 -204
- package/cjs/react-server-dom-webpack-server.node.unbundled.production.js +803 -183
- package/package.json +3 -3
@@ -18,8 +18,20 @@ var util = require('util');
|
|
18
18
|
var ReactDOM = require('react-dom');
|
19
19
|
var React = require('react');
|
20
20
|
|
21
|
-
|
22
|
-
|
21
|
+
function _defineProperty(obj, key, value) {
|
22
|
+
if (key in obj) {
|
23
|
+
Object.defineProperty(obj, key, {
|
24
|
+
value: value,
|
25
|
+
enumerable: true,
|
26
|
+
configurable: true,
|
27
|
+
writable: true
|
28
|
+
});
|
29
|
+
} else {
|
30
|
+
obj[key] = value;
|
31
|
+
}
|
32
|
+
|
33
|
+
return obj;
|
34
|
+
}
|
23
35
|
|
24
36
|
function createStringDecoder() {
|
25
37
|
return new util.TextDecoder();
|
@@ -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,7 +1116,7 @@ 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 _partJSON2 =
|
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
|
@@ -981,7 +1162,7 @@ function processReply(root, formFieldPrefix, temporaryReferences, resolve, rejec
|
|
981
1162
|
|
982
1163
|
_thenable.then(function (partValue) {
|
983
1164
|
try {
|
984
|
-
var _partJSON3 =
|
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
|
@@ -1003,6 +1184,36 @@ function processReply(root, formFieldPrefix, temporaryReferences, resolve, rejec
|
|
1003
1184
|
return serializePromiseID(promiseId);
|
1004
1185
|
}
|
1005
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
|
+
|
1006
1217
|
if (isArray(value)) {
|
1007
1218
|
// $FlowFixMe[incompatible-return]
|
1008
1219
|
return value;
|
@@ -1029,29 +1240,117 @@ function processReply(root, formFieldPrefix, temporaryReferences, resolve, rejec
|
|
1029
1240
|
}
|
1030
1241
|
|
1031
1242
|
if (value instanceof Map) {
|
1032
|
-
var
|
1243
|
+
var mapId = nextPartId++;
|
1244
|
+
|
1245
|
+
var _partJSON4 = serializeModel(Array.from(value), mapId);
|
1033
1246
|
|
1034
1247
|
if (formData === null) {
|
1035
1248
|
formData = new FormData();
|
1036
1249
|
}
|
1037
1250
|
|
1038
|
-
var mapId = nextPartId++;
|
1039
1251
|
formData.append(formFieldPrefix + mapId, _partJSON4);
|
1040
1252
|
return serializeMapID(mapId);
|
1041
1253
|
}
|
1042
1254
|
|
1043
1255
|
if (value instanceof Set) {
|
1044
|
-
var
|
1256
|
+
var setId = nextPartId++;
|
1257
|
+
|
1258
|
+
var _partJSON5 = serializeModel(Array.from(value), setId);
|
1045
1259
|
|
1046
1260
|
if (formData === null) {
|
1047
1261
|
formData = new FormData();
|
1048
1262
|
}
|
1049
1263
|
|
1050
|
-
var setId = nextPartId++;
|
1051
1264
|
formData.append(formFieldPrefix + setId, _partJSON5);
|
1052
1265
|
return serializeSetID(setId);
|
1053
1266
|
}
|
1054
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
|
+
|
1055
1354
|
var iteratorFn = getIteratorFn(value);
|
1056
1355
|
|
1057
1356
|
if (iteratorFn) {
|
@@ -1059,13 +1358,14 @@ function processReply(root, formFieldPrefix, temporaryReferences, resolve, rejec
|
|
1059
1358
|
|
1060
1359
|
if (iterator === value) {
|
1061
1360
|
// Iterator, not Iterable
|
1062
|
-
var
|
1361
|
+
var iteratorId = nextPartId++;
|
1362
|
+
|
1363
|
+
var _partJSON6 = serializeModel(Array.from(iterator), iteratorId);
|
1063
1364
|
|
1064
1365
|
if (formData === null) {
|
1065
1366
|
formData = new FormData();
|
1066
1367
|
}
|
1067
1368
|
|
1068
|
-
var iteratorId = nextPartId++;
|
1069
1369
|
formData.append(formFieldPrefix + iteratorId, _partJSON6);
|
1070
1370
|
return serializeIteratorID(iteratorId);
|
1071
1371
|
}
|
@@ -1073,16 +1373,31 @@ function processReply(root, formFieldPrefix, temporaryReferences, resolve, rejec
|
|
1073
1373
|
return Array.from(iterator);
|
1074
1374
|
}
|
1075
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
|
+
}
|
1388
|
+
} // Verify that this is a simple plain object.
|
1389
|
+
|
1076
1390
|
|
1077
1391
|
var proto = getPrototypeOf(value);
|
1078
1392
|
|
1079
1393
|
if (proto !== ObjectPrototype && (proto === null || getPrototypeOf(proto) !== null)) {
|
1080
1394
|
if (temporaryReferences === undefined) {
|
1081
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.');
|
1082
|
-
} // 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.
|
1083
1398
|
|
1084
1399
|
|
1085
|
-
return
|
1400
|
+
return serializeTemporaryReferenceMarker();
|
1086
1401
|
}
|
1087
1402
|
|
1088
1403
|
{
|
@@ -1151,19 +1466,41 @@ function processReply(root, formFieldPrefix, temporaryReferences, resolve, rejec
|
|
1151
1466
|
return serializeServerReferenceID(_refId);
|
1152
1467
|
}
|
1153
1468
|
|
1154
|
-
if (temporaryReferences
|
1155
|
-
|
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
|
+
}
|
1156
1482
|
}
|
1157
1483
|
|
1158
|
-
|
1484
|
+
throw new Error('Client Functions cannot be passed directly to Server Functions. ' + 'Only Functions passed from the Server can be passed back again.');
|
1159
1485
|
}
|
1160
1486
|
|
1161
1487
|
if (typeof value === 'symbol') {
|
1162
|
-
if (temporaryReferences
|
1163
|
-
|
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
|
+
}
|
1164
1501
|
}
|
1165
1502
|
|
1166
|
-
|
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) ));
|
1167
1504
|
}
|
1168
1505
|
|
1169
1506
|
if (typeof value === 'bigint') {
|
@@ -1171,10 +1508,25 @@ function processReply(root, formFieldPrefix, temporaryReferences, resolve, rejec
|
|
1171
1508
|
}
|
1172
1509
|
|
1173
1510
|
throw new Error("Type " + typeof value + " is not supported as an argument to a Server Function.");
|
1174
|
-
}
|
1511
|
+
}
|
1512
|
+
|
1513
|
+
function serializeModel(model, id) {
|
1514
|
+
if (typeof model === 'object' && model !== null) {
|
1515
|
+
var reference = serializeByValueID(id);
|
1516
|
+
writtenObjects.set(model, reference);
|
1175
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.
|
1525
|
+
|
1526
|
+
return JSON.stringify(model, resolveToJSON);
|
1527
|
+
}
|
1176
1528
|
|
1177
|
-
var json =
|
1529
|
+
var json = serializeModel(root, 0);
|
1178
1530
|
|
1179
1531
|
if (formData === null) {
|
1180
1532
|
// If it's a simple data structure, we just use plain JSON.
|
@@ -1600,6 +1952,14 @@ function wakeChunkIfInitialized(chunk, resolveListeners, rejectListeners) {
|
|
1600
1952
|
|
1601
1953
|
function triggerErrorOnChunk(chunk, error) {
|
1602
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
|
+
}
|
1603
1963
|
|
1604
1964
|
return;
|
1605
1965
|
}
|
@@ -1629,8 +1989,48 @@ function createInitializedTextChunk(response, value) {
|
|
1629
1989
|
return new Chunk(INITIALIZED, value, null, response);
|
1630
1990
|
}
|
1631
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
|
+
|
1632
2025
|
function resolveModelChunk(chunk, value) {
|
1633
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
|
+
}
|
1634
2034
|
|
1635
2035
|
return;
|
1636
2036
|
}
|
@@ -1749,7 +2149,8 @@ function nullRefGetter() {
|
|
1749
2149
|
}
|
1750
2150
|
}
|
1751
2151
|
|
1752
|
-
function createElement(type, key, props, owner
|
2152
|
+
function createElement(type, key, props, owner, // DEV-only
|
2153
|
+
stack) // DEV-only
|
1753
2154
|
{
|
1754
2155
|
var element;
|
1755
2156
|
|
@@ -1787,6 +2188,10 @@ function createElement(type, key, props, owner) // DEV-only
|
|
1787
2188
|
writable: true,
|
1788
2189
|
value: null
|
1789
2190
|
});
|
2191
|
+
// _debugInfo later. We could move it into _store which remains mutable.
|
2192
|
+
|
2193
|
+
|
2194
|
+
Object.freeze(element.props);
|
1790
2195
|
}
|
1791
2196
|
|
1792
2197
|
return element;
|
@@ -1820,7 +2225,7 @@ function getChunk(response, id) {
|
|
1820
2225
|
return chunk;
|
1821
2226
|
}
|
1822
2227
|
|
1823
|
-
function createModelResolver(chunk, parentObject, key, cyclic, response, map) {
|
2228
|
+
function createModelResolver(chunk, parentObject, key, cyclic, response, map, path) {
|
1824
2229
|
var blocked;
|
1825
2230
|
|
1826
2231
|
if (initializingChunkBlockedModel) {
|
@@ -1837,6 +2242,10 @@ function createModelResolver(chunk, parentObject, key, cyclic, response, map) {
|
|
1837
2242
|
}
|
1838
2243
|
|
1839
2244
|
return function (value) {
|
2245
|
+
for (var i = 1; i < path.length; i++) {
|
2246
|
+
value = value[path[i]];
|
2247
|
+
}
|
2248
|
+
|
1840
2249
|
parentObject[key] = map(response, value); // If this is the root object for a model reference, where `blocked.value`
|
1841
2250
|
// is a stale `null`, the resolved value can be used directly.
|
1842
2251
|
|
@@ -1897,7 +2306,9 @@ function createServerReferenceProxy(response, metaData) {
|
|
1897
2306
|
return proxy;
|
1898
2307
|
}
|
1899
2308
|
|
1900
|
-
function getOutlinedModel(response,
|
2309
|
+
function getOutlinedModel(response, reference, parentObject, key, map) {
|
2310
|
+
var path = reference.split(':');
|
2311
|
+
var id = parseInt(path[0], 16);
|
1901
2312
|
var chunk = getChunk(response, id);
|
1902
2313
|
|
1903
2314
|
switch (chunk.status) {
|
@@ -1913,7 +2324,13 @@ function getOutlinedModel(response, id, parentObject, key, map) {
|
|
1913
2324
|
|
1914
2325
|
switch (chunk.status) {
|
1915
2326
|
case INITIALIZED:
|
1916
|
-
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);
|
1917
2334
|
|
1918
2335
|
if (chunk._debugInfo) {
|
1919
2336
|
// If we have a direct reference to an object that was rendered by a synchronous
|
@@ -1941,7 +2358,7 @@ function getOutlinedModel(response, id, parentObject, key, map) {
|
|
1941
2358
|
case BLOCKED:
|
1942
2359
|
case CYCLIC:
|
1943
2360
|
var parentChunk = initializingChunk;
|
1944
|
-
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));
|
1945
2362
|
return null;
|
1946
2363
|
|
1947
2364
|
default:
|
@@ -1957,6 +2374,12 @@ function createSet(response, model) {
|
|
1957
2374
|
return new Set(model);
|
1958
2375
|
}
|
1959
2376
|
|
2377
|
+
function createBlob(response, model) {
|
2378
|
+
return new Blob(model.slice(1), {
|
2379
|
+
type: model[0]
|
2380
|
+
});
|
2381
|
+
}
|
2382
|
+
|
1960
2383
|
function createFormData(response, model) {
|
1961
2384
|
var formData = new FormData();
|
1962
2385
|
|
@@ -2024,61 +2447,63 @@ function parseModelString(response, parentObject, key, value) {
|
|
2024
2447
|
case 'F':
|
2025
2448
|
{
|
2026
2449
|
// Server Reference
|
2027
|
-
var
|
2028
|
-
|
2029
|
-
return getOutlinedModel(response, _id2, parentObject, key, createServerReferenceProxy);
|
2450
|
+
var ref = value.slice(2);
|
2451
|
+
return getOutlinedModel(response, ref, parentObject, key, createServerReferenceProxy);
|
2030
2452
|
}
|
2031
2453
|
|
2032
2454
|
case 'T':
|
2033
2455
|
{
|
2034
2456
|
// Temporary Reference
|
2035
|
-
var
|
2036
|
-
|
2457
|
+
var reference = '$' + value.slice(2);
|
2037
2458
|
var temporaryReferences = response._tempRefs;
|
2038
2459
|
|
2039
2460
|
if (temporaryReferences == null) {
|
2040
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.');
|
2041
2462
|
}
|
2042
2463
|
|
2043
|
-
return readTemporaryReference(temporaryReferences,
|
2464
|
+
return readTemporaryReference(temporaryReferences, reference);
|
2044
2465
|
}
|
2045
2466
|
|
2046
2467
|
case 'Q':
|
2047
2468
|
{
|
2048
2469
|
// Map
|
2049
|
-
var
|
2470
|
+
var _ref = value.slice(2);
|
2050
2471
|
|
2051
|
-
return getOutlinedModel(response,
|
2472
|
+
return getOutlinedModel(response, _ref, parentObject, key, createMap);
|
2052
2473
|
}
|
2053
2474
|
|
2054
2475
|
case 'W':
|
2055
2476
|
{
|
2056
2477
|
// Set
|
2057
|
-
var
|
2478
|
+
var _ref2 = value.slice(2);
|
2058
2479
|
|
2059
|
-
return getOutlinedModel(response,
|
2480
|
+
return getOutlinedModel(response, _ref2, parentObject, key, createSet);
|
2060
2481
|
}
|
2061
2482
|
|
2062
2483
|
case 'B':
|
2063
2484
|
{
|
2485
|
+
// Blob
|
2486
|
+
{
|
2487
|
+
var _ref3 = value.slice(2);
|
2064
2488
|
|
2065
|
-
|
2489
|
+
return getOutlinedModel(response, _ref3, parentObject, key, createBlob);
|
2490
|
+
}
|
2066
2491
|
}
|
2067
2492
|
|
2068
2493
|
case 'K':
|
2069
2494
|
{
|
2070
2495
|
// FormData
|
2071
|
-
var
|
2496
|
+
var _ref4 = value.slice(2);
|
2072
2497
|
|
2073
|
-
return getOutlinedModel(response,
|
2498
|
+
return getOutlinedModel(response, _ref4, parentObject, key, createFormData);
|
2074
2499
|
}
|
2075
2500
|
|
2076
2501
|
case 'i':
|
2077
2502
|
{
|
2078
2503
|
// Iterator
|
2079
|
-
var
|
2504
|
+
var _ref5 = value.slice(2);
|
2080
2505
|
|
2081
|
-
return getOutlinedModel(response,
|
2506
|
+
return getOutlinedModel(response, _ref5, parentObject, key, extractIterator);
|
2082
2507
|
}
|
2083
2508
|
|
2084
2509
|
case 'I':
|
@@ -2142,9 +2567,9 @@ function parseModelString(response, parentObject, key, value) {
|
|
2142
2567
|
default:
|
2143
2568
|
{
|
2144
2569
|
// We assume that anything else is a reference ID.
|
2145
|
-
var
|
2570
|
+
var _ref6 = value.slice(1);
|
2146
2571
|
|
2147
|
-
return getOutlinedModel(response,
|
2572
|
+
return getOutlinedModel(response, _ref6, parentObject, key, createModel);
|
2148
2573
|
}
|
2149
2574
|
}
|
2150
2575
|
}
|
@@ -2205,9 +2630,41 @@ function resolveModel(response, id, model) {
|
|
2205
2630
|
function resolveText(response, id, text) {
|
2206
2631
|
var chunks = response._chunks;
|
2207
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
|
+
|
2208
2646
|
chunks.set(id, createInitializedTextChunk(response, text));
|
2209
2647
|
}
|
2210
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
|
+
|
2211
2668
|
function resolveModule(response, id, model) {
|
2212
2669
|
var chunks = response._chunks;
|
2213
2670
|
var chunk = chunks.get(id);
|
@@ -2250,6 +2707,245 @@ function resolveModule(response, id, model) {
|
|
2250
2707
|
}
|
2251
2708
|
}
|
2252
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
|
+
|
2253
2949
|
function resolveErrorDev(response, id, digest, message, stack) {
|
2254
2950
|
|
2255
2951
|
|
@@ -2291,7 +2987,127 @@ function resolveConsoleEntry(response, value) {
|
|
2291
2987
|
printToConsole(methodName, args, env);
|
2292
2988
|
}
|
2293
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
|
+
|
2294
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
|
+
}
|
2295
3111
|
|
2296
3112
|
var stringDecoder = response._stringDecoder;
|
2297
3113
|
var row = '';
|
@@ -2366,26 +3182,56 @@ function processFullRow(response, id, tag, buffer, chunk) {
|
|
2366
3182
|
case 82
|
2367
3183
|
/* "R" */
|
2368
3184
|
:
|
3185
|
+
{
|
3186
|
+
{
|
3187
|
+
startReadableStream(response, id, undefined);
|
3188
|
+
return;
|
3189
|
+
}
|
3190
|
+
}
|
2369
3191
|
// Fallthrough
|
2370
3192
|
|
2371
3193
|
case 114
|
2372
3194
|
/* "r" */
|
2373
3195
|
:
|
3196
|
+
{
|
3197
|
+
{
|
3198
|
+
startReadableStream(response, id, 'bytes');
|
3199
|
+
return;
|
3200
|
+
}
|
3201
|
+
}
|
2374
3202
|
// Fallthrough
|
2375
3203
|
|
2376
3204
|
case 88
|
2377
3205
|
/* "X" */
|
2378
3206
|
:
|
3207
|
+
{
|
3208
|
+
{
|
3209
|
+
startAsyncIterable(response, id, false);
|
3210
|
+
return;
|
3211
|
+
}
|
3212
|
+
}
|
2379
3213
|
// Fallthrough
|
2380
3214
|
|
2381
3215
|
case 120
|
2382
3216
|
/* "x" */
|
2383
3217
|
:
|
3218
|
+
{
|
3219
|
+
{
|
3220
|
+
startAsyncIterable(response, id, true);
|
3221
|
+
return;
|
3222
|
+
}
|
3223
|
+
}
|
2384
3224
|
// Fallthrough
|
2385
3225
|
|
2386
3226
|
case 67
|
2387
3227
|
/* "C" */
|
2388
3228
|
:
|
3229
|
+
{
|
3230
|
+
{
|
3231
|
+
stopStream(response, id, row);
|
3232
|
+
return;
|
3233
|
+
}
|
3234
|
+
}
|
2389
3235
|
// Fallthrough
|
2390
3236
|
|
2391
3237
|
case 80
|
@@ -2438,7 +3284,31 @@ function processBinaryChunk(response, chunk) {
|
|
2438
3284
|
|
2439
3285
|
if (resolvedRowTag === 84
|
2440
3286
|
/* "T" */
|
2441
|
-
||
|
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)
|
2442
3312
|
/* "V" */
|
2443
3313
|
) {
|
2444
3314
|
rowTag = resolvedRowTag;
|