Chore: async write stream & mkdirp

This commit is contained in:
SukkaW
2024-09-15 14:06:22 +08:00
parent 49787fc664
commit e7cc9e2924
7 changed files with 60 additions and 23 deletions

View File

@@ -0,0 +1,9 @@
import type { Writable } from 'node:stream';
import { once } from 'node:events';
export const asyncWriteToStream = <T>(stream: Writable, chunk: T) => {
const res = stream.write(chunk);
if (!res) {
return once(stream, 'drain'); // returns a promise only if needed
}
};

View File

@@ -7,6 +7,7 @@ import zlib from 'node:zlib';
import process from 'node:process';
import { async as ezspawn } from '@jsdevtools/ez-spawn';
import { mkdirp } from './misc';
const mihomoBinaryDir = path.join(__dirname, '../../node_modules/.cache/mihomo');
const mihomoBinaryPath = path.join(mihomoBinaryDir, 'mihomo');
@@ -22,7 +23,7 @@ const mihomoBinaryUrl: Partial<Record<NodeJS.Platform, Partial<Record<NodeJS.Arc
};
const ensureMihomoBinary = async () => {
await fsp.mkdir(mihomoBinaryDir, { recursive: true });
await mkdirp(mihomoBinaryDir);
if (!fs.existsSync(mihomoBinaryPath)) {
const writeStream = fs.createWriteStream(mihomoBinaryPath);

View File

@@ -10,6 +10,7 @@ import stringify from 'json-stringify-pretty-compact';
import { ipCidrListToSingbox, surgeDomainsetToSingbox, surgeRulesetToSingbox } from './singbox';
import { createTrie } from './trie';
import { pack, unpackFirst, unpackSecond } from './bitwise';
import { asyncWriteToStream } from './async-write-to-stream';
export async function compareAndWriteFile(span: Span, linesA: string[], filePath: string) {
let isEqual = true;
@@ -67,17 +68,24 @@ export async function compareAndWriteFile(span: Span, linesA: string[], filePath
}
await span.traceChildAsync(`writing ${filePath}`, async () => {
// if (linesALen < 10000) {
return writeFile(filePath, fastStringArrayJoin(linesA, '\n') + '\n');
// }
// const writer = file.writer();
// The default highwater mark is normally 16384,
// So we make sure direct write to file if the content is
// most likely less than 500 lines
if (linesALen < 500) {
return writeFile(filePath, fastStringArrayJoin(linesA, '\n') + '\n');
}
// for (let i = 0; i < linesALen; i++) {
// writer.write(linesA[i]);
// writer.write('\n');
// }
// return writer.end();
const writeStream = fs.createWriteStream(filePath);
for (let i = 0; i < linesALen; i++) {
let p = asyncWriteToStream(writeStream, linesA[i]);
// eslint-disable-next-line no-await-in-loop -- stream high water mark
if (p) await p;
p = asyncWriteToStream(writeStream, '\n');
// eslint-disable-next-line no-await-in-loop -- stream high water mark
if (p) await p;
}
await asyncWriteToStream(writeStream, '\n');
writeStream.end();
});
}

View File

@@ -23,9 +23,17 @@ interface Write {
): Promise<unknown>
}
export const mkdirp = (dir: string) => {
if (fs.existsSync(dir)) {
return;
}
return fsp.mkdir(dir, { recursive: true });
};
export const writeFile: Write = async (destination: string, input, dir = dirname(destination)) => {
if (!fs.existsSync(dir)) {
await fsp.mkdir(dir, { recursive: true });
const p = mkdirp(dir);
if (p) {
await p;
}
return fsp.writeFile(destination, input, { encoding: 'utf-8' });
};