From f7b6e051801e9d6ece212f59498468f0b60d32b1 Mon Sep 17 00:00:00 2001 From: MDLeom <43627182+curbengh@users.noreply.github.com> Date: Fri, 1 Aug 2025 10:18:46 +0000 Subject: [PATCH 1/3] chore(node): requires at least Node v22.15 in preparation for native zstd support BREAKING CHANGE drop Node v20 --- .github/workflows/tester.yml | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/tester.yml b/.github/workflows/tester.yml index 9db94b1..82cfc4f 100644 --- a/.github/workflows/tester.yml +++ b/.github/workflows/tester.yml @@ -8,7 +8,7 @@ jobs: strategy: matrix: os: [ubuntu-latest, windows-latest, macos-latest] - node-version: ["20", "22", "24"] + node-version: ["22", "24"] fail-fast: false steps: - uses: actions/checkout@v4 diff --git a/package.json b/package.json index a483083..9953ccc 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,7 @@ "test": "jest" }, "engines": { - "node": ">= 20.9.0" + "node": ">= 22.15.0" }, "author": "curben", "license": "MIT", From 2cd5786e86bd498bd8da8796917ba97972ffff35 Mon Sep 17 00:00:00 2001 From: MDLeom <43627182+curbengh@users.noreply.github.com> Date: Fri, 1 Aug 2025 10:51:23 +0000 Subject: [PATCH 2/3] feat: native zstd fixes #160 closes #162 --- README.md | 2 +- lib/filter.js | 7 +++---- package.json | 3 +-- test/zstd.test.js | 12 +++++++----- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 46f0d6c..1276128 100644 --- a/README.md +++ b/README.md @@ -266,7 +266,7 @@ minify: - **verbose** - Verbose output. Defaults to `false`. - **include** - Include files. Support [wildcard](http://www.globtester.com/) pattern(s) in a string or array. - **globOptions** - See [globbing](#globbing) section. -- **level** - Compression level. Range `1-22`. Defaults to `3`, or the value of [`DEFAULT_LEVEL`](https://github.com/mongodb-js/zstd/blob/a3a08c61c9045411c8275e248498dbc583457fb5/src/lib.rs#L9) +- **level** - Compression level. Range `1-22`. Defaults to `3`, or the value of [`ZSTD_CLEVEL_DEFAULT`](https://nodejs.org/api/zlib.html#zlib_compressor_options_1) ## Globbing diff --git a/lib/filter.js b/lib/filter.js index 0d17003..1fc0c79 100644 --- a/lib/filter.js +++ b/lib/filter.js @@ -8,9 +8,9 @@ const zlib = require('zlib') const { promisify } = require('util') const gzip = promisify(zlib.gzip) const br = promisify(zlib.brotliCompress) +const zstd = promisify(zlib.zstdCompress) const { minify: compressXml } = require('minify-xml') const micromatch = require('micromatch') -const { compress: zstd } = require('@mongodb-js/zstd') const isMatch = (path = '', patterns = [], options = {}) => { if (path && patterns) { @@ -240,7 +240,7 @@ function zstdFn () { const routeList = route.list() const { globOptions, include, verbose } = options let { level } = options - if (typeof level !== 'number') level = undefined + if (typeof level !== 'number') level = zlib.constants.ZSTD_CLEVEL_DEFAULT return Promise.all((match(routeList, include, globOptions)).map((path) => { return new Promise((resolve, reject) => { @@ -250,8 +250,7 @@ function zstdFn () { assetPath.on('end', async () => { if (assetTxt.length) { try { - const input = Buffer.from(assetTxt, 'utf-8') - const result = await zstd(input, level) + const result = await zstd(assetTxt, { params: { [zlib.constants.ZSTD_c_compressionLevel]: level } }) if (verbose) logFn.call(this, assetTxt, result, path, 'zstd') resolve(route.set(path + '.zst', result)) } catch (err) { diff --git a/package.json b/package.json index 9953ccc..18ef52b 100644 --- a/package.json +++ b/package.json @@ -31,8 +31,7 @@ "micromatch": "^4.0.2", "minify-xml": "^3.2.0", "svgo": "^4.0.0", - "terser": "^5.3.0", - "@mongodb-js/zstd": "^2.0.1" + "terser": "^5.3.0" }, "devDependencies": { "hexo": "^7.1.0", diff --git a/test/zstd.test.js b/test/zstd.test.js index c6e236e..89995e0 100644 --- a/test/zstd.test.js +++ b/test/zstd.test.js @@ -2,14 +2,16 @@ 'use strict' const Hexo = require('hexo') -const { compress: zstd, decompress: unzstd } = require('@mongodb-js/zstd') +const zlib = require('zlib') +const { promisify } = require('util') +const zstd = promisify(zlib.zstdCompress) +const unzstd = promisify(zlib.zstdDecompress) describe('zstd', () => { const hexo = new Hexo(__dirname) const z = require('../lib/filter').zstdFn.bind(hexo) const path = 'foo.txt' const input = 'Lorem ipsum dolor sit amet consectetur adipiscing elit fusce' - const inputBuf = Buffer.from(input, 'utf8') beforeEach(() => { hexo.config.minify = { @@ -36,7 +38,7 @@ describe('zstd', () => { output.on('data', (chunk) => (buf.push(chunk))) output.on('end', async () => { const result = Buffer.concat(buf) - const expected = await zstd(inputBuf) + const expected = await zstd(input) const resultUnzst = await unzstd(result) const expectedUnzst = await unzstd(expected) @@ -74,7 +76,7 @@ describe('zstd', () => { output.on('data', (chunk) => (buf.push(chunk))) output.on('end', async () => { const result = Buffer.concat(buf) - const expected = await zstd(inputBuf, level) + const expected = await zstd(input, { params: { [zlib.constants.ZSTD_c_compressionLevel]: level } }) expect(result.equals(expected)).toBe(true) }) @@ -98,7 +100,7 @@ describe('zstd', () => { output.on('data', (chunk) => (buf.push(chunk))) output.on('end', async () => { const result = Buffer.concat(buf) - const expected = await zstd(inputBuf, undefined) + const expected = await zstd(input, { params: { [zlib.constants.ZSTD_c_compressionLevel]: zlib.constants.ZSTD_CLEVEL_DEFAULT } }) expect(result.equals(expected)).toBe(true) }) From 5deaab2a11a7f130eedcf8589f7b77dfe6d3aa08 Mon Sep 17 00:00:00 2001 From: MDLeom <43627182+curbengh@users.noreply.github.com> Date: Mon, 4 Aug 2025 12:16:04 +0000 Subject: [PATCH 3/3] feat: enable zstd by default --- README.md | 6 ++++-- index.js | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 1276128..731e309 100644 --- a/README.md +++ b/README.md @@ -41,6 +41,7 @@ minify: svg: gzip: brotli: + zstd: xml: json: ``` @@ -53,6 +54,7 @@ minify: - **svg** - See [SVG](#svg) section - **gzip** - See [Gzip](#gzip) section - **brotli** - See [Brotli](#brotli) section +- **zstd** - See [Zstd](#zstd) section - **xml** - See [XML](#xml) section - **json** - See [JSON](#json) section @@ -246,7 +248,7 @@ minify: ```yaml minify: zstd: - enable: false + enable: true include: - "*.html" - "*.css" @@ -261,7 +263,7 @@ minify: - "*.json" ``` -- **enable** - Enable the plugin. Defaults to `false`. +- **enable** - Enable the plugin. Defaults to `true`. - **priority** - Plugin's priority. Defaults to `10`. - **verbose** - Verbose output. Defaults to `false`. - **include** - Include files. Support [wildcard](http://www.globtester.com/) pattern(s) in a string or array. diff --git a/index.js b/index.js index 5294e56..340f0d7 100644 --- a/index.js +++ b/index.js @@ -70,7 +70,7 @@ hexo.config.minify.brotli = Object.assign({ }, hexo.config.minify.brotli) hexo.config.minify.zstd = Object.assign({ - enable: false, + enable: true, priority: 10, verbose: false, include: ['*.html', '*.css', '*.js', '*.txt', '*.ttf', '*.atom', '*.stl', '*.xml', '*.svg', '*.eot', '*.json'],