feat: implement persistent rolling log system with tauri-plugin-log

This commit is contained in:
NimBold
2026-06-16 15:19:57 +03:30
parent 85cdabd72b
commit 4027ac39ab
9 changed files with 441 additions and 27 deletions
+5 -1
View File
@@ -1,4 +1,5 @@
import { invoke as tauriInvoke } from '@tauri-apps/api/core';
import { error as logError } from '@tauri-apps/plugin-log';
import { listen as tauriListen, type Event, type EventCallback, type UnlistenFn } from '@tauri-apps/api/event';
import type { DownloadCategory } from './bindings/DownloadCategory';
import type { DownloadProgressEvent } from './bindings/DownloadProgressEvent';
@@ -104,7 +105,10 @@ export function invokeCommand<K extends CommandName>(
command: K,
...args: CommandArgs<K> extends undefined ? [] : [args: CommandArgs<K>]
): Promise<CommandResult<K>> {
return tauriInvoke<CommandResult<K>>(command, args[0]);
return tauriInvoke<CommandResult<K>>(command, args[0]).catch(err => {
logError(`Invoke command ${command} failed: ${err}`);
throw err;
});
}
type EventMap = {
+13 -3
View File
@@ -1,6 +1,7 @@
import { create } from 'zustand';
import { persist, createJSONStorage, StateStorage } from 'zustand/middleware';
import { LazyStore } from '@tauri-apps/plugin-store';
import { info } from '@tauri-apps/plugin-log';
export const tauriStore = new LazyStore('store.bin');
@@ -49,9 +50,18 @@ export const useSettingsStore = create<SettingsState>()(
globalSpeedLimit: 0,
concurrentDownloads: 3,
setDefaultDownloadPath: (path) => set({ defaultDownloadPath: path }),
setGlobalSpeedLimit: (limit) => set({ globalSpeedLimit: limit }),
setConcurrentDownloads: (count) => set({ concurrentDownloads: count }),
setDefaultDownloadPath: (path) => {
info(`Settings updated: defaultDownloadPath = ${path}`);
set({ defaultDownloadPath: path });
},
setGlobalSpeedLimit: (limit) => {
info(`Settings updated: globalSpeedLimit = ${limit}`);
set({ globalSpeedLimit: limit });
},
setConcurrentDownloads: (count) => {
info(`Settings updated: concurrentDownloads = ${count}`);
set({ concurrentDownloads: count });
},
}),
{
name: 'firelink-engine-settings',
+8 -1
View File
@@ -1,5 +1,6 @@
import { create } from 'zustand';
import { LazyStore } from '@tauri-apps/plugin-store';
import { info } from '@tauri-apps/plugin-log';
import { invokeCommand as invoke } from '../ipc';
export const tauriStore = new LazyStore('store.bin');
@@ -140,7 +141,7 @@ export const useDownloadStore = create<DownloadState>((set, get) => ({
},
setSelectedPropertiesDownloadId: (id) => set({ selectedPropertiesDownloadId: id }),
addDownload: (item) => {
set((state) => ({ downloads: [...state.downloads, item] }));
info(`Download ${item.id} added to queue`);
set((state) => ({ downloads: [...state.downloads, item] }));
get().processQueue();
},
@@ -161,9 +162,11 @@ export const useDownloadStore = create<DownloadState>((set, get) => ({
// If status changed to something that frees up a slot, process queue
if (updates.status && ['completed', 'failed', 'paused'].includes(updates.status)) {
info(`Download ${id} status changed to ${updates.status}`);
get().processQueue();
syncSystemIntegrations();
} else if (updates.status === 'downloading') {
info(`Download ${id} status changed to downloading`);
syncSystemIntegrations();
}
},
@@ -187,6 +190,7 @@ export const useDownloadStore = create<DownloadState>((set, get) => ({
set((state) => ({
downloads: state.downloads.filter(d => d.id !== id)
}));
info(`Download ${id} removed`);
get().processQueue();
syncSystemIntegrations();
},
@@ -207,6 +211,7 @@ export const useDownloadStore = create<DownloadState>((set, get) => ({
if (wasDownloading) {
invoke('pause_download', { id }).catch(console.error);
}
info(`Download ${id} redownload requested (queued)`);
get().processQueue();
},
startQueue: async (queueId) => {
@@ -224,6 +229,7 @@ export const useDownloadStore = create<DownloadState>((set, get) => ({
)
}));
info(`Queue ${queueId} started, ${runnableIds.length} items queued`);
await get().processQueue();
return runnableIds.length;
},
@@ -242,6 +248,7 @@ export const useDownloadStore = create<DownloadState>((set, get) => ({
)
}));
info(`Queue ${queueId} paused, ${activeIds.length} items paused`);
await Promise.all(activeIds.map(id => invoke('pause_download', { id }).catch(() => {})));
syncSystemIntegrations();
return activeIds.length;
+14 -7
View File
@@ -1,6 +1,7 @@
import { create } from 'zustand';
import { persist, createJSONStorage, StateStorage } from 'zustand/middleware';
import { invokeCommand as invoke } from '../ipc';
import { info } from '@tauri-apps/plugin-log';
import type { ActiveView } from '../bindings/ActiveView';
import type { AppFontSize } from '../bindings/AppFontSize';
import type { ListRowDensity } from '../bindings/ListRowDensity';
@@ -232,12 +233,14 @@ export const useSettingsStore = create<SettingsState>()(
extensionPairingToken: generateSecureToken(),
autoCheckUpdates: true,
setTheme: (theme) => set({ theme }),
setDefaultDownloadPath: (path) => set({ defaultDownloadPath: path }),
setTheme: (theme) => { info('Settings updated: theme'); set({ theme }); },
setDefaultDownloadPath: (path) => { info('Settings updated: defaultDownloadPath'); set({ defaultDownloadPath: path }); },
setMaxConcurrentDownloads: (max) => {
info('Settings updated: maxConcurrentDownloads');
set({ maxConcurrentDownloads: max });
},
setGlobalSpeedLimit: (limit) => {
info('Settings updated: globalSpeedLimit');
set({ globalSpeedLimit: limit });
},
setActiveView: (view) => set({ activeView: view }),
@@ -266,14 +269,18 @@ export const useSettingsStore = create<SettingsState>()(
setCustomUserAgent: (customUserAgent) => set({ customUserAgent }),
setAskWhereToSaveEachFile: (askWhereToSaveEachFile) => set({ askWhereToSaveEachFile }),
setPreventsSleepWhileDownloading: (preventsSleepWhileDownloading) => {
info('Settings updated: preventsSleepWhileDownloading');
set({ preventsSleepWhileDownloading });
if (!preventsSleepWhileDownloading) invoke('set_prevent_sleep', { prevent: false }).catch(console.error);
},
setMediaCookieSource: (mediaCookieSource) => set({ mediaCookieSource }),
setCategoryDirectory: (category, path) => set((state) => ({
downloadDirectories: { ...state.downloadDirectories, [category]: path }
})),
resetCategoryDirectories: () => set({ downloadDirectories: { ...defaultDirectories } }),
setMediaCookieSource: (mediaCookieSource) => { info('Settings updated: mediaCookieSource'); set({ mediaCookieSource }); },
setCategoryDirectory: (category, path) => {
info(`Settings updated: category directory ${category}`);
set((state) => ({
downloadDirectories: { ...state.downloadDirectories, [category]: path }
}));
},
resetCategoryDirectories: () => { info('Settings updated: resetCategoryDirectories'); set({ downloadDirectories: { ...defaultDirectories } }); },
addSiteLogin: (login) => set((state) => ({
siteLogins: [...state.siteLogins, login]
})),