131
132
export type Response = {
133
_bundlerConfig: ServerManifest,
134
+ _prefix: string,
135
+ _formData: FormData,
136
_chunks: Map<number, SomeChunk<any>>,
137
_fromJSON: (key: string, value: JSONValue) => any,
138
};
311
const chunks = response._chunks;
312
let chunk = chunks.get(id);
313
if (!chunk) {
312
- chunk = createPendingChunk(response);
314
+ const prefix = response._prefix;
315
+ const key = prefix + id;
316
+ // Check if we have this field in the backing store already.
317
+ const backingEntry = response._formData.get(key);
318
+ if (backingEntry != null) {
319
+ // We assume that this is a string entry for now.
320
+ chunk = createResolvedModelChunk(response, (backingEntry: any));
321
+ } else {
322
+ // We're still waiting on this entry to stream in.
323
+ chunk = createPendingChunk(response);
324
+ }
325
chunks.set(id, chunk);
326
}
327
return chunk;
409
key,
410
);
411
}
412
+ case 'K': {
413
+ // FormData
414
+ const stringId = value.substring(2);
415
+ const formPrefix = response._prefix + stringId + '_';
416
+ const data = new FormData();
417
+ const backingFormData = response._formData;
418
+ // We assume that the reference to FormData always comes after each
419
+ // entry that it references so we can assume they all exist in the
420
+ // backing store already.
421
+ // $FlowFixMe[prop-missing] FormData has forEach on it.
422
+ backingFormData.forEach((entry: File | string, entryKey: string) => {
423
+ if (entryKey.startsWith(formPrefix)) {
424
+ data.append(entryKey.substr(formPrefix.length), entry);
425
+ }
426
+ });
427
+ return data;
428
+ }
429
case 'I': {
430
// $Infinity
431
return Infinity;
481
return value;
482
}
483
455
-export function createResponse(bundlerConfig: ServerManifest): Response {
484
+export function createResponse(
485
+ bundlerConfig: ServerManifest,
486
+ formFieldPrefix: string,
487
+ backingFormData?: FormData = new FormData(),
488
+): Response {
489
const chunks: Map<number, SomeChunk<any>> = new Map();
490
const response: Response = {
491
_bundlerConfig: bundlerConfig,
492
+ _prefix: formFieldPrefix,
493
+ _formData: backingFormData,
494
_chunks: chunks,
495
_fromJSON: function (this: any, key: string, value: JSONValue) {
496
if (typeof value === 'string') {
505
506
export function resolveField(
507
response: Response,
473
- id: number,
474
- model: string,
508
+ key: string,
509
+ value: string,
510
): void {
476
- const chunks = response._chunks;
477
- const chunk = chunks.get(id);
478
- if (!chunk) {
479
- chunks.set(id, createResolvedModelChunk(response, model));
480
- } else {
481
- resolveModelChunk(chunk, model);
511
+ // Add this field to the backing store.
512
+ response._formData.append(key, value);
513
+ const prefix = response._prefix;
514
+ if (key.startsWith(prefix)) {
515
+ const chunks = response._chunks;
516
+ const id = +key.substr(prefix.length);
517
+ const chunk = chunks.get(id);
518
+ if (chunk) {
519
+ // We were waiting on this key so now we can resolve it.
520
+ resolveModelChunk(chunk, value);
521
+ }
522
}
523
}
524
485
-export function resolveFile(response: Response, id: number, file: File): void {
486
- throw new Error('Not implemented.');
525
+export function resolveFile(response: Response, key: string, file: File): void {
526
+ // Add this field to the backing store.
527
+ response._formData.append(key, file);
528
}
529
489
-export opaque type FileHandle = {};
530
+export opaque type FileHandle = {
531
+ chunks: Array<Uint8Array>,
532
+ filename: string,
533
+ mime: string,
534
+};
535
536
export function resolveFileInfo(
537
response: Response,
493
- id: number,
538
+ key: string,
539
filename: string,
540
mime: string,
541
): FileHandle {
497
- throw new Error('Not implemented.');
542
+ return {
543
+ chunks: [],
544
+ filename,
545
+ mime,
546
+ };
547
}
548
549
export function resolveFileChunk(
551
handle: FileHandle,
552
chunk: Uint8Array,
553
): void {
505
- throw new Error('Not implemented.');
554
+ handle.chunks.push(chunk);
555
}
556
557
export function resolveFileComplete(
558
response: Response,
559
+ key: string,
560
handle: FileHandle,
561
): void {
512
- throw new Error('Not implemented.');
562
+ // Add this file to the backing store.
563
+ const file = new File(handle.chunks, handle.filename, {type: handle.mime});
564
+ response._formData.append(key, file);
565
}
566
567
export function close(response: Response): void {