mirror of
https://github.com/vercel-labs/scriptc.git
synced 2026-11-01 07:33:12 +08:00
fs.watchFile(path[, options], listener) polls the resolved path every `interval` milliseconds (5007 by default, `persistent` by default) and calls its listener with (current, previous) Stats when a poll sees a difference. The first poll only records the baseline, a path that cannot be stat'd polls as all-zero Stats, and a stat failure that repeats for the same errno is not re-reported. One poller per RESOLVED path is shared by every listener on it, and fs.unwatchFile(path[, listener]) removes the last listener registered with that callback, or every listener when called without one. The call is a statement, since Node's StatWatcher has no lowering, and bigint: true is refused. The implementation is scr_watch_file.c, a new gated runtime unit switched by moduleUsesFsWatchFile, so programs that do not poll link none of it. The feature travels the usual chain (runtime-features, executable-features, the native link info, the executable cache keys, the runtime-pack matrix) and the validator learns that fs.unwatchFile's trailing listener slot may be omitted. Evidence: - tests/corpus/fs-watch-file-names.ts and fs-watch-file-polling.ts match Node on stdout, stderr and exit status in the plain and sanitized lanes - 1564-fs-watch.ts, 1751-options-record-stance.ts and the `fs` corpus stay green; the new order baselines and corpus cost files are recorded Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
85 lines
2.8 KiB
TypeScript
85 lines
2.8 KiB
TypeScript
import { buildCacheRoot, prepareBuildCacheRoot } from "./build-cache.js";
|
|
import { loadRuntimePack } from "./runtime-pack.js";
|
|
import { nativeCodegenTarget, nativeCodegenTargetRefusal } from "./targets.js";
|
|
import {
|
|
warmNativeCaches as warmDevelopmentRuntime,
|
|
type NativeCacheWarmProfile,
|
|
type WarmNativeCachesOptions,
|
|
type WarmNativeCachesResult,
|
|
} from "./native/cache-warm.js";
|
|
|
|
/** Verify and read the installed runtime families before the first build. */
|
|
export async function warmNativeCaches(
|
|
options: WarmNativeCachesOptions = {},
|
|
): Promise<WarmNativeCachesResult> {
|
|
if (options.sanitize) return warmDevelopmentRuntime(options);
|
|
const cacheRoot = await prepareBuildCacheRoot(buildCacheRoot());
|
|
if (cacheRoot === null) throw new Error("the native build cache is disabled or unavailable");
|
|
const known = new Set<NativeCacheWarmProfile>(["runtime", "tls"]);
|
|
for (const profile of options.profiles ?? [])
|
|
if (!known.has(profile)) throw new Error(`unknown native cache warm profile '${profile}'`);
|
|
const target = nativeCodegenTarget();
|
|
if (target === null)
|
|
throw new Error(nativeCodegenTargetRefusal() ?? "unsupported runtime-pack target");
|
|
if (!target.supports.exe)
|
|
throw new Error(
|
|
`native cache warming requires an executable target; ${target.name} supports library archives`,
|
|
);
|
|
const profiles = [...new Set(options.profiles ?? (["runtime", "tls"] as const))];
|
|
const results = [];
|
|
for (const profile of profiles) {
|
|
const started = performance.now();
|
|
await loadRuntimePack({
|
|
target,
|
|
optimization: options.optimization ?? "release",
|
|
features: {
|
|
fetch: profile === "tls",
|
|
regex: false,
|
|
copying: false,
|
|
textDecoderLegacy: false,
|
|
fileHandle: false,
|
|
zlib: false,
|
|
assert: false,
|
|
inspect: false,
|
|
dynInvoke: false,
|
|
dc: false,
|
|
dynAsync: false,
|
|
events: false,
|
|
emitter: false,
|
|
symbol: false,
|
|
bigint: false,
|
|
searchParams: false,
|
|
qs: false,
|
|
utilPromisify: false,
|
|
dynBuiltinClass: false,
|
|
dynBuiltinStream: false,
|
|
parseArgs: false,
|
|
stream: false,
|
|
net: false,
|
|
http: false,
|
|
http2: false,
|
|
dgram: false,
|
|
dnsPromises: false,
|
|
dgramDyn: false,
|
|
textCodecDyn: false,
|
|
watch: false,
|
|
watchFile: false,
|
|
foreignFfi: false,
|
|
nodeTest: false,
|
|
tls: false,
|
|
cipher: false,
|
|
ecdh: false,
|
|
dh: false,
|
|
pki: false,
|
|
ed25519: false,
|
|
x509: false,
|
|
webcrypto: false,
|
|
perfLoop: false,
|
|
tlsCa: false,
|
|
},
|
|
});
|
|
results.push({ profile, elapsedMs: Math.round((performance.now() - started) * 10) / 10 });
|
|
}
|
|
return { cacheRoot, profiles: results };
|
|
}
|