Skip to content

Commit 72b868e

Browse files
doc: add esm example for zlib
1 parent 5ba3b54 commit 72b868e

File tree

1 file changed

+213
-10
lines changed

1 file changed

+213
-10
lines changed

doc/api/zlib.md

+213-10
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,11 @@ Gzip, Deflate/Inflate, and Brotli.
1111

1212
To access it:
1313

14-
```js
14+
```mjs
15+
import os from 'node:zlib';
16+
```
17+
18+
```cjs
1519
const zlib = require('node:zlib');
1620
```
1721

@@ -21,7 +25,43 @@ Compressing or decompressing a stream (such as a file) can be accomplished by
2125
piping the source stream through a `zlib` `Transform` stream into a destination
2226
stream:
2327

24-
```js
28+
```mjs
29+
import { createGzip } from 'node:zlib';
30+
import { pipeline } from 'node:stream';
31+
import {
32+
createReadStream,
33+
createWriteStream,
34+
} from 'node:fs';
35+
36+
const gzip = createGzip();
37+
const source = createReadStream('input.txt');
38+
const destination = createWriteStream('input.txt.gz');
39+
40+
pipeline(source, gzip, destination, (err) => {
41+
if (err) {
42+
console.error('An error occurred:', err);
43+
process.exitCode = 1;
44+
}
45+
});
46+
47+
// Or, Promisified
48+
import { pipeline } from 'node:stream/promises';
49+
50+
async function do_gzip(input, output) {
51+
const gzip = createGzip();
52+
const source = createReadStream(input);
53+
const destination = createWriteStream(output);
54+
await pipe(source, gzip, destination);
55+
}
56+
57+
do_gzip('input.txt', 'input.txt.gz')
58+
.catch((err) => {
59+
console.error('An error occurred:', err);
60+
process.exitCode = 1;
61+
});
62+
```
63+
64+
```cjs
2565
const { createGzip } = require('node:zlib');
2666
const { pipeline } = require('node:stream');
2767
const {
@@ -41,9 +81,7 @@ pipeline(source, gzip, destination, (err) => {
4181
});
4282

4383
// Or, Promisified
44-
45-
const { promisify } = require('node:util');
46-
const pipe = promisify(pipeline);
84+
const { pipeline } = require('node:stream/promises');
4785

4886
async function do_gzip(input, output) {
4987
const gzip = createGzip();
@@ -61,7 +99,41 @@ do_gzip('input.txt', 'input.txt.gz')
6199

62100
It is also possible to compress or decompress data in a single step:
63101

64-
```js
102+
```mjs
103+
import { deflate, unzip } from 'node:zlib';
104+
105+
const input = '.................................';
106+
deflate(input, (err, buffer) => {
107+
if (err) {
108+
console.error('An error occurred:', err);
109+
process.exitCode = 1;
110+
}
111+
console.log(buffer.toString('base64'));
112+
});
113+
114+
const buffer = Buffer.from('eJzT0yMAAGTvBe8=', 'base64');
115+
unzip(buffer, (err, buffer) => {
116+
if (err) {
117+
console.error('An error occurred:', err);
118+
process.exitCode = 1;
119+
}
120+
console.log(buffer.toString());
121+
});
122+
123+
// Or, Promisified
124+
125+
import { promisify } from 'node:util';
126+
const do_unzip = promisify(unzip);
127+
128+
do_unzip(buffer)
129+
.then((buf) => console.log(buf.toString()))
130+
.catch((err) => {
131+
console.error('An error occurred:', err);
132+
process.exitCode = 1;
133+
});
134+
```
135+
136+
```cjs
65137
const { deflate, unzip } = require('node:zlib');
66138

67139
const input = '.................................';
@@ -104,7 +176,18 @@ limitations in some applications.
104176
Creating and using a large number of zlib objects simultaneously can cause
105177
significant memory fragmentation.
106178

107-
```js
179+
```mjs
180+
import zlib from 'node:zlib';
181+
182+
const payload = Buffer.from('This is some data');
183+
184+
// WARNING: DO NOT DO THIS!
185+
for (let i = 0; i < 30000; ++i) {
186+
zlib.deflate(payload, (err, buffer) => {});
187+
}
188+
```
189+
190+
```cjs
108191
const zlib = require('node:zlib');
109192

110193
const payload = Buffer.from('This is some data');
@@ -138,7 +221,46 @@ Using `zlib` encoding can be expensive, and the results ought to be cached.
138221
See [Memory usage tuning][] for more information on the speed/memory/compression
139222
tradeoffs involved in `zlib` usage.
140223

141-
```js
224+
```mjs
225+
// Client request example
226+
import zlib from 'node:zlib';
227+
import http from 'node:http';
228+
import fs from 'node:fs';
229+
import { pipeline } from 'node:stream';
230+
231+
const request = http.get({ host: 'example.com',
232+
path: '/',
233+
port: 80,
234+
headers: { 'Accept-Encoding': 'br,gzip,deflate' } });
235+
request.on('response', (response) => {
236+
const output = fs.createWriteStream('example.com_index.html');
237+
238+
const onError = (err) => {
239+
if (err) {
240+
console.error('An error occurred:', err);
241+
process.exitCode = 1;
242+
}
243+
};
244+
245+
switch (response.headers['content-encoding']) {
246+
case 'br':
247+
pipeline(response, zlib.createBrotliDecompress(), output, onError);
248+
break;
249+
// Or, just use zlib.createUnzip() to handle both of the following cases:
250+
case 'gzip':
251+
pipeline(response, zlib.createGunzip(), output, onError);
252+
break;
253+
case 'deflate':
254+
pipeline(response, zlib.createInflate(), output, onError);
255+
break;
256+
default:
257+
pipeline(response, output, onError);
258+
break;
259+
}
260+
});
261+
```
262+
263+
```cjs
142264
// Client request example
143265
const zlib = require('node:zlib');
144266
const http = require('node:http');
@@ -177,7 +299,52 @@ request.on('response', (response) => {
177299
});
178300
```
179301

180-
```js
302+
```mjs
303+
// server example
304+
// Running a gzip operation on every request is quite expensive.
305+
// It would be much more efficient to cache the compressed buffer.
306+
import zlib from 'node:zlib';
307+
import http from 'node:http';
308+
import fs from 'node:fs';
309+
import { pipeline } from 'node:stream';
310+
311+
http.createServer((request, response) => {
312+
const raw = fs.createReadStream('index.html');
313+
// Store both a compressed and an uncompressed version of the resource.
314+
response.setHeader('Vary', 'Accept-Encoding');
315+
const acceptEncoding = request.headers['accept-encoding'] || '';
316+
317+
const onError = (err) => {
318+
if (err) {
319+
// If an error occurs, there's not much we can do because
320+
// the server has already sent the 200 response code and
321+
// some amount of data has already been sent to the client.
322+
// The best we can do is terminate the response immediately
323+
// and log the error.
324+
response.end();
325+
console.error('An error occurred:', err);
326+
}
327+
};
328+
329+
// Note: This is not a conformant accept-encoding parser.
330+
// See https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.3
331+
if (/\bdeflate\b/.test(acceptEncoding)) {
332+
response.writeHead(200, { 'Content-Encoding': 'deflate' });
333+
pipeline(raw, zlib.createDeflate(), response, onError);
334+
} else if (/\bgzip\b/.test(acceptEncoding)) {
335+
response.writeHead(200, { 'Content-Encoding': 'gzip' });
336+
pipeline(raw, zlib.createGzip(), response, onError);
337+
} else if (/\bbr\b/.test(acceptEncoding)) {
338+
response.writeHead(200, { 'Content-Encoding': 'br' });
339+
pipeline(raw, zlib.createBrotliCompress(), response, onError);
340+
} else {
341+
response.writeHead(200, {});
342+
pipeline(raw, response, onError);
343+
}
344+
}).listen(1337);
345+
```
346+
347+
```cjs
181348
// server example
182349
// Running a gzip operation on every request is quite expensive.
183350
// It would be much more efficient to cache the compressed buffer.
@@ -315,7 +482,43 @@ quality, but can be useful when data needs to be available as soon as possible.
315482
In the following example, `flush()` is used to write a compressed partial
316483
HTTP response to the client:
317484

318-
```js
485+
```mjs
486+
import zlib from 'node:zlib;
487+
import http from 'node:http;
488+
import { pipeline } from 'node:stream;
489+
490+
http.createServer((request, response) => {
491+
// For the sake of simplicity, the Accept-Encoding checks are omitted.
492+
response.writeHead(200, { 'content-encoding': 'gzip' });
493+
const output = zlib.createGzip();
494+
let i;
495+
496+
pipeline(output, response, (err) => {
497+
if (err) {
498+
// If an error occurs, there's not much we can do because
499+
// the server has already sent the 200 response code and
500+
// some amount of data has already been sent to the client.
501+
// The best we can do is terminate the response immediately
502+
// and log the error.
503+
clearInterval(i);
504+
response.end();
505+
console.error('An error occurred:', err);
506+
}
507+
});
508+
509+
i = setInterval(() => {
510+
output.write(`The current time is ${Date()}\n`, () => {
511+
// The data has been passed to zlib, but the compression algorithm may
512+
// have decided to buffer the data for more efficient compression.
513+
// Calling .flush() will make the data available as soon as the client
514+
// is ready to receive it.
515+
output.flush();
516+
});
517+
}, 1000);
518+
}).listen(1337);
519+
```
520+
521+
```cjs
319522
const zlib = require('node:zlib');
320523
const http = require('node:http');
321524
const { pipeline } = require('node:stream');

0 commit comments

Comments
 (0)