-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathworker.ts
More file actions
112 lines (97 loc) · 3.29 KB
/
Copy pathworker.ts
File metadata and controls
112 lines (97 loc) · 3.29 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
// Derived from @prettier/cli, see THIRD_PARTY_NOTICES.md
import { hash } from 'node:crypto';
import { readFileSync, writeFileSync } from 'node:fs';
import type { FmtCacheEntry } from './cacheStore.ts';
import { hasDottedBasename } from './pathHelpers.ts';
import type { FmtFileCache, FmtFileRequest, FmtWorkerResult } from './types.ts';
interface FormatFileTask {
file: FmtFileRequest;
shouldWrite: boolean;
cache?: FmtFileCache;
}
const hashContent = (content: string | Uint8Array): string =>
hash('sha256', content, 'base64url').slice(0, 16);
/**
* Use synchronous direct I/O inside the dedicated worker to avoid libuv
* scheduling overhead. This prioritizes throughput over crash-safe replacement.
*/
const formatFile = async ({
file,
shouldWrite,
cache,
}: FormatFileTask): Promise<FmtWorkerResult> => {
let source: string | undefined;
let sourceBuffer: Buffer | undefined;
let contentHash: string | undefined;
const readSource = (shouldHash = !shouldWrite): string => {
if (sourceBuffer !== undefined) {
return sourceBuffer.toString('utf8');
}
if (!cache || !shouldHash) {
return readFileSync(file.path, 'utf8');
}
sourceBuffer = readFileSync(file.path);
contentHash = hashContent(sourceBuffer);
return sourceBuffer.toString('utf8');
};
if (cache?.entry && cache.entry[1] === cache.optionsHash) {
const { entry } = cache;
if (entry[2] === 'unsupported') {
if (entry[0] === '') {
if (hasDottedBasename(file.path)) {
return { status: 'unsupported' };
}
} else {
sourceBuffer = readFileSync(file.path);
contentHash = hashContent(sourceBuffer);
if (entry[0] === contentHash) {
return { status: 'unsupported' };
}
}
} else {
sourceBuffer = readFileSync(file.path);
contentHash = hashContent(sourceBuffer);
if (entry[0] === contentHash && (!shouldWrite || entry[2] === 'clean')) {
return { status: entry[2] === 'clean' ? 'unchanged' : 'changed' };
}
}
}
const { formatFmtSource } = await import('./format.ts');
const result = await formatFmtSource(file, () => (source ??= readSource()));
if (result.status === 'unsupported') {
return cache
? {
status: 'unsupported',
cacheEntry: [
hasDottedBasename(file.path)
? ''
: (contentHash ??
hashContent(sourceBuffer ?? readFileSync(file.path))),
cache.optionsHash,
'unsupported',
],
}
: { status: 'unsupported' };
}
const unchanged = result.source === result.formatted;
if (!unchanged && shouldWrite) {
writeFileSync(file.path, result.formatted, 'utf8');
}
const status = unchanged ? 'unchanged' : 'changed';
if (!cache) {
return { status };
}
const cacheHash =
shouldWrite && !unchanged
? hashContent(result.formatted)
: (contentHash ?? hashContent(result.source));
const cacheEntry: FmtCacheEntry = [
cacheHash,
cache.optionsHash,
shouldWrite || unchanged ? 'clean' : 'dirty',
];
return { status, cacheEntry };
};
/** Confirms that the worker module is ready. Formatter dependencies load only on a cache miss. */
const initializeFmtWorker = (): true => true;
export { formatFile, initializeFmtWorker };