@@ -77,50 +77,62 @@ const brotli = await brotliPromise; // Import is async in browsers due to wasm r
7777
7878const input = ' some input' ;
7979
80+ // Get a stream for your input:
8081const inputStream = new ReadableStream ({
81- start (controller ) {
82+ start (controller ) {
8283 controller .enqueue (input);
8384 controller .close ();
8485 }
8586});
8687
88+ // Convert the streaming data to Uint8Arrays, if necessary:
8789const textEncoderStream = new TextEncoderStream ();
90+
91+ // Create a stream to incrementally compress the data as it streams:
8892const compressStream = new brotli.CompressStream ();
8993const compressionStream = new TransformStream ({
90- start () {},
91- transform (chunk , controller ) {
92- controller .enqueue (compressStream .compress (chunk, 100 ));
94+ start () { },
95+ transform (chunk , controller ) {
96+ // Compress data, producing 1024 bytes of output at a time (i.e. limiting the output):
97+ controller .enqueue (compressStream .compress (chunk, 1024 ));
9398 },
94- flush (controller ) {
95- if (compressStream .result () === brotli .BrotliStreamResult .NeedsMoreInput ) {
96- controller .enqueue (compressStream .compress (undefined , 100 ));
99+ flush (controller ) {
100+ // Stream remaining compressed data after input finishes, 1024 bytes of output at a time:
101+ while (
102+ compressStream .result () === brotli .BrotliStreamResult .NeedsMoreInput ||
103+ compressStream .result () === brotli .BrotliStreamResult .NeedsMoreOutput
104+ ) {
105+ controller .enqueue (compressStream .compress (undefined , 1024 ));
97106 }
98107 controller .terminate ();
99108 }
100109});
101110
102111const decompressStream = new brotli.DecompressStream ();
103112const decompressionStream = new TransformStream ({
104- start () {},
105- transform (chunk , controller ) {
106- controller .enqueue (decompressStream .decompress (chunk, 100 ));
113+ start () { },
114+ transform (chunk , controller ) {
115+ // Decompress, producing 1024 bytes of output at a time:
116+ controller .enqueue (decompressStream .decompress (chunk, 1024 ));
107117 },
108- flush (controller ) {
109- if (decompressStream .result () === brotli .BrotliStreamResult .NeedsMoreInput ) {
110- controller .enqueue (decompressStream .decompress (undefined , 100 ));
118+ flush (controller ) {
119+ // Decompress all remaining output after input finishes, 1024 bytes at a time:
120+ while (decompressStream .result () === brotli .BrotliStreamResult .NeedsMoreOutput ) {
121+ controller .enqueue (decompressStream .decompress (new Uint8Array (0 ), 1024 ));
111122 }
112123 controller .terminate ();
113124 }
114125});
115126
116- const textDecoderStream = new TextDecoderStream ()
127+ const textDecoderStream = new TextDecoderStream ();
128+
129+ let output = ' ' ;
117130const outputStream = new WritableStream ({
118- write (chunk ) {
131+ write (chunk ) {
119132 output += chunk;
120133 }
121134});
122135
123- let output = ' ' ;
124136await inputStream
125137 .pipeThrough (textEncoderStream)
126138 .pipeThrough (compressionStream)
@@ -130,7 +142,9 @@ await inputStream
130142console .log (output); // Prints 'some input'
131143```
132144
133- Note that ` TransformStream ` has become available in all browsers as of mid-2022. https://caniuse.com/mdn-api_transformstream
145+ Note that ` TransformStream ` has become available in all browsers as of mid-2022: https://caniuse.com/mdn-api_transformstream . It's also been available in Node.js (experimentally) since v16.5.0.
146+
147+ This is a simplified demo example - you may well want to tweak the specific stream buffer sizes for compression/decompression to your use case, to reuse buffers, or explore further optimizations if you're interested in these streaming use cases.
134148
135149## Alternatives
136150
0 commit comments