bedee3ba8d
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
85 lines
2.3 KiB
TypeScript
85 lines
2.3 KiB
TypeScript
import { aiGenerationClient } from "./aiGenerationClient";
|
|
|
|
interface UploadEntry {
|
|
promise: Promise<string | null>;
|
|
url: string | null;
|
|
status: "pending" | "done" | "failed";
|
|
}
|
|
|
|
const uploadCache = new Map<string, UploadEntry>();
|
|
|
|
function fileToDataUrl(file: File): Promise<string> {
|
|
return new Promise((resolve, reject) => {
|
|
const reader = new FileReader();
|
|
reader.onload = () => resolve(String(reader.result || ""));
|
|
reader.onerror = () => reject(reader.error || new Error("文件读取失败"));
|
|
reader.readAsDataURL(file);
|
|
});
|
|
}
|
|
|
|
function buildCacheKey(file: File, fingerprint?: string): string {
|
|
if (fingerprint) return fingerprint;
|
|
return `${file.name}__${file.size}__${file.lastModified}`;
|
|
}
|
|
|
|
export function preUploadReference(
|
|
file: File,
|
|
name: string,
|
|
fingerprint?: string,
|
|
): Promise<string | null> {
|
|
const key = buildCacheKey(file, fingerprint);
|
|
const cached = uploadCache.get(key);
|
|
if (cached) return cached.promise;
|
|
|
|
const scope = file.type.startsWith("video/") ? "reference-video" : "reference-image";
|
|
|
|
const promise = (async () => {
|
|
try {
|
|
const dataUrl = await fileToDataUrl(file);
|
|
const uploaded = await aiGenerationClient.uploadAsset({
|
|
dataUrl,
|
|
name,
|
|
mimeType: file.type,
|
|
scope,
|
|
});
|
|
const entry = uploadCache.get(key);
|
|
if (entry) {
|
|
entry.url = uploaded.url;
|
|
entry.status = "done";
|
|
}
|
|
return uploaded.url;
|
|
} catch (error) {
|
|
const entry = uploadCache.get(key);
|
|
if (entry) entry.status = "failed";
|
|
console.warn("[referenceUpload] pre-upload failed:", error);
|
|
return null;
|
|
}
|
|
})();
|
|
|
|
uploadCache.set(key, { promise, url: null, status: "pending" });
|
|
return promise;
|
|
}
|
|
|
|
export function getPreUploadedUrl(
|
|
file: File,
|
|
fingerprint?: string,
|
|
): string | null {
|
|
const key = buildCacheKey(file, fingerprint);
|
|
return uploadCache.get(key)?.url ?? null;
|
|
}
|
|
|
|
export async function resolvePreUploadedUrl(
|
|
file: File,
|
|
name: string,
|
|
fingerprint?: string,
|
|
): Promise<string | null> {
|
|
const key = buildCacheKey(file, fingerprint);
|
|
const cached = uploadCache.get(key);
|
|
if (cached) return cached.promise;
|
|
return preUploadReference(file, name, fingerprint);
|
|
}
|
|
|
|
export function clearUploadCache(): void {
|
|
uploadCache.clear();
|
|
}
|