네트워크 호출 결과가 IndexedDB에 캐시되지 않던 버그 수정

This commit is contained in:
static
2026-01-01 23:52:47 +09:00
parent d98be331ad
commit 2e3cd4f8a2
4 changed files with 158 additions and 36 deletions

View File

@@ -52,25 +52,76 @@ const fetchFromServer = async (id: CategoryId, masterKey: CryptoKey) => {
metadata,
subCategories: subCategoriesRaw,
files: filesRaw,
} = await trpc().category.get.query({ id });
const [subCategories, files] = await Promise.all([
Promise.all(
subCategoriesRaw.map(async (category) => ({
} = await trpc().category.get.query({ id, recurse: true });
const subCategories = await Promise.all(
subCategoriesRaw.map(async (category) => {
const decrypted = await decryptCategoryMetadata(category, masterKey);
const existing = await IndexedDB.getCategoryInfo(category.id);
await IndexedDB.storeCategoryInfo({
id: category.id,
...(await decryptCategoryMetadata(category, masterKey)),
})),
),
filesRaw
? Promise.all(
filesRaw.map(async (file) => ({
parentId: id,
name: decrypted.name,
files: existing?.files ?? [],
isFileRecursive: existing?.isFileRecursive ?? false,
});
return {
id: category.id,
...decrypted,
};
}),
);
const existingFiles = filesRaw
? await IndexedDB.bulkGetFileInfos(filesRaw.map((file) => file.id))
: [];
const files = filesRaw
? await Promise.all(
filesRaw.map(async (file, index) => {
const decrypted = await decryptFileMetadata(file, masterKey);
const existing = existingFiles[index];
if (existing) {
const categoryIds = file.isRecursive
? existing.categoryIds
: Array.from(new Set([...existing.categoryIds, id as number]));
await IndexedDB.storeFileInfo({
id: file.id,
parentId: existing.parentId,
contentType: file.contentType,
name: decrypted.name,
createdAt: decrypted.createdAt,
lastModifiedAt: decrypted.lastModifiedAt,
categoryIds,
});
}
return {
id: file.id,
contentType: file.contentType,
isRecursive: file.isRecursive,
...(await decryptFileMetadata(file, masterKey)),
})),
)
: undefined,
]);
...decrypted,
};
}),
)
: undefined;
const decryptedMetadata = metadata
? await decryptCategoryMetadata(metadata, masterKey)
: undefined;
if (id !== "root" && metadata && decryptedMetadata) {
const existingCategory = await IndexedDB.getCategoryInfo(id);
await IndexedDB.storeCategoryInfo({
id: id as number,
parentId: metadata.parent,
name: decryptedMetadata.name,
files:
files?.map((file) => ({
id: file.id,
isRecursive: file.isRecursive,
})) ??
existingCategory?.files ??
[],
isFileRecursive: existingCategory?.isFileRecursive ?? false,
});
}
if (id === "root") {
return {
@@ -84,7 +135,7 @@ const fetchFromServer = async (id: CategoryId, masterKey: CryptoKey) => {
exists: true as const,
subCategories,
files,
...(await decryptCategoryMetadata(metadata!, masterKey)),
...decryptedMetadata!,
};
}
} catch (e) {

View File

@@ -39,22 +39,52 @@ const fetchFromServer = async (id: DirectoryId, masterKey: CryptoKey) => {
subDirectories: subDirectoriesRaw,
files: filesRaw,
} = await trpc().directory.get.query({ id });
const [subDirectories, files] = await Promise.all([
const existingFiles = await IndexedDB.bulkGetFileInfos(filesRaw.map((file) => file.id));
const [subDirectories, files, decryptedMetadata] = await Promise.all([
Promise.all(
subDirectoriesRaw.map(async (directory) => ({
id: directory.id,
...(await decryptDirectoryMetadata(directory, masterKey)),
})),
subDirectoriesRaw.map(async (directory) => {
const decrypted = await decryptDirectoryMetadata(directory, masterKey);
await IndexedDB.storeDirectoryInfo({
id: directory.id,
parentId: id,
name: decrypted.name,
});
return {
id: directory.id,
...decrypted,
};
}),
),
Promise.all(
filesRaw.map(async (file) => ({
id: file.id,
contentType: file.contentType,
...(await decryptFileMetadata(file, masterKey)),
})),
filesRaw.map(async (file, index) => {
const decrypted = await decryptFileMetadata(file, masterKey);
await IndexedDB.storeFileInfo({
id: file.id,
parentId: id,
contentType: file.contentType,
name: decrypted.name,
createdAt: decrypted.createdAt,
lastModifiedAt: decrypted.lastModifiedAt,
categoryIds: existingFiles[index]?.categoryIds ?? [],
});
return {
id: file.id,
contentType: file.contentType,
...decrypted,
};
}),
),
metadata ? decryptDirectoryMetadata(metadata, masterKey) : undefined,
]);
if (id !== "root" && metadata && decryptedMetadata) {
await IndexedDB.storeDirectoryInfo({
id,
parentId: metadata.parent,
name: decryptedMetadata.name,
});
}
if (id === "root") {
return {
id,
@@ -69,7 +99,7 @@ const fetchFromServer = async (id: DirectoryId, masterKey: CryptoKey) => {
parentId: metadata!.parent,
subDirectories,
files,
...(await decryptDirectoryMetadata(metadata!, masterKey)),
...decryptedMetadata!,
};
}
} catch (e) {

View File

@@ -66,15 +66,26 @@ const bulkFetchFromIndexedDB = async (ids: number[]) => {
const fetchFromServer = async (id: number, masterKey: CryptoKey) => {
try {
const { categories: categoriesRaw, ...metadata } = await trpc().file.get.query({ id });
const [categories] = await Promise.all([
const [categories, decryptedMetadata] = await Promise.all([
Promise.all(
categoriesRaw.map(async (category) => ({
id: category.id,
...(await decryptCategoryMetadata(category, masterKey)),
})),
),
decryptFileMetadata(metadata, masterKey),
]);
await IndexedDB.storeFileInfo({
id,
parentId: metadata.parent,
contentType: metadata.contentType,
name: decryptedMetadata.name,
createdAt: decryptedMetadata.createdAt,
lastModifiedAt: decryptedMetadata.lastModifiedAt,
categoryIds: categories.map((category) => category.id),
});
return {
id,
exists: true as const,
@@ -82,7 +93,7 @@ const fetchFromServer = async (id: number, masterKey: CryptoKey) => {
contentType: metadata.contentType,
contentIv: metadata.contentIv,
categories,
...(await decryptFileMetadata(metadata, masterKey)),
...decryptedMetadata,
};
} catch (e) {
if (isTRPCClientError(e) && e.data?.code === "NOT_FOUND") {
@@ -97,12 +108,25 @@ const bulkFetchFromServer = async (ids: number[], masterKey: CryptoKey) => {
const filesRaw = await trpc().file.bulkGet.query({ ids });
const files = await Promise.all(
filesRaw.map(async (file) => {
const categories = await Promise.all(
file.categories.map(async (category) => ({
id: category.id,
...(await decryptCategoryMetadata(category, masterKey)),
})),
);
const [categories, decryptedMetadata] = await Promise.all([
Promise.all(
file.categories.map(async (category) => ({
id: category.id,
...(await decryptCategoryMetadata(category, masterKey)),
})),
),
decryptFileMetadata(file, masterKey),
]);
await IndexedDB.storeFileInfo({
id: file.id,
parentId: file.parent,
contentType: file.contentType,
name: decryptedMetadata.name,
createdAt: decryptedMetadata.createdAt,
lastModifiedAt: decryptedMetadata.lastModifiedAt,
categoryIds: categories.map((category) => category.id),
});
return {
id: file.id,
exists: true as const,
@@ -110,7 +134,7 @@ const bulkFetchFromServer = async (ids: number[], masterKey: CryptoKey) => {
contentType: file.contentType,
contentIv: file.contentIv,
categories,
...(await decryptFileMetadata(file, masterKey)),
...decryptedMetadata,
};
}),
);