mirror of
https://github.com/kmc7468/arkvault.git
synced 2026-11-04 08:10:28 +09:00
파일을 다운로드할 때 전체 파일을 메모리에 올리는 대신 서비스 워커에서 스트리밍으로 복호화하도록 변경
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
877cf9c42e
commit
3e52fa7a7c
29 files changed
+629
-467
No files matched your search
@@ -1,41 +1,57 @@
|
||||
import {
|
||||
deleteFileCache,
|
||||
deleteFileThumbnailCache,
|
||||
getFileCache,
|
||||
storeFileCache,
|
||||
storeFileThumbnailCache,
|
||||
} from "#lib/client/cache/index.js";
|
||||
import { getDecryptedFileUrl, prepareFileDecryption } from "#lib/client/serviceWorker.js";
|
||||
import {
|
||||
getDecryptedFileUrl,
|
||||
prepareFileDecryption,
|
||||
saveDecryptedFile,
|
||||
} from "#lib/client/serviceWorker.js";
|
||||
import { getAllFileInfos } from "#lib/client/storage/indexedDB/index.js";
|
||||
import { uploadBlob } from "#lib/client/transfer/chunkedUpload.js";
|
||||
import { downloadFile } from "#lib/client/transfer/index.js";
|
||||
import { trpc } from "#trpc/client.js";
|
||||
import type { DataKey } from "./types";
|
||||
|
||||
// Returns the decrypted content of the file, from the cache if available
|
||||
export const getFileContent = async (fileId: number, dataKey: CryptoKey, isLegacy: boolean) => {
|
||||
const cache = await getFileCache(fileId);
|
||||
if (cache) return cache;
|
||||
interface StreamableFile {
|
||||
id: number;
|
||||
isLegacy?: boolean;
|
||||
dataKey?: DataKey;
|
||||
contentType: string;
|
||||
}
|
||||
|
||||
const fileBuffer = await downloadFile(fileId, dataKey, isLegacy);
|
||||
void storeFileCache(fileId, fileBuffer);
|
||||
return fileBuffer;
|
||||
};
|
||||
// Returns a URL from which the service worker streams the decrypted content of the file
|
||||
export const getFileStreamUrl = async ({ id, isLegacy, dataKey, contentType }: StreamableFile) => {
|
||||
if (!dataKey) {
|
||||
throw new Error("Data key not loaded");
|
||||
}
|
||||
|
||||
// Returns a URL from which the service worker streams the decrypted file
|
||||
export const getFileStreamUrl = async (fileId: number, dataKey: CryptoKey, contentType: string) => {
|
||||
const res = await fetch(`/api/file/${fileId}/download`, { method: "HEAD" });
|
||||
const res = await fetch(`/api/file/${id}/download`, { method: "HEAD" });
|
||||
if (!res.ok) {
|
||||
throw new Error("Failed to get the file size");
|
||||
}
|
||||
|
||||
const encContentSize = parseInt(res.headers.get("Content-Length") ?? "0", 10);
|
||||
if (encContentSize <= 0) {
|
||||
throw new Error("Invalid file size");
|
||||
}
|
||||
await prepareFileDecryption(id, {
|
||||
isLegacy: !!isLegacy,
|
||||
dataKey: dataKey.key,
|
||||
encContentSize,
|
||||
contentType,
|
||||
});
|
||||
return getDecryptedFileUrl(id);
|
||||
};
|
||||
|
||||
await prepareFileDecryption(fileId, { isLegacy: false, dataKey, encContentSize, contentType });
|
||||
return getDecryptedFileUrl(fileId);
|
||||
export const getFileBlob = async (file: StreamableFile) => {
|
||||
const res = await fetch(await getFileStreamUrl(file));
|
||||
if (!res.ok) {
|
||||
throw new Error("Failed to download the file");
|
||||
}
|
||||
return await res.blob();
|
||||
};
|
||||
|
||||
export const saveFile = async (file: StreamableFile & { name: string }) => {
|
||||
await getFileStreamUrl(file);
|
||||
saveDecryptedFile(file.id, file.name);
|
||||
};
|
||||
|
||||
export const uploadFileThumbnail = async (fileId: number, thumbnail: Blob, dataKey: DataKey) => {
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { storeFileCache, storeFileThumbnailCache } from "#lib/client/cache/index.js";
|
||||
import { storeFileThumbnailCache } from "#lib/client/cache/index.js";
|
||||
import { uploadFile as doUploadFile } from "#lib/client/transfer/index.js";
|
||||
import { invalidateDirectory } from "./directory";
|
||||
|
||||
// Uploads the file and caches it locally. Returns `false` if the upload is canceled.
|
||||
// Uploads the file and caches its thumbnail locally. Returns `false` if the upload is canceled.
|
||||
export const uploadFile = async (
|
||||
file: File,
|
||||
parentId: DirectoryId,
|
||||
@@ -12,9 +12,6 @@ export const uploadFile = async (
|
||||
if (!res) return false;
|
||||
|
||||
invalidateDirectory(parentId);
|
||||
if (res.fileBuffer) {
|
||||
void storeFileCache(res.fileId, res.fileBuffer);
|
||||
}
|
||||
if (res.thumbnailBuffer) {
|
||||
void storeFileThumbnailCache(res.fileId, res.thumbnailBuffer);
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user