mirror of
https://github.com/MODSetter/SurfSense.git
synced 2026-04-25 00:36:31 +02:00
feat: add seedFolderMtimes API for seeding file modification times during folder synchronization
This commit is contained in:
parent
e8c2377824
commit
d009d06432
6 changed files with 48 additions and 0 deletions
|
|
@ -31,6 +31,7 @@ export const IPC_CHANNELS = {
|
|||
FOLDER_SYNC_GET_PENDING_EVENTS: 'folder-sync:get-pending-events',
|
||||
FOLDER_SYNC_ACK_EVENTS: 'folder-sync:ack-events',
|
||||
FOLDER_SYNC_LIST_FILES: 'folder-sync:list-files',
|
||||
FOLDER_SYNC_SEED_MTIMES: 'folder-sync:seed-mtimes',
|
||||
BROWSE_FILES: 'browse:files',
|
||||
READ_LOCAL_FILES: 'browse:read-local-files',
|
||||
// Auth token sync across windows
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ import {
|
|||
browseFiles,
|
||||
readLocalFiles,
|
||||
listFolderFiles,
|
||||
seedFolderMtimes,
|
||||
type WatchedFolderConfig,
|
||||
} from '../modules/folder-watcher';
|
||||
import { getShortcuts, setShortcuts, type ShortcutConfig } from '../modules/shortcuts';
|
||||
|
|
@ -97,6 +98,12 @@ export function registerIpcHandlers(): void {
|
|||
listFolderFiles(config)
|
||||
);
|
||||
|
||||
ipcMain.handle(
|
||||
IPC_CHANNELS.FOLDER_SYNC_SEED_MTIMES,
|
||||
(_event, folderPath: string, mtimes: Record<string, number>) =>
|
||||
seedFolderMtimes(folderPath, mtimes),
|
||||
);
|
||||
|
||||
ipcMain.handle(IPC_CHANNELS.BROWSE_FILES, () => browseFiles());
|
||||
|
||||
ipcMain.handle(IPC_CHANNELS.READ_LOCAL_FILES, (_event, paths: string[]) =>
|
||||
|
|
|
|||
|
|
@ -449,14 +449,30 @@ export async function acknowledgeFileEvents(eventIds: string[]): Promise<{ ackno
|
|||
|
||||
const ackSet = new Set(eventIds);
|
||||
let acknowledged = 0;
|
||||
const foldersToUpdate = new Set<string>();
|
||||
|
||||
for (const [key, event] of outboxEvents.entries()) {
|
||||
if (ackSet.has(event.id)) {
|
||||
if (event.action !== 'unlink') {
|
||||
const map = mtimeMaps.get(event.folderPath);
|
||||
if (map) {
|
||||
try {
|
||||
map[event.relativePath] = fs.statSync(event.fullPath).mtimeMs;
|
||||
foldersToUpdate.add(event.folderPath);
|
||||
} catch {
|
||||
// File may have been removed
|
||||
}
|
||||
}
|
||||
}
|
||||
outboxEvents.delete(key);
|
||||
acknowledged += 1;
|
||||
}
|
||||
}
|
||||
|
||||
for (const fp of foldersToUpdate) {
|
||||
persistMtimeMap(fp);
|
||||
}
|
||||
|
||||
if (acknowledged > 0) {
|
||||
persistOutbox();
|
||||
}
|
||||
|
|
@ -464,6 +480,17 @@ export async function acknowledgeFileEvents(eventIds: string[]): Promise<{ ackno
|
|||
return { acknowledged };
|
||||
}
|
||||
|
||||
export async function seedFolderMtimes(
|
||||
folderPath: string,
|
||||
mtimes: Record<string, number>,
|
||||
): Promise<void> {
|
||||
const ms = await getMtimeStore();
|
||||
const existing: MtimeMap = ms.get(folderPath) ?? {};
|
||||
const merged = { ...existing, ...mtimes };
|
||||
mtimeMaps.set(folderPath, merged);
|
||||
ms.set(folderPath, merged);
|
||||
}
|
||||
|
||||
export async function pauseWatcher(): Promise<void> {
|
||||
for (const [, entry] of watchers) {
|
||||
if (entry.watcher) {
|
||||
|
|
|
|||
|
|
@ -65,6 +65,8 @@ contextBridge.exposeInMainWorld('electronAPI', {
|
|||
getPendingFileEvents: () => ipcRenderer.invoke(IPC_CHANNELS.FOLDER_SYNC_GET_PENDING_EVENTS),
|
||||
acknowledgeFileEvents: (eventIds: string[]) => ipcRenderer.invoke(IPC_CHANNELS.FOLDER_SYNC_ACK_EVENTS, eventIds),
|
||||
listFolderFiles: (config: any) => ipcRenderer.invoke(IPC_CHANNELS.FOLDER_SYNC_LIST_FILES, config),
|
||||
seedFolderMtimes: (folderPath: string, mtimes: Record<string, number>) =>
|
||||
ipcRenderer.invoke(IPC_CHANNELS.FOLDER_SYNC_SEED_MTIMES, folderPath, mtimes),
|
||||
|
||||
// Browse files via native dialog
|
||||
browseFiles: () => ipcRenderer.invoke(IPC_CHANNELS.BROWSE_FILES),
|
||||
|
|
|
|||
|
|
@ -212,5 +212,15 @@ export async function uploadFolderScan(params: FolderSyncParams): Promise<number
|
|||
|
||||
params.onProgress?.({ phase: "done", uploaded: entriesToUpload.length, total: entriesToUpload.length });
|
||||
|
||||
// Seed the Electron mtime store so the reconciliation scan in
|
||||
// startWatcher won't re-emit events for files we just indexed.
|
||||
if (api.seedFolderMtimes) {
|
||||
const mtimes: Record<string, number> = {};
|
||||
for (const f of allFiles) {
|
||||
mtimes[f.relativePath] = f.mtimeMs;
|
||||
}
|
||||
await api.seedFolderMtimes(folderPath, mtimes);
|
||||
}
|
||||
|
||||
return rootFolderId;
|
||||
}
|
||||
|
|
|
|||
1
surfsense_web/types/window.d.ts
vendored
1
surfsense_web/types/window.d.ts
vendored
|
|
@ -90,6 +90,7 @@ interface ElectronAPI {
|
|||
getPendingFileEvents: () => Promise<FolderSyncFileChangedEvent[]>;
|
||||
acknowledgeFileEvents: (eventIds: string[]) => Promise<{ acknowledged: number }>;
|
||||
listFolderFiles: (config: WatchedFolderConfig) => Promise<FolderFileEntry[]>;
|
||||
seedFolderMtimes: (folderPath: string, mtimes: Record<string, number>) => Promise<void>;
|
||||
// Browse files/folders via native dialogs
|
||||
browseFiles: () => Promise<string[] | null>;
|
||||
readLocalFiles: (paths: string[]) => Promise<LocalFileData[]>;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue