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.
@@ -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
- var enableBinaryFlight = false;
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
- // We always create a new entry regardless if we've already written the same
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, id) {
778
- if (id < 0 || id >= set.length) {
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 serializeTemporaryReferenceID(id) {
802
- return '$T' + id.toString(16);
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 === undefined) {
894
- 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) ));
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
- return serializeTemporaryReferenceID(writeTemporaryReference(temporaryReferences, value));
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 = JSON.stringify(resolvedModel, resolveToJSON); // $FlowFixMe[incompatible-type] We know it's not null because we assigned it above.
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 _partJSON = JSON.stringify(value, resolveToJSON); // $FlowFixMe[incompatible-type] We know it's not null because we assigned it above.
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, _partJSON);
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 _partJSON2 = JSON.stringify(partValue, resolveToJSON); // $FlowFixMe[incompatible-type] We know it's not null because we assigned it above.
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, _partJSON2);
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
- }, function (reason) {
1000
- // In the future we could consider serializing this as an error
1001
- // that throws on the server instead.
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 _partJSON3 = JSON.stringify(Array.from(value), resolveToJSON);
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
- var mapId = nextPartId++;
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 _partJSON4 = JSON.stringify(Array.from(value), resolveToJSON);
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
- var setId = nextPartId++;
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 _partJSON5 = JSON.stringify(Array.from(iterator), resolveToJSON);
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
- var iteratorId = nextPartId++;
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 can serialize class instances as temporary references.
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 serializeTemporaryReferenceID(writeTemporaryReference(temporaryReferences, value));
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 === undefined) {
1157
- throw new Error('Client Functions cannot be passed directly to Server Functions. ' + 'Only Functions passed from the Server can be passed back again.');
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
- return serializeTemporaryReferenceID(writeTemporaryReference(temporaryReferences, value));
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 === undefined) {
1165
- 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) ));
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
- return serializeTemporaryReferenceID(writeTemporaryReference(temporaryReferences, value));
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
- } // $FlowFixMe[incompatible-type] it's not going to be undefined because we'll encode it.
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 = JSON.stringify(root, resolveToJSON);
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) // DEV-only
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, id, parentObject, key, map) {
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 chunkValue = map(response, chunk.value);
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 _id2 = parseInt(value.slice(2), 16);
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 _id3 = parseInt(value.slice(2), 16);
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, _id3);
2464
+ return readTemporaryReference(temporaryReferences, reference);
2046
2465
  }
2047
2466
 
2048
2467
  case 'Q':
2049
2468
  {
2050
2469
  // Map
2051
- var _id4 = parseInt(value.slice(2), 16);
2470
+ var _ref = value.slice(2);
2052
2471
 
2053
- return getOutlinedModel(response, _id4, parentObject, key, createMap);
2472
+ return getOutlinedModel(response, _ref, parentObject, key, createMap);
2054
2473
  }
2055
2474
 
2056
2475
  case 'W':
2057
2476
  {
2058
2477
  // Set
2059
- var _id5 = parseInt(value.slice(2), 16);
2478
+ var _ref2 = value.slice(2);
2060
2479
 
2061
- return getOutlinedModel(response, _id5, parentObject, key, createSet);
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
- return undefined;
2489
+ return getOutlinedModel(response, _ref3, parentObject, key, createBlob);
2490
+ }
2068
2491
  }
2069
2492
 
2070
2493
  case 'K':
2071
2494
  {
2072
2495
  // FormData
2073
- var _id7 = parseInt(value.slice(2), 16);
2496
+ var _ref4 = value.slice(2);
2074
2497
 
2075
- return getOutlinedModel(response, _id7, parentObject, key, createFormData);
2498
+ return getOutlinedModel(response, _ref4, parentObject, key, createFormData);
2076
2499
  }
2077
2500
 
2078
2501
  case 'i':
2079
2502
  {
2080
2503
  // Iterator
2081
- var _id8 = parseInt(value.slice(2), 16);
2504
+ var _ref5 = value.slice(2);
2082
2505
 
2083
- return getOutlinedModel(response, _id8, parentObject, key, extractIterator);
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 _id9 = parseInt(value.slice(1), 16);
2570
+ var _ref6 = value.slice(1);
2148
2571
 
2149
- return getOutlinedModel(response, _id9, parentObject, key, createModel);
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
- || enableBinaryFlight
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;