@@ -77,50 +77,62 @@ const brotli = await brotliPromise; // Import is async in browsers due to wasm r
77
77
78
78
const input = ' some input' ;
79
79
80
+ // Get a stream for your input:
80
81
const inputStream = new ReadableStream ({
81
- start (controller ) {
82
+ start (controller ) {
82
83
controller .enqueue (input);
83
84
controller .close ();
84
85
}
85
86
});
86
87
88
+ // Convert the streaming data to Uint8Arrays, if necessary:
87
89
const textEncoderStream = new TextEncoderStream ();
90
+
91
+ // Create a stream to incrementally compress the data as it streams:
88
92
const compressStream = new brotli.CompressStream ();
89
93
const 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 ));
93
98
},
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 ));
97
106
}
98
107
controller .terminate ();
99
108
}
100
109
});
101
110
102
111
const decompressStream = new brotli.DecompressStream ();
103
112
const 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 ));
107
117
},
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 ));
111
122
}
112
123
controller .terminate ();
113
124
}
114
125
});
115
126
116
- const textDecoderStream = new TextDecoderStream ()
127
+ const textDecoderStream = new TextDecoderStream ();
128
+
129
+ let output = ' ' ;
117
130
const outputStream = new WritableStream ({
118
- write (chunk ) {
131
+ write (chunk ) {
119
132
output += chunk;
120
133
}
121
134
});
122
135
123
- let output = ' ' ;
124
136
await inputStream
125
137
.pipeThrough (textEncoderStream)
126
138
.pipeThrough (compressionStream)
@@ -130,7 +142,9 @@ await inputStream
130
142
console .log (output); // Prints 'some input'
131
143
```
132
144
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.
134
148
135
149
## Alternatives
136
150
0 commit comments