From 4a0d5e99d0225abdfd18179e7f42c4c43820adef Mon Sep 17 00:00:00 2001 From: vorotamoroz Date: Wed, 11 Mar 2026 14:57:36 +0100 Subject: [PATCH] Fix import path and add readme --- src/apps/webapp/README.md | 181 ++++++++++++++++++ .../webapp/adapters/FSAPIConversionAdapter.ts | 4 +- .../webapp/adapters/FSAPIFileSystemAdapter.ts | 6 +- src/apps/webapp/adapters/FSAPIPathAdapter.ts | 4 +- .../webapp/adapters/FSAPIStorageAdapter.ts | 4 +- .../webapp/adapters/FSAPITypeGuardAdapter.ts | 2 +- src/apps/webapp/adapters/FSAPITypes.ts | 2 +- src/apps/webapp/adapters/FSAPIVaultAdapter.ts | 4 +- src/apps/webapp/main.ts | 30 +-- .../FSAPIStorageEventManagerAdapter.ts | 10 +- .../managers/StorageEventManagerFSAPI.ts | 9 +- src/apps/webapp/package.json | 4 - .../serviceModules/DatabaseFileAccess.ts | 4 +- .../serviceModules/FSAPIServiceModules.ts | 15 +- .../webapp/serviceModules/FileAccessFSAPI.ts | 2 +- .../serviceModules/ServiceFileAccessImpl.ts | 5 +- 16 files changed, 233 insertions(+), 53 deletions(-) create mode 100644 src/apps/webapp/README.md diff --git a/src/apps/webapp/README.md b/src/apps/webapp/README.md new file mode 100644 index 0000000..b0aba0a --- /dev/null +++ b/src/apps/webapp/README.md @@ -0,0 +1,181 @@ +# LiveSync WebApp +Browser-based implementation of Obsidian LiveSync using the FileSystem API. +Note: (I vrtmrz have not tested this so much yet). + +## Features + +- 🌐 Runs entirely in the browser +- 📁 Uses FileSystem API to access your local vault +- 🔄 Syncs with CouchDB, Object Storage server (compatible with Obsidian LiveSync plugin) +- 🚫 No server-side code required!! +- 💾 Settings stored in `.livesync/settings.json` within your vault +- 👁️ Real-time file watching (Chrome 124+ with FileSystemObserver) + +## Requirements + +- **FileSystem API support**: + - Chrome/Edge 86+ (required) + - Opera 72+ (required) + - Safari 15.2+ (experimental, limited support) + - Firefox: Not supported yet + +- **FileSystemObserver support** (optional, for real-time file watching): + - Chrome 124+ (recommended) + - Without this, files are only scanned on startup + +## Getting Started + +### Installation + +```bash +# Install dependencies (ensure you are in repository root directory, not src/apps/cli) +# due to shared dependencies with webapp and main library +npm install +``` + +### Development + +```bash +# Build the project (ensure you are in `src/apps/webapp` directory) +cd src/apps/webapp +npm run dev +``` + +This will start a development server at `http://localhost:3000`. + +### Build + +```bash +# Build the project (ensure you are in `src/apps/webapp` directory) +cd src/apps/webapp +npm run build +``` + +The built files will be in the `dist` directory. + +### Usage + +1. Open the webapp in your browser +2. Grant directory access when prompted +3. Configure CouchDB connection by editing `.livesync/settings.json` in your vault + - You can also copy data.json from Obsidian's plug-in folder. + +Example `.livesync/settings.json`: + +```json +{ + "couchDB_URI": "https://your-couchdb-server.com", + "couchDB_USER": "your-username", + "couchDB_PASSWORD": "your-password", + "couchDB_DBNAME": "your-database", + "isConfigured": true, + "liveSync": true, + "syncOnSave": true +} +``` + +After editing, reload the page. + +## Architecture + +### Directory Structure + +``` +webapp/ +├── adapters/ # FileSystem API adapters +│ ├── FSAPITypes.ts +│ ├── FSAPIPathAdapter.ts +│ ├── FSAPITypeGuardAdapter.ts +│ ├── FSAPIConversionAdapter.ts +│ ├── FSAPIStorageAdapter.ts +│ ├── FSAPIVaultAdapter.ts +│ └── FSAPIFileSystemAdapter.ts +├── managers/ # Event managers +│ ├── FSAPIStorageEventManagerAdapter.ts +│ └── StorageEventManagerFSAPI.ts +├── serviceModules/ # Service implementations +│ ├── FileAccessFSAPI.ts +│ ├── ServiceFileAccessImpl.ts +│ ├── DatabaseFileAccess.ts +│ └── FSAPIServiceModules.ts +├── main.ts # Application entry point +├── index.html # HTML entry +├── package.json +├── vite.config.ts +└── README.md +``` + +### Key Components + +1. **Adapters**: Implement `IFileSystemAdapter` interface using FileSystem API +2. **Managers**: Handle storage events and file watching +3. **Service Modules**: Integrate with LiveSyncBaseCore +4. **Main**: Application initialization and lifecycle management + +### Service Hub + +Uses `BrowserServiceHub` which provides: + +- Database service (IndexedDB via PouchDB) +- Settings service (file-based in `.livesync/settings.json`) +- Replication service +- File processing service +- And more... + +## Limitations + +- **Real-time file watching**: Requires Chrome 124+ with FileSystemObserver + - Without it, changes are only detected on manual refresh +- **Performance**: Slower than native file system access +- **Permissions**: Requires user to grant directory access (cached via IndexedDB) +- **Browser support**: Limited to browsers with FileSystem API support + +## Differences from CLI Version + +- Uses `BrowserServiceHub` instead of `HeadlessServiceHub` +- Uses FileSystem API instead of Node.js `fs` +- Settings stored in `.livesync/settings.json` in vault +- Real-time file watching only with FileSystemObserver (Chrome 124+) + +## Differences from Obsidian Plugin + +- No Obsidian-specific modules (UI, settings dialog, etc.) +- Simplified configuration +- No plugin/theme sync features +- No internal file handling (`.obsidian` folder) + +## Development Notes + +- TypeScript configuration: Uses project's tsconfig.json +- Module resolution: Aliased paths via Vite config +- External dependencies: Bundled by Vite + +## Troubleshooting + +### "Failed to get directory access" + +- Make sure you're using a supported browser +- Try refreshing the page +- Clear browser cache and IndexedDB + +### "Settings not found" + +- Check that `.livesync/settings.json` exists in your vault directory +- Verify the JSON format is valid +- Create the file manually if needed + +### "File watching not working" + +- Make sure you're using Chrome 124 or later +- Check browser console for FileSystemObserver messages +- Try manually triggering sync if automatic watching isn't available + +### "Sync not working" + +- Verify CouchDB credentials +- Check browser console for errors +- Ensure CouchDB server is accessible (CORS enabled) + +## License + +Same as the main Obsidian LiveSync project. diff --git a/src/apps/webapp/adapters/FSAPIConversionAdapter.ts b/src/apps/webapp/adapters/FSAPIConversionAdapter.ts index 7acd106..f0136ff 100644 --- a/src/apps/webapp/adapters/FSAPIConversionAdapter.ts +++ b/src/apps/webapp/adapters/FSAPIConversionAdapter.ts @@ -1,5 +1,5 @@ -import type { UXFileInfoStub, UXFolderInfo } from "../../../lib/src/common/types"; -import type { IConversionAdapter } from "../../../lib/src/serviceModules/adapters"; +import type { UXFileInfoStub, UXFolderInfo } from "@lib/common/types"; +import type { IConversionAdapter } from "@lib/serviceModules/adapters"; import type { FSAPIFile, FSAPIFolder } from "./FSAPITypes"; /** diff --git a/src/apps/webapp/adapters/FSAPIFileSystemAdapter.ts b/src/apps/webapp/adapters/FSAPIFileSystemAdapter.ts index 1c87b46..e2ebbf3 100644 --- a/src/apps/webapp/adapters/FSAPIFileSystemAdapter.ts +++ b/src/apps/webapp/adapters/FSAPIFileSystemAdapter.ts @@ -1,5 +1,5 @@ -import type { FilePath, UXStat } from "../../../lib/src/common/types"; -import type { IFileSystemAdapter } from "../../../lib/src/serviceModules/adapters"; +import type { FilePath, UXStat } from "@lib/common/types"; +import type { IFileSystemAdapter } from "@lib/serviceModules/adapters"; import { FSAPIPathAdapter } from "./FSAPIPathAdapter"; import { FSAPITypeGuardAdapter } from "./FSAPITypeGuardAdapter"; import { FSAPIConversionAdapter } from "./FSAPIConversionAdapter"; @@ -75,7 +75,7 @@ export class FSAPIFileSystemAdapter implements IFileSystemAdapter { const pathStr = this.normalisePath(p); diff --git a/src/apps/webapp/adapters/FSAPIPathAdapter.ts b/src/apps/webapp/adapters/FSAPIPathAdapter.ts index 640f3bf..06764fa 100644 --- a/src/apps/webapp/adapters/FSAPIPathAdapter.ts +++ b/src/apps/webapp/adapters/FSAPIPathAdapter.ts @@ -1,5 +1,5 @@ -import type { FilePath } from "../../../lib/src/common/types"; -import type { IPathAdapter } from "../../../lib/src/serviceModules/adapters"; +import type { FilePath } from "@lib/common/types"; +import type { IPathAdapter } from "@lib/serviceModules/adapters"; import type { FSAPIFile } from "./FSAPITypes"; /** diff --git a/src/apps/webapp/adapters/FSAPIStorageAdapter.ts b/src/apps/webapp/adapters/FSAPIStorageAdapter.ts index ec4fb81..6767410 100644 --- a/src/apps/webapp/adapters/FSAPIStorageAdapter.ts +++ b/src/apps/webapp/adapters/FSAPIStorageAdapter.ts @@ -1,5 +1,5 @@ -import type { UXDataWriteOptions } from "../../../lib/src/common/types"; -import type { IStorageAdapter } from "../../../lib/src/serviceModules/adapters"; +import type { UXDataWriteOptions } from "@lib/common/types"; +import type { IStorageAdapter } from "@lib/serviceModules/adapters"; import type { FSAPIStat } from "./FSAPITypes"; /** diff --git a/src/apps/webapp/adapters/FSAPITypeGuardAdapter.ts b/src/apps/webapp/adapters/FSAPITypeGuardAdapter.ts index 49e34a8..06fa9b1 100644 --- a/src/apps/webapp/adapters/FSAPITypeGuardAdapter.ts +++ b/src/apps/webapp/adapters/FSAPITypeGuardAdapter.ts @@ -1,4 +1,4 @@ -import type { ITypeGuardAdapter } from "../../../lib/src/serviceModules/adapters"; +import type { ITypeGuardAdapter } from "@lib/serviceModules/adapters"; import type { FSAPIFile, FSAPIFolder } from "./FSAPITypes"; /** diff --git a/src/apps/webapp/adapters/FSAPITypes.ts b/src/apps/webapp/adapters/FSAPITypes.ts index fd696a9..91b3407 100644 --- a/src/apps/webapp/adapters/FSAPITypes.ts +++ b/src/apps/webapp/adapters/FSAPITypes.ts @@ -1,4 +1,4 @@ -import type { FilePath, UXStat } from "../../../lib/src/common/types"; +import type { FilePath, UXStat } from "@lib/common/types"; /** * FileSystem API file representation diff --git a/src/apps/webapp/adapters/FSAPIVaultAdapter.ts b/src/apps/webapp/adapters/FSAPIVaultAdapter.ts index c709e47..acc6ebd 100644 --- a/src/apps/webapp/adapters/FSAPIVaultAdapter.ts +++ b/src/apps/webapp/adapters/FSAPIVaultAdapter.ts @@ -1,5 +1,5 @@ -import type { FilePath, UXDataWriteOptions } from "../../../lib/src/common/types"; -import type { IVaultAdapter } from "../../../lib/src/serviceModules/adapters"; +import type { FilePath, UXDataWriteOptions } from "@lib/common/types"; +import type { IVaultAdapter } from "@lib/serviceModules/adapters"; import type { FSAPIFile, FSAPIFolder } from "./FSAPITypes"; /** diff --git a/src/apps/webapp/main.ts b/src/apps/webapp/main.ts index b723395..a7ffcdd 100644 --- a/src/apps/webapp/main.ts +++ b/src/apps/webapp/main.ts @@ -3,16 +3,19 @@ * Browser-based version of Self-hosted LiveSync plugin using FileSystem API */ -import { BrowserServiceHub } from "../../lib/src/services/BrowserServices"; -import { LiveSyncBaseCore } from "../../LiveSyncBaseCore"; -import { ServiceContext } from "../../lib/src/services/base/ServiceBase"; +import { BrowserServiceHub } from "@lib/services/BrowserServices"; +import { LiveSyncBaseCore } from "@/LiveSyncBaseCore"; +import { ServiceContext } from "@lib/services/base/ServiceBase"; import { initialiseServiceModulesFSAPI } from "./serviceModules/FSAPIServiceModules"; -import type { ObsidianLiveSyncSettings } from "../../lib/src/common/types"; -import type { BrowserAPIService } from "../../lib/src/services/implements/browser/BrowserAPIService"; -import type { InjectableSettingService } from "../../lib/src/services/implements/injectable/InjectableSettingService"; -// import { SetupManager } from "@/modules/features/SetupManager"; +import type { ObsidianLiveSyncSettings } from "@lib/common/types"; +import type { BrowserAPIService } from "@lib/services/implements/browser/BrowserAPIService"; +import type { InjectableSettingService } from "@lib/services/implements/injectable/InjectableSettingService"; +import { useOfflineScanner } from "@lib/serviceFeatures/offlineScanner"; +import { useRedFlagFeatures } from "@/serviceFeatures/redFlag"; +import { useCheckRemoteSize } from "@lib/serviceFeatures/checkRemoteSize"; +import { SetupManager } from "@/modules/features/SetupManager"; // import { ModuleObsidianSettingsAsMarkdown } from "@/modules/features/ModuleObsidianSettingAsMarkdown"; -// import { ModuleSetupObsidian } from "@/modules/features/ModuleSetupObsidian"; +import { ModuleSetupObsidian } from "@/modules/features/ModuleSetupObsidian"; // import { ModuleObsidianMenu } from "@/modules/essentialObsidian/ModuleObsidianMenu"; const SETTINGS_DIR = ".livesync"; @@ -105,7 +108,8 @@ class LiveSyncWebApp { // new ModuleObsidianEvents(this, core), // new ModuleObsidianSettingDialogue(this, core), // new ModuleObsidianMenu(core), - // new ModuleSetupObsidian(core), + new ModuleSetupObsidian(core), + new SetupManager(core), // new ModuleObsidianSettingsAsMarkdown(core), // new ModuleLog(this, core), // new ModuleObsidianDocumentHistory(this, core), @@ -116,8 +120,12 @@ class LiveSyncWebApp { // new ModuleIntegratedTest(this, core), // new SetupManager(core), ], - () => [],// No add-ons - () => [], + () => [], // No add-ons + (core) => { + useOfflineScanner(core); + useRedFlagFeatures(core); + useCheckRemoteSize(core); + } ); // Start the core diff --git a/src/apps/webapp/managers/FSAPIStorageEventManagerAdapter.ts b/src/apps/webapp/managers/FSAPIStorageEventManagerAdapter.ts index 5977c58..e33f5e6 100644 --- a/src/apps/webapp/managers/FSAPIStorageEventManagerAdapter.ts +++ b/src/apps/webapp/managers/FSAPIStorageEventManagerAdapter.ts @@ -1,6 +1,6 @@ -import type { FilePath, UXFileInfoStub, UXInternalFileInfoStub } from "../../../lib/src/common/types"; -import type { FileEventItem } from "../../../lib/src/common/types"; -import type { IStorageEventManagerAdapter } from "../../../lib/src/managers/adapters"; +import type { FilePath, UXFileInfoStub, UXInternalFileInfoStub } from "@lib/common/types"; +import type { FileEventItem } from "@lib/common/types"; +import type { IStorageEventManagerAdapter } from "@lib/managers/adapters"; import type { IStorageEventTypeGuardAdapter, IStorageEventPersistenceAdapter, @@ -8,8 +8,8 @@ import type { IStorageEventStatusAdapter, IStorageEventConverterAdapter, IStorageEventWatchHandlers, -} from "../../../lib/src/managers/adapters"; -import type { FileEventItemSentinel } from "../../../lib/src/managers/StorageEventManager"; +} from "@lib/managers/adapters"; +import type { FileEventItemSentinel } from "@lib/managers/StorageEventManager"; import type { FSAPIFile, FSAPIFolder } from "../adapters/FSAPITypes"; /** diff --git a/src/apps/webapp/managers/StorageEventManagerFSAPI.ts b/src/apps/webapp/managers/StorageEventManagerFSAPI.ts index 1bbc483..fb2761f 100644 --- a/src/apps/webapp/managers/StorageEventManagerFSAPI.ts +++ b/src/apps/webapp/managers/StorageEventManagerFSAPI.ts @@ -1,10 +1,7 @@ -import { - StorageEventManagerBase, - type StorageEventManagerBaseDependencies, -} from "../../../lib/src/managers/StorageEventManager"; +import { StorageEventManagerBase, type StorageEventManagerBaseDependencies } from "@lib/managers/StorageEventManager"; import { FSAPIStorageEventManagerAdapter } from "./FSAPIStorageEventManagerAdapter"; -import type { IMinimumLiveSyncCommands, LiveSyncBaseCore } from "../../../LiveSyncBaseCore"; -import type { ServiceContext } from "../../../lib/src/services/base/ServiceBase"; +import type { IMinimumLiveSyncCommands, LiveSyncBaseCore } from "@/LiveSyncBaseCore"; +import type { ServiceContext } from "@lib/services/base/ServiceBase"; export class StorageEventManagerFSAPI extends StorageEventManagerBase { core: LiveSyncBaseCore; diff --git a/src/apps/webapp/package.json b/src/apps/webapp/package.json index 0e1f5b1..403e8ad 100644 --- a/src/apps/webapp/package.json +++ b/src/apps/webapp/package.json @@ -13,9 +13,5 @@ "devDependencies": { "typescript": "5.9.3", "vite": "^7.3.1" - }, - "imports": { - "../../src/worker/bgWorker.ts": "../../src/worker/bgWorker.mock.ts", - "@lib/worker/bgWorker.ts": "@lib/worker/bgWorker.mock.ts" } } diff --git a/src/apps/webapp/serviceModules/DatabaseFileAccess.ts b/src/apps/webapp/serviceModules/DatabaseFileAccess.ts index 6365042..346a9b6 100644 --- a/src/apps/webapp/serviceModules/DatabaseFileAccess.ts +++ b/src/apps/webapp/serviceModules/DatabaseFileAccess.ts @@ -1,8 +1,8 @@ import { ServiceDatabaseFileAccessBase, type ServiceDatabaseFileAccessDependencies, -} from "../../../lib/src/serviceModules/ServiceDatabaseFileAccessBase"; -import type { DatabaseFileAccess } from "../../../lib/src/interfaces/DatabaseFileAccess"; +} from "@lib/serviceModules/ServiceDatabaseFileAccessBase"; +import type { DatabaseFileAccess } from "@lib/interfaces/DatabaseFileAccess"; /** * FileSystem API-specific implementation of ServiceDatabaseFileAccess diff --git a/src/apps/webapp/serviceModules/FSAPIServiceModules.ts b/src/apps/webapp/serviceModules/FSAPIServiceModules.ts index 152422c..26a0a2f 100644 --- a/src/apps/webapp/serviceModules/FSAPIServiceModules.ts +++ b/src/apps/webapp/serviceModules/FSAPIServiceModules.ts @@ -1,14 +1,15 @@ -import type { InjectableServiceHub } from "../../../lib/src/services/implements/injectable/InjectableServiceHub"; -import { ServiceRebuilder } from "../../../lib/src/serviceModules/Rebuilder"; -import { ServiceFileHandler } from "../../../serviceModules/FileHandler"; -import { StorageAccessManager } from "../../../lib/src/managers/StorageProcessingManager"; -import type { ServiceModules } from "../../../types"; -import type { LiveSyncBaseCore } from "../../../LiveSyncBaseCore"; -import type { ServiceContext } from "../../../lib/src/services/base/ServiceBase"; +import type { InjectableServiceHub } from "@lib/services/implements/injectable/InjectableServiceHub"; +import { ServiceRebuilder } from "@lib/serviceModules/Rebuilder"; + +import { StorageAccessManager } from "@lib/managers/StorageProcessingManager"; +import type { LiveSyncBaseCore } from "@/LiveSyncBaseCore"; +import type { ServiceContext } from "@lib/services/base/ServiceBase"; import { FileAccessFSAPI } from "./FileAccessFSAPI"; import { ServiceFileAccessFSAPI } from "./ServiceFileAccessImpl"; import { ServiceDatabaseFileAccessFSAPI } from "./DatabaseFileAccess"; import { StorageEventManagerFSAPI } from "../managers/StorageEventManagerFSAPI"; +import type { ServiceModules } from "@lib/interfaces/ServiceModule"; +import { ServiceFileHandler } from "@/serviceModules/FileHandler"; /** * Initialize service modules for FileSystem API webapp version diff --git a/src/apps/webapp/serviceModules/FileAccessFSAPI.ts b/src/apps/webapp/serviceModules/FileAccessFSAPI.ts index 45e5660..9d1561e 100644 --- a/src/apps/webapp/serviceModules/FileAccessFSAPI.ts +++ b/src/apps/webapp/serviceModules/FileAccessFSAPI.ts @@ -1,4 +1,4 @@ -import { FileAccessBase, type FileAccessBaseDependencies } from "../../../lib/src/serviceModules/FileAccessBase"; +import { FileAccessBase, type FileAccessBaseDependencies } from "@lib/serviceModules/FileAccessBase"; import { FSAPIFileSystemAdapter } from "../adapters/FSAPIFileSystemAdapter"; /** diff --git a/src/apps/webapp/serviceModules/ServiceFileAccessImpl.ts b/src/apps/webapp/serviceModules/ServiceFileAccessImpl.ts index 4b6a474..f5396e2 100644 --- a/src/apps/webapp/serviceModules/ServiceFileAccessImpl.ts +++ b/src/apps/webapp/serviceModules/ServiceFileAccessImpl.ts @@ -1,7 +1,4 @@ -import { - ServiceFileAccessBase, - type StorageAccessBaseDependencies, -} from "../../../lib/src/serviceModules/ServiceFileAccessBase"; +import { ServiceFileAccessBase, type StorageAccessBaseDependencies } from "@lib/serviceModules/ServiceFileAccessBase"; import { FSAPIFileSystemAdapter } from "../adapters/FSAPIFileSystemAdapter"; /**