Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion packages/cli/src/server/fileWatcher.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,14 @@ describe("shouldWatchProjectFile", () => {
expect(shouldWatchProjectFile("Dockerfile")).toBe(true);
});

it("skips generated and dependency directories excluded from signatures", () => {
it("skips generated and dependency directories", () => {
expect(shouldWatchProjectFile("node_modules/pkg/index.js")).toBe(false);
expect(shouldWatchProjectFile("renders/output.mp4")).toBe(false);
expect(shouldWatchProjectFile("dist/index.html")).toBe(false);
expect(shouldWatchProjectFile(".hyperframes/cache.json")).toBe(false);
expect(shouldWatchProjectFile(".transcode-cache/proxy.mp4")).toBe(false);
expect(shouldWatchProjectFile(".thumbnails/frame.jpg")).toBe(false);
expect(shouldWatchProjectFile(".waveform-cache/peaks.json")).toBe(false);
});
});

Expand Down
3 changes: 3 additions & 0 deletions packages/cli/src/server/fileWatcher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@ const WATCHER_EXCLUDED_DIRS = new Set([
".git",
".hyperframes",
".next",
".thumbnails",
".transcode-cache",
".vite",
".waveform-cache",
"build",
"coverage",
"dist",
Expand Down
3 changes: 3 additions & 0 deletions packages/studio-server/src/helpers/projectSignature.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,10 @@ const SIGNATURE_EXCLUDED_DIRS = new Set([
".git",
".hyperframes",
".next",
".thumbnails",
".transcode-cache",
".vite",
".waveform-cache",
"build",
"coverage",
"dist",
Expand Down
8 changes: 7 additions & 1 deletion packages/studio-server/src/helpers/safePath.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,13 @@ import { readdirSync } from "node:fs";
// Re-exported here for back-compat with existing `../helpers/safePath.js` imports.
export { isSafePath, resolveWithinProject } from "@hyperframes/core";

const IGNORE_DIRS = new Set([".thumbnails", "node_modules", ".git"]);
const IGNORE_DIRS = new Set([
".thumbnails",
".transcode-cache",
".waveform-cache",
"node_modules",
".git",
]);

function shouldIgnoreDir(rel: string): boolean {
return rel === ".hyperframes/backup";
Expand Down
47 changes: 47 additions & 0 deletions packages/studio-server/src/routes/projects.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,37 @@ describe("GET /projects/:id/signature", () => {
expect(second.signature).not.toBe(first.signature);
});

it("ignores generated cache writes while detecting source edits", async () => {
const projectDir = createProjectDir();
const app = new Hono();
registerProjectRoutes(app, createAdapter(projectDir));
const getSignature = async () =>
(
(await (await app.request("http://localhost/projects/demo/signature")).json()) as {
signature: string;
}
).signature;

const initial = await getSignature();
const generatedFiles = [
[".transcode-cache", "proxy.mp4"],
[".thumbnails", "frame.jpg"],
[".waveform-cache", "peaks.json"],
] as const;
const generatedSignatures: string[] = [];
for (const [dir, file] of generatedFiles) {
mkdirSync(join(projectDir, dir));
writeFileSync(join(projectDir, dir, file), `generated ${dir}`);
generatedSignatures.push(await getSignature());
}

expect(generatedSignatures).toEqual([initial, initial, initial]);

mkdirSync(join(projectDir, "src"));
writeFileSync(join(projectDir, "src", "scene.ts"), "export const scene = true;");
expect(await getSignature()).not.toBe(initial);
});

it("404s for an unknown project", async () => {
const app = new Hono();
registerProjectRoutes(app, {
Expand Down Expand Up @@ -132,4 +163,20 @@ describe("registerProjectRoutes — composition discovery (#1384)", () => {
// Only Studio's own backup snapshots are hidden from the tree (#1366).
expect(payload.files).not.toContain(".hyperframes/backup/snapshot.html");
});

it("omits generated cache files from the project file tree", async () => {
const projectDir = createProjectDir();
mkdirSync(join(projectDir, ".transcode-cache"));
writeFileSync(join(projectDir, ".transcode-cache", "proxy.mp4"), "proxy");
mkdirSync(join(projectDir, ".waveform-cache"));
writeFileSync(join(projectDir, ".waveform-cache", "peaks.json"), "[]");
const app = new Hono();
registerProjectRoutes(app, createAdapter(projectDir));

const response = await app.request("http://localhost/projects/demo");
const payload = (await response.json()) as { files?: string[] };

expect(payload.files).not.toContain(".transcode-cache/proxy.mp4");
expect(payload.files).not.toContain(".waveform-cache/peaks.json");
});
});
Loading