Spaces:
Running
Running
| import fs from 'fs' | |
| import path from 'path' | |
| import { createHash } from 'crypto' | |
| const RENDER_CACHE_ROOT = path.join(process.cwd(), '.studio-workspace', 'render-cache') | |
| export interface RenderCacheWorkspace { | |
| key: string | |
| rootDir: string | |
| tempDir: string | |
| mediaDir: string | |
| codeFile: string | |
| } | |
| function normalizeRenderCacheKey(renderCacheKey: string): string { | |
| const trimmed = renderCacheKey.trim() | |
| if (!trimmed) { | |
| throw new Error('renderCacheKey must not be empty') | |
| } | |
| return trimmed | |
| } | |
| function toDirectoryName(renderCacheKey: string): string { | |
| const normalized = normalizeRenderCacheKey(renderCacheKey) | |
| const readable = normalized | |
| .toLowerCase() | |
| .replace(/[^a-z0-9]+/g, '-') | |
| .replace(/^-+|-+$/g, '') | |
| .slice(0, 48) || 'render-cache' | |
| const digest = createHash('sha1').update(normalized).digest('hex').slice(0, 12) | |
| return `${readable}-${digest}` | |
| } | |
| function ensureWorkspace(rootDir: string): void { | |
| fs.mkdirSync(rootDir, { recursive: true }) | |
| } | |
| export function resolveRenderCacheWorkspace( | |
| renderCacheKey: string, | |
| scope: 'video' | 'image', | |
| blockIndex?: number | |
| ): RenderCacheWorkspace { | |
| const directoryName = toDirectoryName(renderCacheKey) | |
| const scopeSuffix = | |
| scope === 'video' | |
| ? 'video' | |
| : `image-${String(blockIndex ?? 0).padStart(3, '0')}` | |
| const rootDir = path.join(RENDER_CACHE_ROOT, directoryName, scopeSuffix) | |
| const mediaDir = path.join(rootDir, 'media') | |
| const codeFile = path.join(rootDir, 'scene.py') | |
| ensureWorkspace(mediaDir) | |
| return { | |
| key: renderCacheKey, | |
| rootDir, | |
| tempDir: rootDir, | |
| mediaDir, | |
| codeFile | |
| } | |
| } | |
| export function buildClassicRenderCacheKey( | |
| clientId: string | undefined, | |
| outputMode: 'video' | 'image', | |
| requestedKey?: string | |
| ): string { | |
| const normalizedRequested = requestedKey?.trim() | |
| if (normalizedRequested) { | |
| return normalizedRequested | |
| } | |
| const normalizedClientId = clientId?.trim() || 'anonymous' | |
| return `classic-${normalizedClientId}-${outputMode}` | |
| } | |
| export function buildStudioRenderCacheKey( | |
| sessionId: string, | |
| outputMode: 'video' | 'image', | |
| workId?: string | |
| ): string { | |
| const normalizedWorkId = workId?.trim() | |
| if (normalizedWorkId) { | |
| return `studio-${sessionId}-${outputMode}-${normalizedWorkId}` | |
| } | |
| return `studio-${sessionId}-${outputMode}` | |
| } | |