diff --git a/eslint.config.js b/eslint.config.js
index c052e3e..1994a63 100644
--- a/eslint.config.js
+++ b/eslint.config.js
@@ -13,6 +13,20 @@ const svelteConfig = (await loadConfig("./", { traverse: false }))?.config;
const gitignorePath = fileURLToPath(new URL("./.gitignore", import.meta.url));
+// Restricts the direction of dependencies between modules
+const defineImportBoundaries = (boundaries) =>
+ Object.entries(boundaries).map(([files, regex]) => ({
+ files: [files],
+ rules: {
+ "no-restricted-imports": [
+ "error",
+ {
+ patterns: [{ regex, message: "Violates the dependency direction between modules." }],
+ },
+ ],
+ },
+ }));
+
export default defineConfig(
includeIgnoreFile(gitignorePath),
js.configs.recommended,
@@ -37,6 +51,17 @@ export default defineConfig(
"no-undef": "off",
},
},
+ ...defineImportBoundaries({
+ // Pure code shared by the server, the client, and the service worker
+ "src/lib/shared/**": "^(#lib/(?!shared/)|#trpc/|#workers/|\\$app/|svelte($|/))",
+ "src/lib/server/**": "^(#lib/(client|features|ui)/|#trpc/)",
+ // Infrastructure of the browser
+ "src/lib/client/**": "^#lib/(server|features|ui)/",
+ // Domain-agnostic components
+ "src/lib/ui/**": "^(#lib/(server|client|features)/|#trpc/)",
+ "src/lib/features/**": "^#lib/server/",
+ "src/service-worker/**": "^(#lib/(?!shared/|client/storage/opfs\\.js$)|#trpc/|#workers/)",
+ }),
{
files: ["**/*.svelte", "**/*.svelte.ts", "**/*.svelte.js"],
languageOptions: {
diff --git a/src/lib/client/cache/thumbnailCache.svelte.ts b/src/lib/client/cache/thumbnailCache.svelte.ts
index 5a36e3d..cc45213 100644
--- a/src/lib/client/cache/thumbnailCache.svelte.ts
+++ b/src/lib/client/cache/thumbnailCache.svelte.ts
@@ -1,7 +1,6 @@
/* eslint-disable svelte/prefer-svelte-reactivity -- Lookup tables of reactive entries */
import { LRUCache } from "lru-cache";
import { deleteDirectory, deleteFile, readFile, writeFile } from "#lib/client/storage/opfs.js";
-import type { SummarizedFileInfo } from "#lib/features/filesystem/index.js";
import { decryptChunk, encodeToBase64 } from "#lib/shared/crypto/index.js";
export interface Thumbnail {
@@ -33,7 +32,11 @@ const fetchFromServer = async (fileId: number, dataKey: CryptoKey) => {
return getThumbnailUrl(thumbnailBuffer);
};
-export const getFileThumbnail = (file: SummarizedFileInfo) => {
+export const getFileThumbnail = (file: {
+ id: number;
+ contentType: string;
+ dataKey?: { key: CryptoKey };
+}) => {
if (!(file.contentType.startsWith("image/") || file.contentType.startsWith("video/"))) {
return undefined;
}
diff --git a/src/lib/components/atoms/buttons/index.ts b/src/lib/components/atoms/buttons/index.ts
deleted file mode 100644
index 4ed77f2..0000000
--- a/src/lib/components/atoms/buttons/index.ts
+++ /dev/null
@@ -1,6 +0,0 @@
-export { default as ActionEntryButton } from "./ActionEntryButton.svelte";
-export { default as Button } from "./Button.svelte";
-export { default as EntryButton } from "./EntryButton.svelte";
-export { default as FileThumbnailButton } from "./FileThumbnailButton.svelte";
-export { default as FloatingButton } from "./FloatingButton.svelte";
-export { default as TextButton } from "./TextButton.svelte";
diff --git a/src/lib/components/atoms/divs/index.ts b/src/lib/components/atoms/divs/index.ts
deleted file mode 100644
index 561bbde..0000000
--- a/src/lib/components/atoms/divs/index.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-export { default as AdaptiveDiv } from "./AdaptiveDiv.svelte";
-export { default as BottomDiv } from "./BottomDiv.svelte";
-export { default as FullscreenDiv } from "./FullscreenDiv.svelte";
diff --git a/src/lib/components/atoms/index.ts b/src/lib/components/atoms/index.ts
deleted file mode 100644
index 1ba53f7..0000000
--- a/src/lib/components/atoms/index.ts
+++ /dev/null
@@ -1,8 +0,0 @@
-export { default as BottomSheet } from "./BottomSheet.svelte";
-export * from "./buttons";
-export { default as Chip } from "./Chip.svelte";
-export * from "./divs";
-export * from "./inputs";
-export { default as Modal } from "./Modal.svelte";
-export { default as RowVirtualizer } from "./RowVirtualizer.svelte";
-export { default as Toasts } from "./Toasts.svelte";
diff --git a/src/lib/components/atoms/inputs/index.ts b/src/lib/components/atoms/inputs/index.ts
deleted file mode 100644
index 47cb929..0000000
--- a/src/lib/components/atoms/inputs/index.ts
+++ /dev/null
@@ -1,2 +0,0 @@
-export { default as CheckBox } from "./CheckBox.svelte";
-export { default as TextInput } from "./TextInput.svelte";
diff --git a/src/lib/components/molecules/index.ts b/src/lib/components/molecules/index.ts
deleted file mode 100644
index a36afcd..0000000
--- a/src/lib/components/molecules/index.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-export * from "./ActionModal.svelte";
-export { default as ActionModal } from "./ActionModal.svelte";
-export * from "./Categories.svelte";
-export { default as Categories } from "./Categories.svelte";
-export { default as IconEntryButton } from "./IconEntryButton.svelte";
-export * from "./labels";
-export { default as SubCategories } from "./SubCategories.svelte";
-export { default as TitledDiv } from "./TitledDiv.svelte";
-export { default as TopBar } from "./TopBar.svelte";
diff --git a/src/lib/components/molecules/labels/index.ts b/src/lib/components/molecules/labels/index.ts
deleted file mode 100644
index af8f40b..0000000
--- a/src/lib/components/molecules/labels/index.ts
+++ /dev/null
@@ -1,4 +0,0 @@
-export { default as CategoryLabel } from "./CategoryLabel.svelte";
-export { default as DirectoryEntryLabel } from "./DirectoryEntryLabel.svelte";
-export { default as IconLabel } from "./IconLabel.svelte";
-export { default as TitleLabel } from "./TitleLabel.svelte";
diff --git a/src/lib/components/organisms/index.ts b/src/lib/components/organisms/index.ts
deleted file mode 100644
index fa02317..0000000
--- a/src/lib/components/organisms/index.ts
+++ /dev/null
@@ -1 +0,0 @@
-export * from "./modals";
diff --git a/src/lib/components/organisms/modals/index.ts b/src/lib/components/organisms/modals/index.ts
deleted file mode 100644
index 56c64a1..0000000
--- a/src/lib/components/organisms/modals/index.ts
+++ /dev/null
@@ -1,4 +0,0 @@
-export { default as CategoryCreateModal } from "./CategoryCreateModal.svelte";
-export { default as ForceLoginModal } from "./ForceLoginModal.svelte";
-export { default as RenameModal } from "./RenameModal.svelte";
-export { default as TextInputModal } from "./TextInputModal.svelte";
diff --git a/src/lib/components/organisms/modals/ForceLoginModal.svelte b/src/lib/features/auth/components/ForceLoginModal.svelte
similarity index 88%
rename from src/lib/components/organisms/modals/ForceLoginModal.svelte
rename to src/lib/features/auth/components/ForceLoginModal.svelte
index 010f5f2..259e9b0 100644
--- a/src/lib/components/organisms/modals/ForceLoginModal.svelte
+++ b/src/lib/features/auth/components/ForceLoginModal.svelte
@@ -1,5 +1,5 @@
+
+