tofufirme/compress.js
2023-04-23 21:11:25 -03:00

75 lines
2.4 KiB
JavaScript

import load from "better-sqlite3";
import { createReadStream } from "node:fs";
import { readFile, readdir, rm, stat } from "node:fs/promises";
import { extname, join } from "node:path";
import { Writable } from "node:stream";
import { pipeline } from "node:stream/promises";
import { promisify } from "node:util";
// import * as brotli from "brotli";
import { brotliCompress, constants, createBrotliCompress } from "node:zlib";
const compress = promisify(brotliCompress);
const name = process.argv[2] || "./archive.sqlite3";
await rm(name, { force: true });
const db = load(name);
db.pragma("journal_mode = WAL");
db.exec("create table files(path string, content blob, compressed bool)");
db.exec("create unique index path on files(path)");
const insertStmt = db.prepare(
"insert into files(path, content, compressed) values(?, ?, ?)"
);
/**
* @param {string} parent
* @param {string} strip
*/
async function recurse(parent, strip) {
const dir = await readdir(parent, { withFileTypes: true });
await Promise.all(
dir.map(async (entry) => {
const realPath = join(parent, entry.name);
if (entry.name === "pack.js") {
debugger;
}
if (entry.isFile()) {
if (!realPath.startsWith(strip)) throw new Error("wtf");
const virtualPath = realPath.slice(strip.length);
const file = createReadStream(realPath);
const ext = extname(entry.name).toLowerCase();
if ([".html", ".css", ".js", ".svg", ".json"].includes(ext)) {
try {
const brotli = createBrotliCompress({
params: {
[constants.BROTLI_PARAM_MODE]: constants.BROTLI_MODE_TEXT,
[constants.BROTLI_PARAM_QUALITY]: 11,
[constants.BROTLI_PARAM_SIZE_HINT]: (await stat(realPath)).size,
},
});
pipeline(file, brotli);
const buffers = [];
for await (const data of brotli) {
buffers.push(data);
}
const finalBuffer = Buffer.concat(buffers);
insertStmt.run(virtualPath, finalBuffer, 1);
} catch (error) {
console.error(error);
}
} else if ([".gz", ".br"].includes(ext)) {
// nada
} else {
file.close();
insertStmt.run(virtualPath, await readFile(realPath), 0);
}
} else {
await recurse(realPath, strip);
}
})
);
}
await recurse("input/", "input");