|
580 | 580 | }; |
581 | 581 | } |
582 | 582 |
|
583 | | - function attachWritableObjectURL(url, value) { |
584 | | - value._addObserver({ |
585 | | - write(chunk) { |
586 | | - return Promise.resolve(writeWritableObjectURL(url, chunk)); |
587 | | - }, |
588 | | - close() { |
589 | | - return Promise.resolve(closeWritableObjectURL(url)); |
590 | | - }, |
591 | | - abort(reason) { |
592 | | - return Promise.resolve(abortWritableObjectURL(url, reason == null ? "" : String(reason))); |
593 | | - } |
594 | | - }); |
595 | | - value.__gopeedObjectURL = url; |
596 | | - return url; |
597 | | - } |
598 | | - |
599 | | - function pipeReadableToWritable(readable, writable) { |
600 | | - const writer = writable.getWriter(); |
601 | | - void (async () => { |
602 | | - const reader = readable.getReader(); |
603 | | - try { |
604 | | - while (true) { |
605 | | - const { done, value } = await reader.read(); |
606 | | - if (done) { |
607 | | - break; |
608 | | - } |
609 | | - await writer.write(value); |
610 | | - } |
611 | | - await writer.close(); |
612 | | - } catch (error) { |
613 | | - try { |
614 | | - await writer.abort(error); |
615 | | - } catch (_) { |
616 | | - } |
617 | | - } finally { |
618 | | - if (typeof reader.releaseLock === "function") { |
619 | | - reader.releaseLock(); |
620 | | - } |
621 | | - } |
622 | | - })(); |
623 | | - } |
624 | | - |
625 | 583 | function startReadableObjectURL(url, state) { |
626 | 584 | activeReadableObjectURLs.set(url, state); |
627 | 585 | setTimeout(() => { |
|
661 | 619 | } |
662 | 620 |
|
663 | 621 | async function pumpReadableObjectURL(url, state) { |
| 622 | + let reader = null; |
664 | 623 | try { |
665 | 624 | let source; |
666 | 625 | if (state.initialReadable) { |
|
672 | 631 | } |
673 | 632 | source = await state.openReadable(state.offset); |
674 | 633 | } |
675 | | - const reader = toReadableStreamReader(source, state.sourceLabel); |
| 634 | + reader = toReadableStreamReader(source, state.sourceLabel); |
676 | 635 | if (activeReadableObjectURLs.get(url) !== state || state.cancelled) { |
677 | 636 | releaseReader(reader, "stale gblob producer"); |
| 637 | + reader = null; |
678 | 638 | return; |
679 | 639 | } |
680 | 640 | state.reader = reader; |
|
683 | 643 | const current = activeReadableObjectURLs.get(url); |
684 | 644 | if (current !== state) { |
685 | 645 | releaseReader(reader, "stale gblob producer"); |
| 646 | + reader = null; |
686 | 647 | return; |
687 | 648 | } |
688 | 649 | const { done, value } = await reader.read(); |
|
692 | 653 | await closeWritableObjectURL(url); |
693 | 654 | } |
694 | 655 | releaseReader(reader); |
| 656 | + reader = null; |
695 | 657 | return; |
696 | 658 | } |
697 | 659 | const chunk = value instanceof Uint8Array ? value : new Uint8Array(value); |
698 | 660 | if (activeReadableObjectURLs.get(url) !== state || state.cancelled) { |
699 | 661 | releaseReader(reader, "stale gblob producer"); |
| 662 | + reader = null; |
700 | 663 | return; |
701 | 664 | } |
702 | 665 | await writeWritableObjectURL(url, chunk); |
|
707 | 670 | } |
708 | 671 | } |
709 | 672 | releaseReader(reader, "gblob producer cancelled"); |
| 673 | + reader = null; |
710 | 674 | } catch (error) { |
711 | 675 | if (isIgnorableGBlobObjectURLError(error)) { |
| 676 | + if (activeReadableObjectURLs.get(url) === state) { |
| 677 | + activeReadableObjectURLs.delete(url); |
| 678 | + } |
| 679 | + if (reader) { |
| 680 | + releaseReader(reader, "gblob source closed"); |
| 681 | + reader = null; |
| 682 | + } |
712 | 683 | return; |
713 | 684 | } |
714 | 685 | if (activeReadableObjectURLs.get(url) === state) { |
|
718 | 689 | } catch (_) { |
719 | 690 | } |
720 | 691 | } |
| 692 | + if (reader) { |
| 693 | + releaseReader(reader, error); |
| 694 | + reader = null; |
| 695 | + } |
721 | 696 | } |
722 | 697 | } |
723 | 698 |
|
|
743 | 718 | return createBlobObjectURL(described.value._buffer, described.value.type || ""); |
744 | 719 | } |
745 | 720 | if (described.kind === "readable") { |
746 | | - const transform = new TransformStream(); |
747 | | - const url = attachWritableObjectURL(createWritableObjectURL(false), transform.writable); |
748 | | - pipeReadableToWritable(described.initialReadable, transform.writable); |
| 721 | + const url = createWritableObjectURL(false); |
| 722 | + startReadableObjectURL(url, { |
| 723 | + initialReadable: described.initialReadable, |
| 724 | + openReadable: null, |
| 725 | + sourceLabel: described.sourceLabel, |
| 726 | + offset: 0, |
| 727 | + reader: null, |
| 728 | + cancelled: false, |
| 729 | + }); |
749 | 730 | return url; |
750 | 731 | } |
751 | 732 | if (described.kind === "opener") { |
|
0 commit comments