- Chargement bulk des URLs de frames (1 query au lieu de 1/frame) - Preload des 30 prochaines frames pendant la lecture - Cache navigateur activé sur le proxy S3 (max-age=3600, immutable) - Fallback query tRPC uniquement si la map n'a pas la frame Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
48 lines
1.4 KiB
TypeScript
48 lines
1.4 KiB
TypeScript
import type { Express } from "express";
|
|
import { ENV } from "./env";
|
|
|
|
export function registerStorageProxy(app: Express) {
|
|
app.get("/manus-storage/*", async (req, res) => {
|
|
const key = (req.params as Record<string, string>)[0];
|
|
if (!key) {
|
|
res.status(400).send("Missing storage key");
|
|
return;
|
|
}
|
|
|
|
if (!ENV.forgeApiUrl || !ENV.forgeApiKey) {
|
|
res.status(500).send("Storage proxy not configured");
|
|
return;
|
|
}
|
|
|
|
try {
|
|
const forgeUrl = new URL(
|
|
"v1/storage/presign/get",
|
|
ENV.forgeApiUrl.replace(/\/+$/, "") + "/",
|
|
);
|
|
forgeUrl.searchParams.set("path", key);
|
|
|
|
const forgeResp = await fetch(forgeUrl, {
|
|
headers: { Authorization: `Bearer ${ENV.forgeApiKey}` },
|
|
});
|
|
|
|
if (!forgeResp.ok) {
|
|
const body = await forgeResp.text().catch(() => "");
|
|
console.error(`[StorageProxy] forge error: ${forgeResp.status} ${body}`);
|
|
res.status(502).send("Storage backend error");
|
|
return;
|
|
}
|
|
|
|
const { url } = (await forgeResp.json()) as { url: string };
|
|
if (!url) {
|
|
res.status(502).send("Empty signed URL from backend");
|
|
return;
|
|
}
|
|
|
|
res.set("Cache-Control", "public, max-age=3600, immutable");
|
|
res.redirect(307, url);
|
|
} catch (err) {
|
|
console.error("[StorageProxy] failed:", err);
|
|
res.status(502).send("Storage proxy error");
|
|
}
|
|
});
|
|
}
|