Skip to content

Commit

Permalink
Add minifyPipeline function
Browse files Browse the repository at this point in the history
  • Loading branch information
kristian committed Dec 3, 2023
1 parent eefabe8 commit 385a14e
Show file tree
Hide file tree
Showing 6 changed files with 43 additions and 9 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,13 @@

## `HEAD`

No changes yet

# 4.3.0

- Back to the roots, minimize dependency footprint, similar to how Mathias Bynens handled the library
- Minimum required node version to execute tests is now 16.7.0, due to the use of `node:stream/consumers`
- Asynchronous `minifyPipeline` function utilizing Node.js `node:stream/promises` pipeline

## 4.2.0

Expand Down
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,14 @@ fs.createReadStream("sitemap.xml", "utf8")
.pipe(process.stdout);
```

Similar to streams, Node.js 15 introduced an asynchronous [`stream.pipeline` API](https://nodejs.org/docs/latest-v18.x/api/stream.html#streampipelinesource-transforms-destination-options) that with `stream/promises` utilizes promises. This way you can utilize the advantages of the streaming API (namely no file size limit) in conjunction with the convenience of using a modern promise based API:

```js
import { minifyPipeline as minifyXMLPipeline } from "minify-xml";

await minifyXMLPipeline(fs.createReadStream("catalogue.xml", "utf8"), process.stdout, { end: false });
```

## Options

You may pass in the following options when calling minify:
Expand Down
4 changes: 4 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,10 @@ export function minifyStream(options) {
}
};

import { pipeline } from "node:stream/promises";
export const minifyPipeline = async (source, destination, options) =>
await pipeline(source, minifyStream(options), destination, { end: options?.end });

export function debug(xml, options) {
xml && console.log(`\x1b[90m${xml}\x1b[0m`);

Expand Down
6 changes: 3 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "minify-xml",
"version": "4.2.0",
"version": "4.3.0",
"description": "Fast XML minifier / compressor / uglifier with a command-line",
"keywords": [
"XML",
Expand Down
27 changes: 22 additions & 5 deletions test.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,17 @@ import { readFileSync, promises as fs, createReadStream } from "node:fs";
const exists = path => fs.access(path).then(() => true).catch(() => false);

import { execa } from "execa";
import { Readable } from "node:stream";
import { Readable, Writable } from "node:stream";
const newWritableStream = () => new Writable({
write(chunk, encoding, callback) {
(this.chunks ?? (this.chunks = [])).push(Buffer.from(chunk));
callback();
},
final(callback) {
this.emit("end");
callback();
}
});
import { text as getStream } from "node:stream/consumers";

import { fileURLToPath } from "node:url";
Expand All @@ -17,7 +27,7 @@ const cliPath = path.join(dirname, "cli.js"), cli = async (...options) =>
import { withFile } from "tmp-promise";
const xml = readFileSync(xmlPath, "utf8");

import { default as minify, defaultOptions, minifyStream, defaultStreamOptions } from "./index.js";
import { default as minify, defaultOptions, minifyStream, defaultStreamOptions, minifyPipeline } from "./index.js";
const minifiedXml = minify(xml), minifiedStreamXml = minify(xml, defaultStreamOptions);

glob.sync("test/*/").forEach(dir => {
Expand All @@ -34,10 +44,17 @@ glob.sync("test/*/").forEach(dir => {

// minify in.xml with streamOptions.json (or options.json / default options) as a stream and expect stream.xml
if (await exists(path.join(dir, "stream.xml"))) {
t.is(await getStream(createReadStream(path.join(dir, "in.xml"), "utf8").pipe(minifyStream(streamOptions))),
await fs.readFile(path.join(dir, "stream.xml"), "utf8"));
const stream = () => createReadStream(path.join(dir, "in.xml"), "utf8"),
expected = await fs.readFile(path.join(dir, "stream.xml"), "utf8");
t.is(await getStream(stream().pipe(minifyStream(streamOptions))), expected);

const writeStream = newWritableStream();
await minifyPipeline(stream(), writeStream, streamOptions);
t.is(Buffer.concat(writeStream.chunks ?? []).toString("utf8"), expected);
} else {
t.throws(() => minifyStream(options), { message: /cannot be used with streams/ });
const expected = { message: /cannot be used with streams/ };
t.throws(() => minifyStream(streamOptions), expected);
await t.throwsAsync(async () => await minifyPipeline(undefined, undefined, streamOptions), expected)
}
});
});
Expand Down

0 comments on commit 385a14e

Please sign in to comment.