mirror of
https://github.com/SukkaW/Surge.git
synced 2026-09-12 18:44:36 +08:00
Chore: dispatch write to workers
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import { fastStringArrayJoin } from 'foxts/fast-string-array-join';
|
||||
import fs from 'node:fs';
|
||||
import path from 'node:path';
|
||||
import picocolors from 'picocolors';
|
||||
import type { Span } from '../trace';
|
||||
import { readFileByLine } from './fetch-text-by-line';
|
||||
@@ -10,16 +11,12 @@ import { extractContentHashFromFile } from './content-hash';
|
||||
const fileEqual = createCompareSource(fileEqualWithCommentComparator);
|
||||
|
||||
/**
|
||||
* To keep metadata comment `last updated` not change if real content is the same,
|
||||
* we only write when the actual content differs, and the new `last updated` will
|
||||
* be written along with new content.
|
||||
*
|
||||
* When `contentHash` is provided (and the previous output already embeds a
|
||||
* content hash marker), the comparison only reads the first chunk of the
|
||||
* previous file. Otherwise it falls back to a full comment-insensitive
|
||||
* line-by-line comparison.
|
||||
* The comparison half shared by {@link compareAndWriteFile} and
|
||||
* {@link compareAndWriteFileInWorker} -- there is exactly one implementation of
|
||||
* "is the previous output already up to date", regardless of how the new content
|
||||
* ends up being written.
|
||||
*/
|
||||
export async function compareAndWriteFile(span: Span, linesA: string[], filePath: string, contentHash: string | null = null) {
|
||||
async function isPreviousOutputEqual(span: Span, linesA: string[], filePath: string, contentHash: string | null) {
|
||||
// readFileByLine will not include last empty line. So we always pop the linesA for comparison purpose
|
||||
if (linesA.length > 0 && linesA[linesA.length - 1] === '') {
|
||||
linesA.pop();
|
||||
@@ -44,15 +41,53 @@ export async function compareAndWriteFile(span: Span, linesA: string[], filePath
|
||||
|
||||
if (isEqual) {
|
||||
console.log(picocolors.gray(picocolors.dim(`same content, bail out writing: ${filePath}`)));
|
||||
}
|
||||
|
||||
return isEqual;
|
||||
}
|
||||
|
||||
/**
|
||||
* To keep metadata comment `last updated` not change if real content is the same,
|
||||
* we only write when the actual content differs, and the new `last updated` will
|
||||
* be written along with new content.
|
||||
*
|
||||
* When `contentHash` is provided (and the previous output already embeds a
|
||||
* content hash marker), the comparison only reads the first chunk of the
|
||||
* previous file. Otherwise it falls back to a full comment-insensitive
|
||||
* line-by-line comparison.
|
||||
*/
|
||||
export async function compareAndWriteFile(span: Span, linesA: string[], filePath: string, contentHash: string | null = null) {
|
||||
if (await isPreviousOutputEqual(span, linesA, filePath, contentHash)) {
|
||||
return;
|
||||
}
|
||||
|
||||
return writeFileLines(span, linesA, filePath);
|
||||
}
|
||||
|
||||
/**
|
||||
* Same comparison as {@link compareAndWriteFile}, but the write itself is
|
||||
* synchronous. For worker threads only: blocking a dedicated worker is free,
|
||||
* whereas an async write hands the completion back through libuv to an event
|
||||
* loop we would rather not depend on being idle.
|
||||
*/
|
||||
export async function compareAndWriteFileInWorker(span: Span, linesA: string[], filePath: string, contentHash: string | null = null) {
|
||||
if (await isPreviousOutputEqual(span, linesA, filePath, contentHash)) {
|
||||
return;
|
||||
}
|
||||
|
||||
writeFileLinesSync(span, linesA, filePath);
|
||||
}
|
||||
|
||||
export function writeFileLines(span: Span, linesA: string[], filePath: string): Promise<void> {
|
||||
return span.traceChildAsync<void>(
|
||||
`writing ${filePath}`,
|
||||
() => writeFile(filePath, fastStringArrayJoin(linesA, '\n') + '\n')
|
||||
);
|
||||
}
|
||||
|
||||
export function writeFileLinesSync(span: Span, linesA: string[], filePath: string): void {
|
||||
span.traceChildSync(`writing ${filePath}`, () => {
|
||||
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
||||
fs.writeFileSync(filePath, fastStringArrayJoin(linesA, '\n') + '\n');
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user