mirror of
https://github.com/vrtmrz/obsidian-livesync.git
synced 2026-04-05 08:35:19 +00:00
Fix import path and add readme
This commit is contained in:
181
src/apps/webapp/README.md
Normal file
181
src/apps/webapp/README.md
Normal file
@@ -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.
|
||||
@@ -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";
|
||||
|
||||
/**
|
||||
|
||||
@@ -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<FSAPIFile, FSA
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
*/
|
||||
async getAbstractFileByPathInsensitive(p: FilePath | string): Promise<FSAPIFile | null> {
|
||||
const pathStr = this.normalisePath(p);
|
||||
|
||||
@@ -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";
|
||||
|
||||
/**
|
||||
|
||||
@@ -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";
|
||||
|
||||
/**
|
||||
|
||||
@@ -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";
|
||||
|
||||
/**
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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";
|
||||
|
||||
/**
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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";
|
||||
|
||||
/**
|
||||
|
||||
@@ -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<FSAPIStorageEventManagerAdapter> {
|
||||
core: LiveSyncBaseCore<ServiceContext, IMinimumLiveSyncCommands>;
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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";
|
||||
|
||||
/**
|
||||
|
||||
@@ -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";
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user