208
return '$' + tag + blobId.toString(16);
209
}
210
211
- function serializeReadableStream(stream: ReadableStream): string {
211
+ function serializeBinaryReader(reader: any): string {
212
if (formData === null) {
213
// Upgrade to use FormData to allow us to stream this value.
214
formData = new FormData();
218
pendingParts++;
219
const streamId = nextPartId++;
220
221
- // Detect if this is a BYOB stream. BYOB streams should be able to be read as bytes on the
222
- // receiving side. It also implies that different chunks can be split up or merged as opposed
223
- // to a readable stream that happens to have Uint8Array as the type which might expect it to be
224
- // received in the same slices.
225
- // $FlowFixMe: This is a Node.js extension.
226
- let supportsBYOB: void | boolean = stream.supportsBYOB;
227
- if (supportsBYOB === undefined) {
228
- try {
229
- // $FlowFixMe[extra-arg]: This argument is accepted.
230
- stream.getReader({mode: 'byob'}).releaseLock();
231
- supportsBYOB = true;
232
- } catch (x) {
233
- supportsBYOB = false;
221
+ const buffer = [];
222
+
223
+ function progress(entry: {done: boolean, value: ReactServerValue, ...}) {
224
+ if (entry.done) {
225
+ const blobId = nextPartId++;
226
+ // eslint-disable-next-line react-internal/safe-string-coercion
227
+ data.append(formFieldPrefix + blobId, new Blob(buffer));
228
+ // eslint-disable-next-line react-internal/safe-string-coercion
229
+ data.append(
230
+ formFieldPrefix + streamId,
231
+ '"$o' + blobId.toString(16) + '"',
232
+ );
233
+ // eslint-disable-next-line react-internal/safe-string-coercion
234
+ data.append(formFieldPrefix + streamId, 'C'); // Close signal
235
+ pendingParts--;
236
+ if (pendingParts === 0) {
237
+ resolve(data);
238
+ }
239
+ } else {
240
+ buffer.push(entry.value);
241
+ reader.read(new Uint8Array(1024)).then(progress, reject);
242
}
243
}
244
+ reader.read(new Uint8Array(1024)).then(progress, reject);
245
237
- const reader = stream.getReader();
246
+ return '$r' + streamId.toString(16);
247
+ }
248
+
249
+ function serializeReader(reader: ReadableStreamReader): string {
250
+ if (formData === null) {
251
+ // Upgrade to use FormData to allow us to stream this value.
252
+ formData = new FormData();
253
+ }
254
+ const data = formData;
255
+
256
+ pendingParts++;
257
+ const streamId = nextPartId++;
258
259
function progress(entry: {done: boolean, value: ReactServerValue, ...}) {
260
if (entry.done) {
278
}
279
reader.read().then(progress, reject);
280
261
- return '$' + (supportsBYOB ? 'r' : 'R') + streamId.toString(16);
281
+ return '$R' + streamId.toString(16);
282
+ }
283
+
284
+ function serializeReadableStream(stream: ReadableStream): string {
285
+ // Detect if this is a BYOB stream. BYOB streams should be able to be read as bytes on the
286
+ // receiving side. For binary streams, we serialize them as plain Blobs.
287
+ let binaryReader;
288
+ try {
289
+ // $FlowFixMe[extra-arg]: This argument is accepted.
290
+ binaryReader = stream.getReader({mode: 'byob'});
291
+ } catch (x) {
292
+ return serializeReader(stream.getReader());
293
+ }
294
+ return serializeBinaryReader(binaryReader);
295
}
296
297
function serializeAsyncIterable(