fix(dev): consolidate generated cache directories
Quality / quality (ubuntu-latest) (push) Failing after 9m50s
Quality / quality (windows-latest) (push) Canceled after 0s

This commit is contained in:
2026-08-12 22:25:12 +05:30
parent e638c6be6a
commit b508b49058
8 changed files with 28 additions and 13 deletions
+2 -2
View File
@@ -268,7 +268,7 @@
}, },
"packages/cli": { "packages/cli": {
"name": "@wrnexus/cli", "name": "@wrnexus/cli",
"version": "0.8.30", "version": "0.8.31",
"bin": { "bin": {
"wrnexus": "src/index.ts", "wrnexus": "src/index.ts",
}, },
@@ -332,7 +332,7 @@
}, },
"packages/dev-server": { "packages/dev-server": {
"name": "@wrnexus/dev-server", "name": "@wrnexus/dev-server",
"version": "0.8.28", "version": "0.8.29",
"dependencies": { "dependencies": {
"@wrnexus/authz": "workspace:*", "@wrnexus/authz": "workspace:*",
"@wrnexus/cache": "workspace:*", "@wrnexus/cache": "workspace:*",
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "@wrnexus/cli", "name": "@wrnexus/cli",
"version": "0.8.30", "version": "0.8.31",
"type": "module", "type": "module",
"main": "src/index.ts", "main": "src/index.ts",
"exports": { "exports": {
+1
View File
@@ -540,6 +540,7 @@ export async function runGateway(root: string, args: string[]): Promise<void> {
const hostname = hostArg?.split("=")[1] ?? environmentConfig.hostname; const hostname = hostArg?.split("=")[1] ?? environmentConfig.hostname;
// The published CLI bundle carries the matching gateway/cache lifecycle.
const { startGateway } = await import("@wrnexus/dev-server"); const { startGateway } = await import("@wrnexus/dev-server");
await startGateway({ await startGateway({
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "@wrnexus/dev-server", "name": "@wrnexus/dev-server",
"version": "0.8.28", "version": "0.8.29",
"type": "module", "type": "module",
"main": "src/index.ts", "main": "src/index.ts",
"exports": { "exports": {
+17 -2
View File
@@ -1,5 +1,5 @@
import { existsSync, rmSync } from "node:fs"; import { existsSync, readdirSync, rmSync } from "node:fs";
import { resolve } from "node:path"; import { join, resolve } from "node:path";
export interface ResetDevCacheOptions { export interface ResetDevCacheOptions {
rootDir?: string; rootDir?: string;
@@ -7,6 +7,19 @@ export interface ResetDevCacheOptions {
enabled?: boolean; enabled?: boolean;
} }
function removeLegacyProcessCaches(rootDir: string): void {
if (!existsSync(rootDir)) return;
for (const entry of readdirSync(rootDir, { withFileTypes: true })) {
if (!entry.isDirectory() || !/^\.wrnexus-\d+$/.test(entry.name)) continue;
rmSync(join(rootDir, entry.name), {
recursive: true,
force: true,
maxRetries: 3,
retryDelay: 100,
});
}
}
export function resetDevCache(options: ResetDevCacheOptions = {}): string { export function resetDevCache(options: ResetDevCacheOptions = {}): string {
const rootDir = resolve(options.rootDir ?? process.cwd()); const rootDir = resolve(options.rootDir ?? process.cwd());
@@ -16,6 +29,8 @@ export function resetDevCache(options: ResetDevCacheOptions = {}): string {
return cacheDir; return cacheDir;
} }
removeLegacyProcessCaches(rootDir);
// Safety: never allow deleting the project root. // Safety: never allow deleting the project root.
if (cacheDir === rootDir) { if (cacheDir === rootDir) {
throw new Error("Refusing to remove the project root as the WRNexus cache directory."); throw new Error("Refusing to remove the project root as the WRNexus cache directory.");
+3 -4
View File
@@ -288,10 +288,9 @@ export async function startServer(opts: ServeOptions): Promise<RunningServer> {
const pluginContributions = await pluginRunner.contributions(); const pluginContributions = await pluginRunner.contributions();
const virtualModules = new Map<string, string>(); const virtualModules = new Map<string, string>();
// A live dev server and a test process can share an app root. Keeping the // Keep generated artifacts under the single framework state directory.
// generated artifacts in a process-specific directory prevents a test boot // Startup clears this cache and removes legacy PID-suffixed cache folders.
// from deleting the running server's client modules. const cacheDir = join(appRoot, ".wrnexus", "cache");
const cacheDir = join(appRoot, `.wrnexus-${process.pid}`);
const virtualDir = join(cacheDir, "virtual"); const virtualDir = join(cacheDir, "virtual");
mkdirSync(virtualDir, { recursive: true }); mkdirSync(virtualDir, { recursive: true });
for (const [index, module] of pluginContributions.virtualModules.entries()) { for (const [index, module] of pluginContributions.virtualModules.entries()) {
@@ -63,14 +63,14 @@ export default defineAuthz({ permissions: { "post:read": { title: "View posts" }
try { try {
expect(hasAuthzCatalog()).toBe(true); expect(hasAuthzCatalog()).toBe(true);
expect(getAuthzCatalog().permissions.has("post:read")).toBe(true); expect(getAuthzCatalog().permissions.has("post:read")).toBe(true);
const cacheDir = join(appDir, "..", `.wrnexus-${process.pid}`); const cacheDir = join(appDir, "..", ".wrnexus", "cache");
mkdirSync(cacheDir, { recursive: true }); mkdirSync(cacheDir, { recursive: true });
writeFileSync(join(cacheDir, "generated.js"), "generated", "utf8"); writeFileSync(join(cacheDir, "generated.js"), "generated", "utf8");
expect(existsSync(cacheDir)).toBe(true); expect(existsSync(cacheDir)).toBe(true);
} finally { } finally {
server.stop(); server.stop();
} }
expect(existsSync(join(appDir, "..", `.wrnexus-${process.pid}`))).toBe(false); expect(existsSync(join(appDir, "..", ".wrnexus", "cache"))).toBe(false);
}); });
test("an app with no app/authz declarations boots without throwing", async () => { test("an app with no app/authz declarations boots without throwing", async () => {
@@ -18,7 +18,7 @@ test("per-process dev caches are excluded from root and example project tools",
const projects = ["basic-app", "inter-app-api-showcase"].map((name) => const projects = ["basic-app", "inter-app-api-showcase"].map((name) =>
join(root, "examples", name), join(root, "examples", name),
); );
const caches = projects.map((project) => join(project, ".wrnexus-123")); const caches = projects.map((project) => join(project, ".wrnexus", "cache"));
for (const project of projects) { for (const project of projects) {
const projectEslint = readFileSync(join(project, "eslint.config.js"), "utf8"); const projectEslint = readFileSync(join(project, "eslint.config.js"), "utf8");