feat(w5): ship v2.0.0 platform sync, undo persistence, and updates
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,33 @@
|
||||
import { ipcMain } from 'electron'
|
||||
import { IPC } from '../../../shared/ipc-channels'
|
||||
import type { LogService } from '../../services/log.service'
|
||||
import { extensionRegistry } from '../../services/extension-registry'
|
||||
import { wrap } from '../result'
|
||||
|
||||
export function registerLogHandlers(logs: LogService): void {
|
||||
ipcMain.handle(IPC.LOG_HAD_CRASH, () => wrap(() => logs.hadCrashOnLastRun()))
|
||||
ipcMain.handle(IPC.LOG_CLEAR_CRASH, () =>
|
||||
wrap(() => {
|
||||
logs.clearCrashFlag()
|
||||
})
|
||||
)
|
||||
ipcMain.handle(IPC.LOG_SEND_REPORT, (_e, { note }: { note?: string }) =>
|
||||
wrap(() => logs.sendReportStub(note))
|
||||
)
|
||||
ipcMain.handle(IPC.LOG_WRITE_ERROR, (_e, { message }: { message: string }) =>
|
||||
wrap(() => {
|
||||
logs.logManualError(message)
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
export function registerExtensionHandlers(): void {
|
||||
ipcMain.handle(IPC.EXTENSION_LIST, () => wrap(() => extensionRegistry.list()))
|
||||
ipcMain.handle(IPC.EXTENSION_VALIDATE, (_e, { manifest }: { manifest: unknown }) =>
|
||||
wrap(() => extensionRegistry.validateManifest(manifest))
|
||||
)
|
||||
|
||||
ipcMain.handle(IPC.MCP_TEST_CONNECTION, (_e, { url }: { url: string }) =>
|
||||
wrap(() => ({ ok: true, message: `MCP stub: ${url || 'no url'}` }))
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
import { dialog, ipcMain } from 'electron'
|
||||
import { IPC } from '../../../shared/ipc-channels'
|
||||
import type { SyncConfigureInput, SyncRunInput } from '../../../shared/sync'
|
||||
import { SyncService } from '../../services/sync.service'
|
||||
import type { BookRegistryService } from '../../services/book-registry'
|
||||
import type { GlobalSettingsService } from '../../services/global-settings'
|
||||
import { wrap } from '../result'
|
||||
|
||||
let syncService: SyncService | null = null
|
||||
|
||||
function svc(registry: BookRegistryService, settings: GlobalSettingsService): SyncService {
|
||||
if (!syncService) {
|
||||
syncService = new SyncService(registry, settings, registry.getUserDataDir())
|
||||
}
|
||||
return syncService
|
||||
}
|
||||
|
||||
export function registerSyncHandlers(
|
||||
registry: BookRegistryService,
|
||||
settings: GlobalSettingsService
|
||||
): void {
|
||||
const service = () => svc(registry, settings)
|
||||
|
||||
ipcMain.handle(IPC.SYNC_STATUS, () => wrap(() => service().getStatus()))
|
||||
|
||||
ipcMain.handle(IPC.SYNC_CONFIGURE, (_e, input: SyncConfigureInput) =>
|
||||
wrap(() => service().configure(input))
|
||||
)
|
||||
|
||||
ipcMain.handle(IPC.SYNC_RUN, (_e, input: SyncRunInput) =>
|
||||
wrap(() => service().run(input.password, input.conflictResolution))
|
||||
)
|
||||
|
||||
ipcMain.handle(IPC.SYNC_PICK_FOLDER, async () =>
|
||||
wrap(async () => {
|
||||
const result = await dialog.showOpenDialog({ properties: ['openDirectory', 'createDirectory'] })
|
||||
if (result.canceled || !result.filePaths[0]) return null
|
||||
return result.filePaths[0]
|
||||
})
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
import { ipcMain } from 'electron'
|
||||
import { IPC } from '../../../shared/ipc-channels'
|
||||
import type { UndoOperation } from '../../../shared/undo'
|
||||
import { UndoStackService } from '../../services/undo-stack.service'
|
||||
import type { BookRegistryService } from '../../services/book-registry'
|
||||
import { wrap } from '../result'
|
||||
|
||||
export function registerUndoHandlers(registry: BookRegistryService): void {
|
||||
ipcMain.handle(
|
||||
IPC.UNDO_PUSH,
|
||||
(
|
||||
_e,
|
||||
{
|
||||
bookId,
|
||||
chapterId,
|
||||
operation
|
||||
}: { bookId: string; chapterId: string; operation: UndoOperation }
|
||||
) => wrap(() => new UndoStackService(registry.getDb(bookId)).push(chapterId, operation))
|
||||
)
|
||||
|
||||
ipcMain.handle(
|
||||
IPC.UNDO_LIST,
|
||||
(_e, { bookId, chapterId }: { bookId: string; chapterId: string }) =>
|
||||
wrap(() => new UndoStackService(registry.getDb(bookId)).list(chapterId))
|
||||
)
|
||||
|
||||
ipcMain.handle(
|
||||
IPC.UNDO_APPLY,
|
||||
(_e, { bookId, entryId }: { bookId: string; entryId: number }) =>
|
||||
wrap(() => {
|
||||
const op = new UndoStackService(registry.getDb(bookId)).apply(entryId)
|
||||
if (!op) throw new Error('Undo entry not found')
|
||||
return op
|
||||
})
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
import { ipcMain } from 'electron'
|
||||
import { IPC } from '../../../shared/ipc-channels'
|
||||
import { UpdateService } from '../../services/update.service'
|
||||
import { wrap } from '../result'
|
||||
|
||||
let updateService: UpdateService | null = null
|
||||
|
||||
function service(): UpdateService {
|
||||
if (!updateService) updateService = new UpdateService()
|
||||
return updateService
|
||||
}
|
||||
|
||||
export function registerUpdateHandlers(): void {
|
||||
ipcMain.handle(IPC.UPDATE_CHECK, () => wrap(() => service().check()))
|
||||
ipcMain.handle(IPC.UPDATE_DOWNLOAD, () => wrap(() => service().download()))
|
||||
ipcMain.handle(IPC.UPDATE_INSTALL, () =>
|
||||
wrap(() => {
|
||||
service().install()
|
||||
})
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user