mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-10-30 09:16:55 +00:00
fix(inspector): stop audio waveform caches from making every live question stale (#5536)
* fix(inspector): stop audio waveform caches from making every live question stale * fix(inspector): drop the comment and format the test * refactor(core): share the folders Studio's preview ignores * fix(core): register the project-folders subpath and bundle it into the inspector
This commit is contained in:
@@ -56,6 +56,12 @@
|
||||
"types": "./dist/atomicFile.d.ts",
|
||||
"environments": ["bun", "node"]
|
||||
},
|
||||
"./project-folders": {
|
||||
"source": "./src/projectFolders.ts",
|
||||
"runtime": "./dist/projectFolders.js",
|
||||
"types": "./dist/projectFolders.d.ts",
|
||||
"environments": ["bun", "node"]
|
||||
},
|
||||
"./asset-paths": {
|
||||
"source": "./src/compiler/rewriteSubCompPaths.ts",
|
||||
"runtime": "./dist/compiler/rewriteSubCompPaths.js",
|
||||
|
||||
@@ -68,6 +68,12 @@
|
||||
"import": "./src/atomicFile.ts",
|
||||
"types": "./src/atomicFile.ts"
|
||||
},
|
||||
"./project-folders": {
|
||||
"bun": "./src/projectFolders.ts",
|
||||
"node": "./dist/projectFolders.js",
|
||||
"import": "./src/projectFolders.ts",
|
||||
"types": "./src/projectFolders.ts"
|
||||
},
|
||||
"./asset-paths": {
|
||||
"bun": "./src/compiler/rewriteSubCompPaths.ts",
|
||||
"node": "./dist/compiler/rewriteSubCompPaths.js",
|
||||
@@ -564,6 +570,10 @@
|
||||
"import": "./dist/atomicFile.js",
|
||||
"types": "./dist/atomicFile.d.ts"
|
||||
},
|
||||
"./project-folders": {
|
||||
"import": "./dist/projectFolders.js",
|
||||
"types": "./dist/projectFolders.d.ts"
|
||||
},
|
||||
"./asset-paths": {
|
||||
"import": "./dist/compiler/rewriteSubCompPaths.js",
|
||||
"types": "./dist/compiler/rewriteSubCompPaths.d.ts"
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
/** Folders whose writes never reload Studio's preview, so nothing that judges a preview stale may count them. */
|
||||
export const PREVIEW_IGNORED_DIRS: ReadonlySet<string> = new Set([
|
||||
".cache",
|
||||
".git",
|
||||
".hyperframes",
|
||||
".next",
|
||||
".thumbnails",
|
||||
".transcode-cache",
|
||||
".vite",
|
||||
".waveform-cache",
|
||||
"build",
|
||||
"coverage",
|
||||
"dist",
|
||||
"node_modules",
|
||||
"outputs",
|
||||
"renders",
|
||||
]);
|
||||
@@ -7,6 +7,7 @@ import { TraceMap, originalPositionFor } from "@jridgewell/trace-mapping";
|
||||
import type { BundleScriptProvenance } from "../../core/src/compiler/htmlBundler";
|
||||
import type { ElementRef, Snippet } from "./types";
|
||||
import { sourceDependencies, type SourceRange } from "./sourceDependencies";
|
||||
import { PREVIEW_IGNORED_DIRS } from "../../core/src/projectFolders";
|
||||
|
||||
interface Chunk {
|
||||
file: string;
|
||||
@@ -40,17 +41,7 @@ function occurrences(text: string, needle: string) {
|
||||
}
|
||||
return hits;
|
||||
}
|
||||
const excluded = new Set([
|
||||
"node_modules",
|
||||
".git",
|
||||
".hyperframes",
|
||||
".agents",
|
||||
".claude",
|
||||
"evidence",
|
||||
"outputs",
|
||||
"renders",
|
||||
"snapshots",
|
||||
]);
|
||||
const excluded = new Set([...PREVIEW_IGNORED_DIRS, ".agents", ".claude", "evidence", "snapshots"]);
|
||||
function sourceFiles(project: string) {
|
||||
const files: string[] = [];
|
||||
function visit(dir: string) {
|
||||
|
||||
@@ -1,14 +1,32 @@
|
||||
import { describe, it, expect } from "vitest";
|
||||
import { mkdtempSync, writeFileSync, rmSync } from "node:fs";
|
||||
import { mkdirSync, mkdtempSync, writeFileSync, rmSync } from "node:fs";
|
||||
import { tmpdir } from "node:os";
|
||||
import { join } from "node:path";
|
||||
import { Sources, mergeSnippets, fingerprint } from "../src/sources";
|
||||
import { PREVIEW_IGNORED_DIRS } from "../../core/src/projectFolders";
|
||||
import {
|
||||
bundleToSingleHtml,
|
||||
type BundleScriptProvenance,
|
||||
} from "../../core/src/compiler/htmlBundler";
|
||||
|
||||
describe("source records", () => {
|
||||
it("ignores the generated folders Studio's preview signature ignores", () => {
|
||||
const dir = mkdtempSync(join(tmpdir(), "inspect-source-"));
|
||||
try {
|
||||
writeFileSync(join(dir, "index.html"), "<div></div>");
|
||||
const before = fingerprint(dir);
|
||||
for (const folder of PREVIEW_IGNORED_DIRS) {
|
||||
mkdirSync(join(dir, folder));
|
||||
writeFileSync(join(dir, folder, "peaks.json"), "[1,2,3]");
|
||||
}
|
||||
expect(fingerprint(dir)).toBe(before);
|
||||
writeFileSync(join(dir, "data.json"), "{}");
|
||||
expect(fingerprint(dir)).not.toBe(before);
|
||||
} finally {
|
||||
rmSync(dir, { recursive: true, force: true });
|
||||
}
|
||||
});
|
||||
|
||||
it("keeps original multiline blocks and deduplicates targets without reformatting", () => {
|
||||
const dir = mkdtempSync(join(tmpdir(), "inspect-source-"));
|
||||
try {
|
||||
|
||||
@@ -3,6 +3,7 @@ import { createHash } from "node:crypto";
|
||||
import { lstatSync, readFileSync, readdirSync, type Stats } from "node:fs";
|
||||
import { extname, isAbsolute, relative, resolve, sep } from "node:path";
|
||||
import { isAtomicTempPath } from "@hyperframes/core/atomic-file";
|
||||
import { PREVIEW_IGNORED_DIRS } from "@hyperframes/core/project-folders";
|
||||
import type { ResolvedProject, StudioApiAdapter } from "../types.js";
|
||||
|
||||
const SIGNATURE_TEXT_EXTENSIONS = new Set([
|
||||
@@ -17,22 +18,6 @@ const SIGNATURE_TEXT_EXTENSIONS = new Set([
|
||||
".ts",
|
||||
".tsx",
|
||||
]);
|
||||
const SIGNATURE_EXCLUDED_DIRS = new Set([
|
||||
".cache",
|
||||
".git",
|
||||
".hyperframes",
|
||||
".next",
|
||||
".thumbnails",
|
||||
".transcode-cache",
|
||||
".vite",
|
||||
".waveform-cache",
|
||||
"build",
|
||||
"coverage",
|
||||
"dist",
|
||||
"node_modules",
|
||||
"outputs",
|
||||
"renders",
|
||||
]);
|
||||
const MAX_SIGNATURE_TEXT_BYTES = 2_000_000;
|
||||
export const STUDIO_SIGNATURE_MANIFEST_PATHS = [
|
||||
".hyperframes/studio-manual-edits.json",
|
||||
@@ -72,7 +57,7 @@ export function affectsProjectSignature(projectDir: string, changedPath: string)
|
||||
if (isRenderOutput(projectDir, changedPath, readRenderOutputsOrNone(projectDir))) return false;
|
||||
const segments = relativePath.split(sep);
|
||||
if (STUDIO_SIGNATURE_MANIFEST_PATHS.includes(segments.join("/") as never)) return true;
|
||||
return !segments.some((segment) => SIGNATURE_EXCLUDED_DIRS.has(segment));
|
||||
return !segments.some((segment) => PREVIEW_IGNORED_DIRS.has(segment));
|
||||
}
|
||||
|
||||
interface ProjectSignatureFile {
|
||||
@@ -106,7 +91,7 @@ function isTextContentEligible(file: string, size: number): boolean {
|
||||
}
|
||||
|
||||
const isSkippedEntry = (entry: string) =>
|
||||
SIGNATURE_EXCLUDED_DIRS.has(entry) || isAtomicTempPath(entry);
|
||||
PREVIEW_IGNORED_DIRS.has(entry) || isAtomicTempPath(entry);
|
||||
|
||||
function signatureEntryStat(
|
||||
projectDir: string,
|
||||
|
||||
Reference in New Issue
Block a user