Skip to content

Commit db5378c

Browse files
peixotoleonardomarco-ippolito
authored andcommitted
doc: add esm example for zlib
PR-URL: #55946 Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com> Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
1 parent 58a6fbb commit db5378c

File tree

1 file changed

+230
-13
lines changed

1 file changed

+230
-13
lines changed

doc/api/zlib.md

Lines changed: 230 additions & 13 deletions
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,13 +25,35 @@ 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
25-
const { createGzip } = require('node:zlib');
26-
const { pipeline } = require('node:stream');
28+
```mjs
29+
import {
30+
createReadStream,
31+
createWriteStream,
32+
} from 'node:fs';
33+
import process from 'node:process';
34+
import { createGzip } from 'node:zlib';
35+
import { pipeline } from 'node:stream';
36+
37+
const gzip = createGzip();
38+
const source = createReadStream('input.txt');
39+
const destination = createWriteStream('input.txt.gz');
40+
41+
pipeline(source, gzip, destination, (err) => {
42+
if (err) {
43+
console.error('An error occurred:', err);
44+
process.exitCode = 1;
45+
}
46+
});
47+
```
48+
49+
```cjs
2750
const {
2851
createReadStream,
2952
createWriteStream,
3053
} = require('node:fs');
54+
const process = require('node:process');
55+
const { createGzip } = require('node:zlib');
56+
const { pipeline } = require('node:stream');
3157

3258
const gzip = createGzip();
3359
const source = createReadStream('input.txt');
@@ -39,17 +65,43 @@ pipeline(source, gzip, destination, (err) => {
3965
process.exitCode = 1;
4066
}
4167
});
68+
```
4269

43-
// Or, Promisified
70+
Or, using the promise `pipeline` API:
4471

45-
const { promisify } = require('node:util');
46-
const pipe = promisify(pipeline);
72+
```mjs
73+
import {
74+
createReadStream,
75+
createWriteStream,
76+
} from 'node:fs';
77+
import process from 'node:process';
78+
import { createGzip } from 'node:zlib';
79+
import { pipeline } from 'node:stream/promises';
80+
81+
async function do_gzip(input, output) {
82+
const gzip = createGzip();
83+
const source = createReadStream(input);
84+
const destination = createWriteStream(output);
85+
await pipeline(source, gzip, destination);
86+
}
87+
88+
await do_gzip('input.txt', 'input.txt.gz');
89+
```
90+
91+
```cjs
92+
const {
93+
createReadStream,
94+
createWriteStream,
95+
} = require('node:fs');
96+
const process = require('node:process');
97+
const { createGzip } = require('node:zlib');
98+
const { pipeline } = require('node:stream/promises');
4799

48100
async function do_gzip(input, output) {
49101
const gzip = createGzip();
50102
const source = createReadStream(input);
51103
const destination = createWriteStream(output);
52-
await pipe(source, gzip, destination);
104+
await pipeline(source, gzip, destination);
53105
}
54106

55107
do_gzip('input.txt', 'input.txt.gz')
@@ -61,7 +113,39 @@ do_gzip('input.txt', 'input.txt.gz')
61113

62114
It is also possible to compress or decompress data in a single step:
63115

64-
```js
116+
```mjs
117+
import process from 'node:process';
118+
import { Buffer } from 'node:buffer';
119+
import { deflate, unzip } from 'node:zlib';
120+
121+
const input = '.................................';
122+
deflate(input, (err, buffer) => {
123+
if (err) {
124+
console.error('An error occurred:', err);
125+
process.exitCode = 1;
126+
}
127+
console.log(buffer.toString('base64'));
128+
});
129+
130+
const buffer = Buffer.from('eJzT0yMAAGTvBe8=', 'base64');
131+
unzip(buffer, (err, buffer) => {
132+
if (err) {
133+
console.error('An error occurred:', err);
134+
process.exitCode = 1;
135+
}
136+
console.log(buffer.toString());
137+
});
138+
139+
// Or, Promisified
140+
141+
import { promisify } from 'node:util';
142+
const do_unzip = promisify(unzip);
143+
144+
const unzippedBuffer = await do_unzip(buffer);
145+
console.log(unzippedBuffer.toString());
146+
```
147+
148+
```cjs
65149
const { deflate, unzip } = require('node:zlib');
66150

67151
const input = '.................................';
@@ -104,7 +188,19 @@ limitations in some applications.
104188
Creating and using a large number of zlib objects simultaneously can cause
105189
significant memory fragmentation.
106190

107-
```js
191+
```mjs
192+
import zlib from 'node:zlib';
193+
import { Buffer } from 'node:buffer';
194+
195+
const payload = Buffer.from('This is some data');
196+
197+
// WARNING: DO NOT DO THIS!
198+
for (let i = 0; i < 30000; ++i) {
199+
zlib.deflate(payload, (err, buffer) => {});
200+
}
201+
```
202+
203+
```cjs
108204
const zlib = require('node:zlib');
109205

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

141-
```js
237+
```mjs
238+
// Client request example
239+
import fs from 'node:fs';
240+
import zlib from 'node:zlib';
241+
import http from 'node:http';
242+
import process from 'node:process';
243+
import { pipeline } from 'node:stream';
244+
245+
const request = http.get({ host: 'example.com',
246+
path: '/',
247+
port: 80,
248+
headers: { 'Accept-Encoding': 'br,gzip,deflate' } });
249+
request.on('response', (response) => {
250+
const output = fs.createWriteStream('example.com_index.html');
251+
252+
const onError = (err) => {
253+
if (err) {
254+
console.error('An error occurred:', err);
255+
process.exitCode = 1;
256+
}
257+
};
258+
259+
switch (response.headers['content-encoding']) {
260+
case 'br':
261+
pipeline(response, zlib.createBrotliDecompress(), output, onError);
262+
break;
263+
// Or, just use zlib.createUnzip() to handle both of the following cases:
264+
case 'gzip':
265+
pipeline(response, zlib.createGunzip(), output, onError);
266+
break;
267+
case 'deflate':
268+
pipeline(response, zlib.createInflate(), output, onError);
269+
break;
270+
default:
271+
pipeline(response, output, onError);
272+
break;
273+
}
274+
});
275+
```
276+
277+
```cjs
142278
// Client request example
143279
const zlib = require('node:zlib');
144280
const http = require('node:http');
@@ -177,7 +313,52 @@ request.on('response', (response) => {
177313
});
178314
```
179315

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

321-
```js
502+
```mjs
503+
import zlib from 'node:zlib';
504+
import http from 'node:http';
505+
import { pipeline } from 'node:stream';
506+
507+
http.createServer((request, response) => {
508+
// For the sake of simplicity, the Accept-Encoding checks are omitted.
509+
response.writeHead(200, { 'content-encoding': 'gzip' });
510+
const output = zlib.createGzip();
511+
let i;
512+
513+
pipeline(output, response, (err) => {
514+
if (err) {
515+
// If an error occurs, there's not much we can do because
516+
// the server has already sent the 200 response code and
517+
// some amount of data has already been sent to the client.
518+
// The best we can do is terminate the response immediately
519+
// and log the error.
520+
clearInterval(i);
521+
response.end();
522+
console.error('An error occurred:', err);
523+
}
524+
});
525+
526+
i = setInterval(() => {
527+
output.write(`The current time is ${Date()}\n`, () => {
528+
// The data has been passed to zlib, but the compression algorithm may
529+
// have decided to buffer the data for more efficient compression.
530+
// Calling .flush() will make the data available as soon as the client
531+
// is ready to receive it.
532+
output.flush();
533+
});
534+
}, 1000);
535+
}).listen(1337);
536+
```
537+
538+
```cjs
322539
const zlib = require('node:zlib');
323540
const http = require('node:http');
324541
const { pipeline } = require('node:stream');

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy