From 876008ef014d20e2b69dd68ede4fa3b92c5dff64 Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Sun, 12 Apr 2026 18:01:31 +0300 Subject: [PATCH] refactor(backup): keep only one implementation in core with abstract methods --- .../src/lightweight/backup_provider.ts | 20 ++++++++++++ .../src/local-server-worker.ts | 5 +++ apps/client-standalone/src/test_setup.ts | 2 ++ packages/trilium-core/src/index.ts | 2 +- packages/trilium-core/src/services/backup.ts | 31 ++++++++----------- 5 files changed, 41 insertions(+), 19 deletions(-) create mode 100644 apps/client-standalone/src/lightweight/backup_provider.ts diff --git a/apps/client-standalone/src/lightweight/backup_provider.ts b/apps/client-standalone/src/lightweight/backup_provider.ts new file mode 100644 index 0000000000..a4dd102538 --- /dev/null +++ b/apps/client-standalone/src/lightweight/backup_provider.ts @@ -0,0 +1,20 @@ +import { BackupService } from "@triliumnext/core"; + +/** + * No-op backup service for standalone. + * Backups are not yet implemented in standalone mode. + */ +export default class NoopBackupService extends BackupService { + override async backupNow(name: string): Promise { + console.warn("Backup not available in standalone mode."); + return `backup-${name}-${new Date().toISOString()}.db`; + } + + override regularBackup(): void { + // No-op - scheduled backups not available in standalone + } + + override getExistingBackups(): [] { + return []; + } +} diff --git a/apps/client-standalone/src/local-server-worker.ts b/apps/client-standalone/src/local-server-worker.ts index a238ee0073..e6bd9265f1 100644 --- a/apps/client-standalone/src/local-server-worker.ts +++ b/apps/client-standalone/src/local-server-worker.ts @@ -59,6 +59,7 @@ let BrowserZipProvider: typeof import('./lightweight/zip_provider').default; let FetchRequestProvider: typeof import('./lightweight/request_provider').default; let StandalonePlatformProvider: typeof import('./lightweight/platform_provider').default; let StandaloneLogService: typeof import('./lightweight/log_provider').default; +let NoopBackupService: typeof import('./lightweight/backup_provider').default; let translationProvider: typeof import('./lightweight/translation_provider').default; let createConfiguredRouter: typeof import('./lightweight/browser_routes').createConfiguredRouter; @@ -88,6 +89,7 @@ async function loadModules(): Promise { requestModule, platformModule, logModule, + backupModule, translationModule, routesModule ] = await Promise.all([ @@ -99,6 +101,7 @@ async function loadModules(): Promise { import('./lightweight/request_provider.js'), import('./lightweight/platform_provider.js'), import('./lightweight/log_provider.js'), + import('./lightweight/backup_provider.js'), import('./lightweight/translation_provider.js'), import('./lightweight/browser_routes.js') ]); @@ -111,6 +114,7 @@ async function loadModules(): Promise { FetchRequestProvider = requestModule.default; StandalonePlatformProvider = platformModule.default; StandaloneLogService = logModule.default; + NoopBackupService = backupModule.default; translationProvider = translationModule.default; createConfiguredRouter = routesModule.createConfiguredRouter; @@ -172,6 +176,7 @@ async function initialize(): Promise { request: new FetchRequestProvider(), platform: new StandalonePlatformProvider(queryString), log: logService, + backup: new NoopBackupService(), translations: translationProvider, schema: schemaModule.default, getDemoArchive: async () => { diff --git a/apps/client-standalone/src/test_setup.ts b/apps/client-standalone/src/test_setup.ts index cd77c0a416..0b93dd0c12 100644 --- a/apps/client-standalone/src/test_setup.ts +++ b/apps/client-standalone/src/test_setup.ts @@ -8,6 +8,7 @@ import HappyDomHtmlParser from "happy-dom/lib/html-parser/HTMLParser.js"; import serverEnTranslations from "../../server/src/assets/translations/en/server.json"; import { beforeAll } from "vitest"; +import NoopBackupService from "./lightweight/backup_provider.js"; import BrowserExecutionContext from "./lightweight/cls_provider.js"; import BrowserCryptoProvider from "./lightweight/crypto_provider.js"; import StandalonePlatformProvider from "./lightweight/platform_provider.js"; @@ -129,6 +130,7 @@ beforeAll(async () => { }); }, platform: new StandalonePlatformProvider(""), + backup: new NoopBackupService(), schema: schemaSql, dbConfig: { provider: sqlProvider, diff --git a/packages/trilium-core/src/index.ts b/packages/trilium-core/src/index.ts index 0f3ecfee12..7753281615 100644 --- a/packages/trilium-core/src/index.ts +++ b/packages/trilium-core/src/index.ts @@ -142,7 +142,7 @@ export async function initializeCore({ dbConfig, executionContext, crypto, zip, dataDirectory: string; }; log?: LogService; - backup?: BackupService; + backup: BackupService; }) { initPlatform(platform); initLog(log); diff --git a/packages/trilium-core/src/services/backup.ts b/packages/trilium-core/src/services/backup.ts index dd25b467cf..ee09d1441b 100644 --- a/packages/trilium-core/src/services/backup.ts +++ b/packages/trilium-core/src/services/backup.ts @@ -1,49 +1,44 @@ import type { DatabaseBackup } from "@triliumnext/commons"; /** - * Base backup service class. - * Provides default (no-op) implementations. - * Platform-specific implementations extend this class. + * Abstract backup service class. + * Platform-specific implementations must extend this class. */ -export default class BackupService { +export default abstract class BackupService { /** * Create a backup with the given name. * Returns the backup file path/name. */ - async backupNow(name: string): Promise { - console.warn("Backup not available - no backup provider configured."); - return `backup-${name}-${new Date().toISOString()}.db`; - } + abstract backupNow(name: string): Promise; /** * Perform regular scheduled backups (daily, weekly, monthly). * Called periodically by the scheduler. */ - regularBackup(): void { - // No-op in base implementation - } + abstract regularBackup(): void; /** * Get list of existing backups. - * Returns empty array if not supported. */ - getExistingBackups(): DatabaseBackup[] { - return []; - } + abstract getExistingBackups(): DatabaseBackup[]; } -let backupService: BackupService = new BackupService(); +let backupService: BackupService | undefined; /** * Get the current backup service instance. + * Throws if no provider has been initialized. */ export function getBackup(): BackupService { + if (!backupService) { + throw new Error("Backup service not initialized. Call initBackup() first."); + } return backupService; } /** * Initialize the backup service with a platform-specific provider. */ -export function initBackup(provider?: BackupService): void { - backupService = provider ?? new BackupService(); +export function initBackup(provider: BackupService): void { + backupService = provider; }