diff --git a/app/page.tsx b/app/page.tsx
index fd52e7b..18ff523 100644
--- a/app/page.tsx
+++ b/app/page.tsx
@@ -31,6 +31,8 @@ import enMessages from '@/lib/locales/en.json';
import {NextIntlClientProvider, useTranslations} from "next-intl";
import {LangContext} from "@/context/LangContext";
import {AIUsageContext} from "@/context/AIUsageContext";
+import OfflineProvider from "@/context/OfflineProvider";
+import OfflineContext from "@/context/OfflineContext";
const messagesMap = {
fr: frMessages,
@@ -41,6 +43,7 @@ function ScribeContent() {
const t = useTranslations();
const {lang: locale} = useContext(LangContext);
const {errorMessage} = useContext(AlertContext);
+ const {initializeDatabase} = useContext(OfflineContext);
const editor: Editor | null = useEditor({
extensions: [
StarterKit,
@@ -216,6 +219,19 @@ function ScribeContent() {
});
setCurrentCredits(user.creditsBalance)
setAmountSpent(user.aiUsage)
+
+ // Initialiser la DB locale en Electron
+ if (window.electron && user.id) {
+ try {
+ const dbInitialized = await initializeDatabase(user.id);
+ if (dbInitialized) {
+ console.log('Database initialized successfully');
+ // TODO: Sync initial des données du serveur vers la DB locale
+ }
+ } catch (error) {
+ console.error('Failed to initialize database:', error);
+ }
+ }
} catch (e: unknown) {
if (e instanceof Error) {
errorMessage(e.message);
@@ -359,9 +375,11 @@ export default function Scribe() {
return (
-
-
-
+
+
+
+
+
);
diff --git a/components/ScribeTopBar.tsx b/components/ScribeTopBar.tsx
index 6aadf97..e6e8b83 100644
--- a/components/ScribeTopBar.tsx
+++ b/components/ScribeTopBar.tsx
@@ -2,6 +2,7 @@
import {useContext} from "react";
import {BookContext, BookContextProps} from "@/context/BookContext";
import {useTranslations} from "next-intl";
+import OfflineToggle from "@/components/offline/OfflineToggle";
export default function ScribeTopBar() {
const book: BookContextProps = useContext(BookContext);
@@ -33,6 +34,7 @@ export default function ScribeTopBar() {
)}
+
)
diff --git a/components/book/BookList.tsx b/components/book/BookList.tsx
index 063f95f..b306ce7 100644
--- a/components/book/BookList.tsx
+++ b/components/book/BookList.tsx
@@ -244,8 +244,8 @@ export default function BookList() {
-
- {category}
+
+ {category}
{books.length} {t("bookList.works")}
diff --git a/electron.d.ts b/electron.d.ts
index 6f46db4..fe7c946 100644
--- a/electron.d.ts
+++ b/electron.d.ts
@@ -5,6 +5,23 @@ export interface IElectronAPI {
removeToken: () => Promise;
loginSuccess: (token: string) => void;
logout: () => void;
+
+ // Database operations
+ generateEncryptionKey: (userId: string) => Promise<{ success: boolean; key?: string; error?: string }>;
+ getUserEncryptionKey: (userId: string) => Promise;
+ setUserEncryptionKey: (userId: string, encryptionKey: string) => Promise;
+ dbInitialize: (userId: string, encryptionKey: string) => Promise<{ success: boolean; error?: string }>;
+ dbGetBooks: () => Promise<{ success: boolean; data?: any[]; error?: string }>;
+ dbGetBook: (bookId: string) => Promise<{ success: boolean; data?: any; error?: string }>;
+ dbSaveBook: (book: any, authorId?: string) => Promise<{ success: boolean; error?: string }>;
+ dbDeleteBook: (bookId: string) => Promise<{ success: boolean; error?: string }>;
+ dbSaveChapter: (chapter: any, bookId: string, contentId?: string) => Promise<{ success: boolean; error?: string }>;
+ dbGetCharacters: (bookId: string) => Promise<{ success: boolean; data?: any[]; error?: string }>;
+ dbSaveCharacter: (character: any, bookId: string) => Promise<{ success: boolean; error?: string }>;
+ dbGetConversations: (bookId: string) => Promise<{ success: boolean; data?: any[]; error?: string }>;
+ dbSaveConversation: (conversation: any, bookId: string) => Promise<{ success: boolean; error?: string }>;
+ dbGetSyncStatus: () => Promise<{ success: boolean; data?: any[]; error?: string }>;
+ dbGetPendingChanges: (limit?: number) => Promise<{ success: boolean; data?: any[]; error?: string }>;
}
declare global {
diff --git a/electron/main.ts b/electron/main.ts
index ba0461b..38771bc 100644
--- a/electron/main.ts
+++ b/electron/main.ts
@@ -4,6 +4,7 @@ import * as url from 'url';
import { fileURLToPath } from 'url';
import Store from 'electron-store';
import * as fs from 'fs';
+import { getDatabaseService } from './database/database.service.js';
// Fix pour __dirname en ES modules
const __filename = fileURLToPath(import.meta.url);
@@ -29,10 +30,8 @@ if (!isDev) {
// Définir le nom de l'application
app.setName('ERitors Scribe');
-// En dev, __dirname pointe vers electron/, en prod vers dist/electron/
-const preloadPath = isDev
- ? path.join(__dirname, '../dist/electron/preload.js')
- : path.join(__dirname, 'preload.js');
+// En dev et prod, __dirname pointe vers dist/electron/
+const preloadPath = path.join(__dirname, 'preload.js');
// Icône de l'application
const iconPath = isDev
@@ -143,6 +142,10 @@ ipcMain.on('login-success', (_event, token: string) => {
ipcMain.on('logout', () => {
store.delete('authToken');
+ // Close database connection
+ const db = getDatabaseService();
+ db.close();
+
if (mainWindow) {
mainWindow.close();
}
@@ -150,6 +153,246 @@ ipcMain.on('logout', () => {
createLoginWindow();
});
+// ========== DATABASE IPC HANDLERS ==========
+
+/**
+ * Generate user encryption key
+ */
+ipcMain.handle('generate-encryption-key', async (_event, userId: string) => {
+ try {
+ // Import encryption module dynamically
+ const { generateUserEncryptionKey } = await import('./database/encryption.js');
+ const key = generateUserEncryptionKey(userId);
+ return { success: true, key };
+ } catch (error) {
+ console.error('Failed to generate encryption key:', error);
+ return {
+ success: false,
+ error: error instanceof Error ? error.message : 'Unknown error'
+ };
+ }
+});
+
+/**
+ * Get or generate user encryption key
+ */
+ipcMain.handle('get-user-encryption-key', (_event, userId: string) => {
+ const key = store.get(`encryptionKey-${userId}`, null);
+ return key;
+});
+
+/**
+ * Store user encryption key
+ */
+ipcMain.handle('set-user-encryption-key', (_event, userId: string, encryptionKey: string) => {
+ store.set(`encryptionKey-${userId}`, encryptionKey);
+ return true;
+});
+
+/**
+ * Initialize database for user
+ */
+ipcMain.handle('db-initialize', (_event, userId: string, encryptionKey: string) => {
+ try {
+ const db = getDatabaseService();
+ db.initialize(userId, encryptionKey);
+ return { success: true };
+ } catch (error) {
+ console.error('Failed to initialize database:', error);
+ return {
+ success: false,
+ error: error instanceof Error ? error.message : 'Unknown error'
+ };
+ }
+});
+
+/**
+ * Get all books
+ */
+ipcMain.handle('db-get-books', () => {
+ try {
+ const db = getDatabaseService();
+ const books = db.getBooks();
+ return { success: true, data: books };
+ } catch (error) {
+ console.error('Failed to get books:', error);
+ return {
+ success: false,
+ error: error instanceof Error ? error.message : 'Unknown error'
+ };
+ }
+});
+
+/**
+ * Get single book with all data
+ */
+ipcMain.handle('db-get-book', (_event, bookId: string) => {
+ try {
+ const db = getDatabaseService();
+ const book = db.getBook(bookId);
+ return { success: true, data: book };
+ } catch (error) {
+ console.error('Failed to get book:', error);
+ return {
+ success: false,
+ error: error instanceof Error ? error.message : 'Unknown error'
+ };
+ }
+});
+
+/**
+ * Save book
+ */
+ipcMain.handle('db-save-book', (_event, book: any, authorId?: string) => {
+ try {
+ const db = getDatabaseService();
+ db.saveBook(book, authorId);
+ return { success: true };
+ } catch (error) {
+ console.error('Failed to save book:', error);
+ return {
+ success: false,
+ error: error instanceof Error ? error.message : 'Unknown error'
+ };
+ }
+});
+
+/**
+ * Delete book
+ */
+ipcMain.handle('db-delete-book', (_event, bookId: string) => {
+ try {
+ const db = getDatabaseService();
+ db.deleteBook(bookId);
+ return { success: true };
+ } catch (error) {
+ console.error('Failed to delete book:', error);
+ return {
+ success: false,
+ error: error instanceof Error ? error.message : 'Unknown error'
+ };
+ }
+});
+
+/**
+ * Save chapter
+ */
+ipcMain.handle('db-save-chapter', (_event, chapter: any, bookId: string, contentId?: string) => {
+ try {
+ const db = getDatabaseService();
+ db.saveChapter(chapter, bookId, contentId);
+ return { success: true };
+ } catch (error) {
+ console.error('Failed to save chapter:', error);
+ return {
+ success: false,
+ error: error instanceof Error ? error.message : 'Unknown error'
+ };
+ }
+});
+
+/**
+ * Get characters for a book
+ */
+ipcMain.handle('db-get-characters', (_event, bookId: string) => {
+ try {
+ const db = getDatabaseService();
+ const characters = db.getCharacters(bookId);
+ return { success: true, data: characters };
+ } catch (error) {
+ console.error('Failed to get characters:', error);
+ return {
+ success: false,
+ error: error instanceof Error ? error.message : 'Unknown error'
+ };
+ }
+});
+
+/**
+ * Save character
+ */
+ipcMain.handle('db-save-character', (_event, character: any, bookId: string) => {
+ try {
+ const db = getDatabaseService();
+ db.saveCharacter(character, bookId);
+ return { success: true };
+ } catch (error) {
+ console.error('Failed to save character:', error);
+ return {
+ success: false,
+ error: error instanceof Error ? error.message : 'Unknown error'
+ };
+ }
+});
+
+/**
+ * Get AI conversations for a book
+ */
+ipcMain.handle('db-get-conversations', (_event, bookId: string) => {
+ try {
+ const db = getDatabaseService();
+ const conversations = db.getConversations(bookId);
+ return { success: true, data: conversations };
+ } catch (error) {
+ console.error('Failed to get conversations:', error);
+ return {
+ success: false,
+ error: error instanceof Error ? error.message : 'Unknown error'
+ };
+ }
+});
+
+/**
+ * Save AI conversation
+ */
+ipcMain.handle('db-save-conversation', (_event, conversation: any, bookId: string) => {
+ try {
+ const db = getDatabaseService();
+ db.saveConversation(conversation, bookId);
+ return { success: true };
+ } catch (error) {
+ console.error('Failed to save conversation:', error);
+ return {
+ success: false,
+ error: error instanceof Error ? error.message : 'Unknown error'
+ };
+ }
+});
+
+/**
+ * Get sync status
+ */
+ipcMain.handle('db-get-sync-status', () => {
+ try {
+ const db = getDatabaseService();
+ const status = db.getSyncStatus();
+ return { success: true, data: status };
+ } catch (error) {
+ console.error('Failed to get sync status:', error);
+ return {
+ success: false,
+ error: error instanceof Error ? error.message : 'Unknown error'
+ };
+ }
+});
+
+/**
+ * Get pending changes
+ */
+ipcMain.handle('db-get-pending-changes', (_event, limit: number = 100) => {
+ try {
+ const db = getDatabaseService();
+ const changes = db.getPendingChanges(limit);
+ return { success: true, data: changes };
+ } catch (error) {
+ console.error('Failed to get pending changes:', error);
+ return {
+ success: false,
+ error: error instanceof Error ? error.message : 'Unknown error'
+ };
+ }
+});
+
app.whenReady().then(() => {
console.log('App ready, isDev:', isDev);
console.log('resourcesPath:', process.resourcesPath);
diff --git a/electron/preload.ts b/electron/preload.ts
index db9dff3..50017b4 100644
--- a/electron/preload.ts
+++ b/electron/preload.ts
@@ -12,4 +12,21 @@ contextBridge.exposeInMainWorld('electron', {
// Auth events
loginSuccess: (token: string) => ipcRenderer.send('login-success', token),
logout: () => ipcRenderer.send('logout'),
+
+ // Database operations
+ generateEncryptionKey: (userId: string) => ipcRenderer.invoke('generate-encryption-key', userId),
+ getUserEncryptionKey: (userId: string) => ipcRenderer.invoke('get-user-encryption-key', userId),
+ setUserEncryptionKey: (userId: string, encryptionKey: string) => ipcRenderer.invoke('set-user-encryption-key', userId, encryptionKey),
+ dbInitialize: (userId: string, encryptionKey: string) => ipcRenderer.invoke('db-initialize', userId, encryptionKey),
+ dbGetBooks: () => ipcRenderer.invoke('db-get-books'),
+ dbGetBook: (bookId: string) => ipcRenderer.invoke('db-get-book', bookId),
+ dbSaveBook: (book: any, authorId?: string) => ipcRenderer.invoke('db-save-book', book, authorId),
+ dbDeleteBook: (bookId: string) => ipcRenderer.invoke('db-delete-book', bookId),
+ dbSaveChapter: (chapter: any, bookId: string, contentId?: string) => ipcRenderer.invoke('db-save-chapter', chapter, bookId, contentId),
+ dbGetCharacters: (bookId: string) => ipcRenderer.invoke('db-get-characters', bookId),
+ dbSaveCharacter: (character: any, bookId: string) => ipcRenderer.invoke('db-save-character', character, bookId),
+ dbGetConversations: (bookId: string) => ipcRenderer.invoke('db-get-conversations', bookId),
+ dbSaveConversation: (conversation: any, bookId: string) => ipcRenderer.invoke('db-save-conversation', conversation, bookId),
+ dbGetSyncStatus: () => ipcRenderer.invoke('db-get-sync-status'),
+ dbGetPendingChanges: (limit?: number) => ipcRenderer.invoke('db-get-pending-changes', limit),
});
diff --git a/package-lock.json b/package-lock.json
index 7f4ffce..337afca 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -32,6 +32,7 @@
"next": "^16.0.3",
"next-export-i18n": "^2.4.3",
"next-intl": "^4.5.3",
+ "node-sqlite3-wasm": "^0.8.51",
"postcss": "^8.5.6",
"react": "^19.2.0",
"react-dom": "^19.2.0",
@@ -51,6 +52,8 @@
"concurrently": "^9.2.1",
"electron": "^39.2.1",
"electron-builder": "^26.0.12",
+ "electron-rebuild": "^3.2.9",
+ "electronmon": "^2.0.4",
"tsx": "^4.20.6",
"typescript": "^5.9.3",
"vite": "^7.2.2",
@@ -4760,6 +4763,28 @@
"node": ">= 10.0.0"
}
},
+ "node_modules/aproba": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.1.0.tgz",
+ "integrity": "sha512-tLIEcj5GuR2RSTnxNKdkK0dJ/GrC7P38sUkiDmDuHfsHmbagTFAxDVIBltoklXEVIQ/f14IL8IMJ5pn9Hez1Ew==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/are-we-there-yet": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-3.0.1.tgz",
+ "integrity": "sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg==",
+ "deprecated": "This package is no longer supported.",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "delegates": "^1.0.0",
+ "readable-stream": "^3.6.0"
+ },
+ "engines": {
+ "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
+ }
+ },
"node_modules/argparse": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
@@ -4963,6 +4988,19 @@
"concat-map": "0.0.1"
}
},
+ "node_modules/braces": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
+ "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fill-range": "^7.1.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/browserslist": {
"version": "4.28.0",
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.0.tgz",
@@ -5445,6 +5483,16 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/color-support": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz",
+ "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "color-support": "bin.js"
+ }
+ },
"node_modules/combined-stream": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
@@ -5668,6 +5716,13 @@
"node": ">=16 || 14 >=14.17"
}
},
+ "node_modules/console-control-strings": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
+ "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==",
+ "dev": true,
+ "license": "ISC"
+ },
"node_modules/convert-source-map": {
"version": "1.9.0",
"resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz",
@@ -5915,6 +5970,13 @@
"node": ">=0.4.0"
}
},
+ "node_modules/delegates": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
+ "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/detect-libc": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz",
@@ -6286,6 +6348,97 @@
"node": ">= 10.0.0"
}
},
+ "node_modules/electron-rebuild": {
+ "version": "3.2.9",
+ "resolved": "https://registry.npmjs.org/electron-rebuild/-/electron-rebuild-3.2.9.tgz",
+ "integrity": "sha512-FkEZNFViUem3P0RLYbZkUjC8LUFIK+wKq09GHoOITSJjfDAVQv964hwaNseTTWt58sITQX3/5fHNYcTefqaCWw==",
+ "deprecated": "Please use @electron/rebuild moving forward. There is no API change, just a package name change",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@malept/cross-spawn-promise": "^2.0.0",
+ "chalk": "^4.0.0",
+ "debug": "^4.1.1",
+ "detect-libc": "^2.0.1",
+ "fs-extra": "^10.0.0",
+ "got": "^11.7.0",
+ "lzma-native": "^8.0.5",
+ "node-abi": "^3.0.0",
+ "node-api-version": "^0.1.4",
+ "node-gyp": "^9.0.0",
+ "ora": "^5.1.0",
+ "semver": "^7.3.5",
+ "tar": "^6.0.5",
+ "yargs": "^17.0.1"
+ },
+ "bin": {
+ "electron-rebuild": "lib/src/cli.js"
+ },
+ "engines": {
+ "node": ">=12.13.0"
+ }
+ },
+ "node_modules/electron-rebuild/node_modules/fs-extra": {
+ "version": "10.1.0",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz",
+ "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "graceful-fs": "^4.2.0",
+ "jsonfile": "^6.0.1",
+ "universalify": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/electron-rebuild/node_modules/jsonfile": {
+ "version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.0.tgz",
+ "integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "universalify": "^2.0.0"
+ },
+ "optionalDependencies": {
+ "graceful-fs": "^4.1.6"
+ }
+ },
+ "node_modules/electron-rebuild/node_modules/node-api-version": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/node-api-version/-/node-api-version-0.1.4.tgz",
+ "integrity": "sha512-KGXihXdUChwJAOHO53bv9/vXcLmdUsZ6jIptbvYvkpKfth+r7jw44JkVxQFA3kX5nQjzjmGu1uAu/xNNLNlI5g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "semver": "^7.3.5"
+ }
+ },
+ "node_modules/electron-rebuild/node_modules/semver": {
+ "version": "7.7.3",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz",
+ "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/electron-rebuild/node_modules/universalify": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz",
+ "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 10.0.0"
+ }
+ },
"node_modules/electron-store": {
"version": "11.0.2",
"resolved": "https://registry.npmjs.org/electron-store/-/electron-store-11.0.2.tgz",
@@ -6378,6 +6531,39 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/electronmon": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/electronmon/-/electronmon-2.0.4.tgz",
+ "integrity": "sha512-u6eDrvUbqa+wsnMrhG2vHmo5neL1owLg2e5i1avGWcOb4rHsUf9lSfbs0FvfPsBNpLxxlPO98nrMhAGV+zw/fQ==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "chalk": "^3.0.0",
+ "import-from": "^3.0.0",
+ "runtime-required": "^1.1.0",
+ "watchboy": "^0.4.3"
+ },
+ "bin": {
+ "electronmon": "bin/cli.js"
+ },
+ "engines": {
+ "node": ">=10.0.0"
+ }
+ },
+ "node_modules/electronmon/node_modules/chalk": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz",
+ "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/emoji-regex": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
@@ -6702,6 +6888,19 @@
"node": ">=10"
}
},
+ "node_modules/fill-range": {
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
+ "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "to-regex-range": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/find-root": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz",
@@ -6846,6 +7045,27 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/gauge": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/gauge/-/gauge-4.0.4.tgz",
+ "integrity": "sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg==",
+ "deprecated": "This package is no longer supported.",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "aproba": "^1.0.3 || ^2.0.0",
+ "color-support": "^1.1.3",
+ "console-control-strings": "^1.1.0",
+ "has-unicode": "^2.0.1",
+ "signal-exit": "^3.0.7",
+ "string-width": "^4.2.3",
+ "strip-ansi": "^6.0.1",
+ "wide-align": "^1.1.5"
+ },
+ "engines": {
+ "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
+ }
+ },
"node_modules/gensync": {
"version": "1.0.0-beta.2",
"resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
@@ -7113,6 +7333,13 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/has-unicode": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz",
+ "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==",
+ "dev": true,
+ "license": "ISC"
+ },
"node_modules/hasown": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
@@ -7305,6 +7532,29 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/import-from": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/import-from/-/import-from-3.0.0.tgz",
+ "integrity": "sha512-CiuXOFFSzkU5x/CR0+z7T91Iht4CXgfCxVOFRhh2Zyhg5wOpWvvDLQUsWl+gcN+QscYBjez8hDCt85O7RLDttQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "resolve-from": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/import-from/node_modules/resolve-from": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
+ "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/imurmurhash": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
@@ -7434,6 +7684,16 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/is-number": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
+ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.12.0"
+ }
+ },
"node_modules/is-unicode-supported": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz",
@@ -7935,6 +8195,13 @@
"integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==",
"license": "MIT"
},
+ "node_modules/lodash.difference": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/lodash.difference/-/lodash.difference-4.5.0.tgz",
+ "integrity": "sha512-dS2j+W26TQ7taQBGN8Lbbq04ssV3emRw4NY58WErlTO29pIqS0HmoT5aJ9+TUQ1N3G+JOZSji4eugsWwGp9yPA==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/log-symbols": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz",
@@ -7975,6 +8242,32 @@
"node": ">=10"
}
},
+ "node_modules/lzma-native": {
+ "version": "8.0.6",
+ "resolved": "https://registry.npmjs.org/lzma-native/-/lzma-native-8.0.6.tgz",
+ "integrity": "sha512-09xfg67mkL2Lz20PrrDeNYZxzeW7ADtpYFbwSQh9U8+76RIzx5QsJBMy8qikv3hbUPfpy6hqwxt6FcGK81g9AA==",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "dependencies": {
+ "node-addon-api": "^3.1.0",
+ "node-gyp-build": "^4.2.1",
+ "readable-stream": "^3.6.0"
+ },
+ "bin": {
+ "lzmajs": "bin/lzmajs"
+ },
+ "engines": {
+ "node": ">=10.0.0"
+ }
+ },
+ "node_modules/lzma-native/node_modules/node-addon-api": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.2.1.tgz",
+ "integrity": "sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/magic-string": {
"version": "0.30.21",
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz",
@@ -8110,6 +8403,33 @@
"integrity": "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==",
"license": "MIT"
},
+ "node_modules/micromatch": {
+ "version": "4.0.8",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
+ "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "braces": "^3.0.3",
+ "picomatch": "^2.3.1"
+ },
+ "engines": {
+ "node": ">=8.6"
+ }
+ },
+ "node_modules/micromatch/node_modules/picomatch": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
+ "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
"node_modules/mime": {
"version": "2.6.0",
"resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz",
@@ -8592,12 +8912,69 @@
"node": ">=10"
}
},
+ "node_modules/node-gyp": {
+ "version": "9.4.1",
+ "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-9.4.1.tgz",
+ "integrity": "sha512-OQkWKbjQKbGkMf/xqI1jjy3oCTgMKJac58G2+bjZb3fza6gW2YrCSdMQYaoTb70crvE//Gngr4f0AgVHmqHvBQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "env-paths": "^2.2.0",
+ "exponential-backoff": "^3.1.1",
+ "glob": "^7.1.4",
+ "graceful-fs": "^4.2.6",
+ "make-fetch-happen": "^10.0.3",
+ "nopt": "^6.0.0",
+ "npmlog": "^6.0.0",
+ "rimraf": "^3.0.2",
+ "semver": "^7.3.5",
+ "tar": "^6.1.2",
+ "which": "^2.0.2"
+ },
+ "bin": {
+ "node-gyp": "bin/node-gyp.js"
+ },
+ "engines": {
+ "node": "^12.13 || ^14.13 || >=16"
+ }
+ },
+ "node_modules/node-gyp-build": {
+ "version": "4.8.4",
+ "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.4.tgz",
+ "integrity": "sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "node-gyp-build": "bin.js",
+ "node-gyp-build-optional": "optional.js",
+ "node-gyp-build-test": "build-test.js"
+ }
+ },
+ "node_modules/node-gyp/node_modules/semver": {
+ "version": "7.7.3",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz",
+ "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
"node_modules/node-releases": {
"version": "2.0.27",
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.27.tgz",
"integrity": "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==",
"license": "MIT"
},
+ "node_modules/node-sqlite3-wasm": {
+ "version": "0.8.51",
+ "resolved": "https://registry.npmjs.org/node-sqlite3-wasm/-/node-sqlite3-wasm-0.8.51.tgz",
+ "integrity": "sha512-tbUWEZLrGJwfi6eE6Xw+6GYRIQne4/C7uyh76hDI1tD88JfnLQCqPED8IvW0FVfrMNYuhYkO5a10XjI1du1kLg==",
+ "license": "MIT"
+ },
"node_modules/nopt": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/nopt/-/nopt-6.0.0.tgz",
@@ -8614,6 +8991,19 @@
"node": "^12.13.0 || ^14.15.0 || >=16.0.0"
}
},
+ "node_modules/normalize-path": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz",
+ "integrity": "sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "remove-trailing-separator": "^1.0.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/normalize-range": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz",
@@ -8636,6 +9026,23 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/npmlog": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-6.0.2.tgz",
+ "integrity": "sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg==",
+ "deprecated": "This package is no longer supported.",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "are-we-there-yet": "^3.0.0",
+ "console-control-strings": "^1.1.0",
+ "gauge": "^4.0.3",
+ "set-blocking": "^2.0.0"
+ },
+ "engines": {
+ "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
+ }
+ },
"node_modules/object-keys": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
@@ -8892,6 +9299,16 @@
"url": "https://github.com/sponsors/jonschlinkert"
}
},
+ "node_modules/pify": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz",
+ "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
"node_modules/plist": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/plist/-/plist-3.1.0.tgz",
@@ -10008,6 +10425,13 @@
"node": ">= 6"
}
},
+ "node_modules/remove-trailing-separator": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz",
+ "integrity": "sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw==",
+ "dev": true,
+ "license": "ISC"
+ },
"node_modules/require-directory": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
@@ -10218,6 +10642,16 @@
"integrity": "sha512-UT5EDe2cu2E/6O4igUr5PSFs23nvvukicWHx6GnOPlHAiiYbzNuCRQCuiUdHJQcqKalLKlrYJnjY0ySGsXNQXQ==",
"license": "MIT"
},
+ "node_modules/runtime-required": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/runtime-required/-/runtime-required-1.1.0.tgz",
+ "integrity": "sha512-yX97f5E0WfNpcQnfVjap6vzQcvErkYYCx6eTK4siqGEdC8lglwypUFgZVTX7ShvIlgfkC4XGFl9O1KTYcff0pw==",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": ">=4.0.0"
+ }
+ },
"node_modules/rxjs": {
"version": "7.8.2",
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz",
@@ -10323,6 +10757,13 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/set-blocking": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
+ "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==",
+ "dev": true,
+ "license": "ISC"
+ },
"node_modules/set-cookie-parser": {
"version": "2.7.2",
"resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.2.tgz",
@@ -10961,6 +11402,19 @@
"tmp": "^0.2.0"
}
},
+ "node_modules/to-regex-range": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
+ "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-number": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=8.0"
+ }
+ },
"node_modules/toggle-selection": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/toggle-selection/-/toggle-selection-1.0.6.tgz",
@@ -11102,6 +11556,19 @@
"node": ">= 4.0.0"
}
},
+ "node_modules/unixify": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/unixify/-/unixify-1.0.0.tgz",
+ "integrity": "sha512-6bc58dPYhCMHHuwxldQxO3RRNZ4eCogZ/st++0+fcC1nr0jiGUtAdBJ2qzmLQWSxbtz42pWt4QQMiZ9HvZf5cg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "normalize-path": "^2.1.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/update-browserslist-db": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.4.tgz",
@@ -11312,6 +11779,22 @@
"node": ">=20.0.0"
}
},
+ "node_modules/watchboy": {
+ "version": "0.4.3",
+ "resolved": "https://registry.npmjs.org/watchboy/-/watchboy-0.4.3.tgz",
+ "integrity": "sha512-GHs1HxwvxSMBsqd/WfTOZhj5gBdMqf5HQpfgtKxDfZRxrlYPDdVLRB61LCeRzJaWANmvSIMlfmRVDwVmJFgAKA==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "lodash.difference": "^4.5.0",
+ "micromatch": "^4.0.2",
+ "pify": "^4.0.1",
+ "unixify": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
"node_modules/wcwidth": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz",
@@ -11344,6 +11827,16 @@
"node": ">= 8"
}
},
+ "node_modules/wide-align": {
+ "version": "1.1.5",
+ "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz",
+ "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "string-width": "^1.0.2 || 2 || 3 || 4"
+ }
+ },
"node_modules/wrap-ansi": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
diff --git a/package.json b/package.json
index e606f3d..4829a4a 100644
--- a/package.json
+++ b/package.json
@@ -5,7 +5,7 @@
"type": "module",
"main": "dist/electron/main.js",
"scripts": {
- "dev": "concurrently \"next dev -p 4000\" \"wait-on http://localhost:4000 && electron -r tsx/cjs electron/main.ts\"",
+ "dev": "tsc -p tsconfig.electron.json && tsc -p tsconfig.preload.json && concurrently \"tsc -p tsconfig.electron.json -w\" \"tsc -p tsconfig.preload.json -w\" \"next dev -p 4000\" \"wait-on http://localhost:4000 && wait-on dist/electron/main.js && electron dist/electron/main.js\"",
"build:mac": "next build && tsc --project tsconfig.electron.json && tsc --project tsconfig.preload.json && electron-builder build --mac",
"build:win": "next build && tsc --project tsconfig.electron.json && tsc --project tsconfig.preload.json && electron-builder build --win",
"build:linux": "next build && tsc --project tsconfig.electron.json && tsc --project tsconfig.preload.json && electron-builder build --linux",
@@ -26,6 +26,8 @@
"concurrently": "^9.2.1",
"electron": "^39.2.1",
"electron-builder": "^26.0.12",
+ "electron-rebuild": "^3.2.9",
+ "electronmon": "^2.0.4",
"tsx": "^4.20.6",
"typescript": "^5.9.3",
"vite": "^7.2.2",
@@ -56,6 +58,7 @@
"next": "^16.0.3",
"next-export-i18n": "^2.4.3",
"next-intl": "^4.5.3",
+ "node-sqlite3-wasm": "^0.8.51",
"postcss": "^8.5.6",
"react": "^19.2.0",
"react-dom": "^19.2.0",
diff --git a/tsconfig.electron.json b/tsconfig.electron.json
index e324aa9..f58d065 100644
--- a/tsconfig.electron.json
+++ b/tsconfig.electron.json
@@ -20,6 +20,11 @@
"dist",
"src",
".next",
- "out"
+ "out",
+ "lib",
+ "components",
+ "app",
+ "context",
+ "electron/preload.ts"
]
}
diff --git a/tsconfig.preload.json b/tsconfig.preload.json
index 9e0cff6..49f9906 100644
--- a/tsconfig.preload.json
+++ b/tsconfig.preload.json
@@ -1,11 +1,20 @@
{
- "extends": "./tsconfig.electron.json",
"compilerOptions": {
"module": "CommonJS",
"moduleResolution": "node",
- "outDir": "dist/electron"
+ "target": "ES2022",
+ "outDir": "dist/electron",
+ "lib": ["ES2022"],
+ "esModuleInterop": true,
+ "skipLibCheck": true,
+ "strict": true,
+ "resolveJsonModule": true,
+ "noEmit": false
},
"include": [
"electron/preload.ts"
+ ],
+ "exclude": [
+ "node_modules"
]
}