| 660 | } |
| 661 | |
| 662 | function createGunzipTransform(): TransformObject { |
| 663 | const gunzip = zlib.createGunzip(); |
| 664 | const pending: Uint8Array[] = []; |
| 665 | let error: Error | null = null; |
| 666 | |
| 667 | gunzip.on('data', (chunk: Buffer) => pending.push(new Uint8Array(chunk))); |
| 668 | gunzip.on('error', (err) => { error = err; }); |
| 669 | |
| 670 | async function processChunk(chunk: Uint8Array | null): Promise<Uint8Array[]> { |
| 671 | if (error) throw error; |
| 672 | if (chunk === null) { |
| 673 | await new Promise<void>((resolve, reject) => { |
| 674 | gunzip.once('end', resolve); |
| 675 | gunzip.once('error', reject); |
| 676 | gunzip.end(); |
| 677 | }); |
| 678 | return pending.splice(0); |
| 679 | } |
| 680 | await new Promise<void>((resolve, reject) => { |
| 681 | gunzip.write(copyToBuffer(chunk), (err) => { |
| 682 | if (err) { reject(err); return; } |
| 683 | gunzip.flush(() => resolve()); |
| 684 | }); |
| 685 | }); |
| 686 | return pending.splice(0); |
| 687 | } |
| 688 | |
| 689 | return { |
| 690 | |
| 691 | async *transform(source: AsyncIterable<Uint8Array[] | null>, { signal }: { signal: AbortSignal }) { |
| 692 | const onAbort = () => { |
| 693 | gunzip.destroy(signal.reason instanceof Error ? signal.reason : new Error(String(signal.reason))); |
| 694 | }; |
| 695 | signal.addEventListener('abort', onAbort, { once: true }); |
| 696 | try { |
| 697 | for await (const batches of source) { |
| 698 | if (batches === null) { |
| 699 | const output = await processChunk(null); |
| 700 | for (const chunk of output) yield chunk; |
| 701 | continue; |
| 702 | } |
| 703 | for (const chunk of batches) { |
| 704 | const output = await processChunk(chunk); |
| 705 | for (const out of output) yield out; |
| 706 | } |
| 707 | } |
| 708 | } finally { |
| 709 | signal.removeEventListener('abort', onAbort); |
| 710 | gunzip.destroy(); |
| 711 | } |
| 712 | }, |
| 713 | }; |
| 714 | } |
| 715 | |
| 716 | const plaintext = JSON.stringify( |
| 717 | Array.from({ length: 50 }, (_, i) => ({ id: i, data: 'x'.repeat(100) })) |