Skip to content

Commit 5bb5e45

Browse files
committed
refactor(fmt): inline cache hashing
1 parent b023c32 commit 5bb5e45

7 files changed

Lines changed: 37 additions & 29 deletions

File tree

‎packages/rstack/src/fmt/cacheHash.ts‎

Lines changed: 0 additions & 9 deletions
This file was deleted.

‎packages/rstack/src/fmt/cacheIdentity.ts‎

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1+
import { hash as createDigest } from 'node:crypto';
12
import { isAbsolute } from 'node:path';
23
import stableStringify from 'fast-json-stable-stringify';
3-
import { createCacheHash } from './cacheHash.ts';
44
import { fmtCacheVersion } from './cacheStore.ts';
55
import { createRelativePathResolver, toPosixPath } from './pathHelpers.ts';
66
import type { ResolvedFmtOptions } from './types.ts';
@@ -12,6 +12,10 @@ type CacheKeyResolver = (filePath: string) => string | undefined;
1212
type OptionsHasher = (options: ResolvedFmtOptions) => string | undefined;
1313
type PluginFingerprints = ReadonlyMap<string, string>;
1414

15+
const cacheHashLength = 16;
16+
const createCacheHash = (content: string | Uint8Array): string =>
17+
createDigest('sha256', content, 'base64url').slice(0, cacheHashLength);
18+
1519
/** Identifies formatter behavior shared by all cache entries in this process. */
1620
const cacheNamespace: string = JSON.stringify([fmtCacheVersion, RSTACK_VERSION, PRETTIER_VERSION]);
1721

@@ -63,4 +67,10 @@ const createOptionsHasher = (pluginFingerprints?: PluginFingerprints): OptionsHa
6367
};
6468
};
6569

66-
export { cacheNamespace, createCacheKeyResolver, createOptionsHasher };
70+
export {
71+
cacheHashLength,
72+
cacheNamespace,
73+
createCacheHash,
74+
createCacheKeyResolver,
75+
createOptionsHasher,
76+
};

‎packages/rstack/src/fmt/worker.ts‎

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// Derived from @prettier/cli, see THIRD_PARTY_NOTICES.md
22

3+
import { hash } from 'node:crypto';
34
import { readFileSync, writeFileSync } from 'node:fs';
4-
import { createCacheHash } from './cacheHash.ts';
55
import type { FmtCacheEntry } from './cacheStore.ts';
66
import { hasDottedBasename } from './pathHelpers.ts';
77
import type { FmtFileCache, FmtFileRequest, FmtWorkerResult } from './types.ts';
@@ -12,6 +12,9 @@ interface FormatFileTask {
1212
cache?: FmtFileCache;
1313
}
1414

15+
const hashContent = (content: string | Uint8Array): string =>
16+
hash('sha256', content, 'base64url').slice(0, 16);
17+
1518
/**
1619
* Use synchronous direct I/O inside the dedicated worker to avoid libuv
1720
* scheduling overhead. This prioritizes throughput over crash-safe replacement.
@@ -35,7 +38,7 @@ const formatFile = async ({
3538
}
3639

3740
sourceBuffer = readFileSync(file.path);
38-
contentHash = createCacheHash(sourceBuffer);
41+
contentHash = hashContent(sourceBuffer);
3942
return sourceBuffer.toString('utf8');
4043
};
4144

@@ -48,14 +51,14 @@ const formatFile = async ({
4851
}
4952
} else {
5053
sourceBuffer = readFileSync(file.path);
51-
contentHash = createCacheHash(sourceBuffer);
54+
contentHash = hashContent(sourceBuffer);
5255
if (entry[0] === contentHash) {
5356
return { status: 'unsupported' };
5457
}
5558
}
5659
} else {
5760
sourceBuffer = readFileSync(file.path);
58-
contentHash = createCacheHash(sourceBuffer);
61+
contentHash = hashContent(sourceBuffer);
5962
if (entry[0] === contentHash && (!shouldWrite || entry[2] === 'clean')) {
6063
return { status: entry[2] === 'clean' ? 'unchanged' : 'changed' };
6164
}
@@ -71,7 +74,7 @@ const formatFile = async ({
7174
cacheEntry: [
7275
hasDottedBasename(file.path)
7376
? ''
74-
: (contentHash ?? createCacheHash(sourceBuffer ?? readFileSync(file.path))),
77+
: (contentHash ?? hashContent(sourceBuffer ?? readFileSync(file.path))),
7578
cache.optionsHash,
7679
'unsupported',
7780
],
@@ -92,8 +95,8 @@ const formatFile = async ({
9295

9396
const cacheHash =
9497
shouldWrite && !unchanged
95-
? createCacheHash(result.formatted)
96-
: (contentHash ?? createCacheHash(result.source));
98+
? hashContent(result.formatted)
99+
: (contentHash ?? hashContent(result.source));
97100
const cacheEntry: FmtCacheEntry = [
98101
cacheHash,
99102
cache.optionsHash,

‎packages/rstack/tests/fmt/cacheIdentity.test.ts‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,10 @@ import { pathToFileURL } from 'node:url';
33
import prettierPkgJson from 'prettier/package.json' with { type: 'json' };
44
import { expect, test } from 'rstack/test';
55
import pkgJson from '../../package.json' with { type: 'json' };
6-
import { cacheHashLength, createCacheHash } from '../../src/fmt/cacheHash.ts';
76
import {
7+
cacheHashLength,
88
cacheNamespace,
9+
createCacheHash,
910
createCacheKeyResolver,
1011
createOptionsHasher,
1112
} from '../../src/fmt/cacheIdentity.ts';

‎packages/rstack/tests/fmt/cacheStore.test.ts‎

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import { existsSync, mkdirSync, readFileSync, readdirSync, writeFileSync } from 'node:fs';
22
import path from 'node:path';
33
import { expect, test } from 'rstack/test';
4-
import { createCacheHash } from '../../src/fmt/cacheHash.ts';
54
import {
65
fmtCacheFileName,
76
fmtCacheVersion,
@@ -11,12 +10,12 @@ import {
1110
import { withTempProject } from './helpers.ts';
1211

1312
const namespace = 'test-namespace';
14-
const contentA = createCacheHash('content-a');
15-
const contentB = createCacheHash('content-b');
16-
const contentC = createCacheHash('content-c');
17-
const optionsA = createCacheHash('options-a');
18-
const optionsB = createCacheHash('options-b');
19-
const optionsC = createCacheHash('options-c');
13+
const contentA = 'content-a';
14+
const contentB = 'content-b';
15+
const contentC = 'content-c';
16+
const optionsA = 'options-a';
17+
const optionsB = 'options-b';
18+
const optionsC = 'options-c';
2019
const firstEntry = [contentA, optionsA, 'clean'] as const;
2120
const secondEntry = [contentB, optionsB, 'dirty'] as const;
2221
const unsupportedEntry = ['', optionsC, 'unsupported'] as const;

‎packages/rstack/tests/fmt/runnerCache.test.ts‎

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,12 @@ import { readFileSync, statSync, utimesSync, writeFileSync } from 'node:fs';
22
import path from 'node:path';
33
import { pathToFileURL } from 'node:url';
44
import { expect, test } from 'rstack/test';
5-
import { cacheHashLength, createCacheHash } from '../../src/fmt/cacheHash.ts';
6-
import { cacheNamespace, createOptionsHasher } from '../../src/fmt/cacheIdentity.ts';
5+
import {
6+
cacheHashLength,
7+
cacheNamespace,
8+
createCacheHash,
9+
createOptionsHasher,
10+
} from '../../src/fmt/cacheIdentity.ts';
711
import { loadFmtCacheStore } from '../../src/fmt/cacheStore.ts';
812
import { runFmtFiles } from '../../src/fmt/runner.ts';
913
import type { FmtCacheContext, FmtFileRequest, FmtMode } from '../../src/fmt/types.ts';

‎packages/rstack/tests/fmt/worker.test.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import path from 'node:path';
22
import { readFileSync } from 'node:fs';
33
import { expect, test } from 'rstack/test';
4-
import { createCacheHash } from '../../src/fmt/cacheHash.ts';
4+
import { createCacheHash } from '../../src/fmt/cacheIdentity.ts';
55
import { formatFile } from '../../src/fmt/worker.ts';
66
import { withTempProject, writeProjectFile } from './helpers.ts';
77

0 commit comments

Comments
 (0)