From 931d360fb1694e9d2ad1b2ecc775794f1dfcc65a Mon Sep 17 00:00:00 2001 From: vorotamoroz Date: Wed, 14 Jan 2026 09:41:16 +0000 Subject: [PATCH] Add summary note --- devs.md | 140 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 140 insertions(+) create mode 100644 devs.md diff --git a/devs.md b/devs.md new file mode 100644 index 0000000..33c2c7b --- /dev/null +++ b/devs.md @@ -0,0 +1,140 @@ +# Self-hosted LiveSync Development Guide +## Project Overview + +Self-hosted LiveSync is an Obsidian plugin for synchronising vaults across devices using CouchDB, MinIO/S3, or peer-to-peer WebRTC. The codebase uses a modular architecture with TypeScript, Svelte, and PouchDB. + +## Architecture + +### Module System + +The plugin uses a dynamic module system to reduce coupling and improve maintainability: + +- **Service Hub**: Central registry for services using dependency injection + - Services are registered, and accessed via `this.services` (in most modules) +- **Module Loading**: All modules extend `AbstractModule` or `AbstractObsidianModule` (which extends `AbstractModule`). These modules are loaded in main.ts and some modules +- **Module Categories** (by directory): + - `core/` - Platform-independent core functionality + - `coreObsidian/` - Obsidian-specific core (e.g., `ModuleFileAccessObsidian`) + - `essential/` - Required modules (e.g., `ModuleMigration`, `ModuleKeyValueDB`) + - `features/` - Optional features (e.g., `ModuleLog`, `ModuleObsidianSettings`) + - `extras/` - Development/testing tools (e.g., `ModuleDev`, `ModuleIntegratedTest`) + +### Key Architectural Components + +- **LiveSyncLocalDB** (`src/lib/src/pouchdb/`): Local PouchDB database wrapper +- **Replicators** (`src/lib/src/replication/`): CouchDB, Journal, and MinIO sync engines +- **Service Hub** (`src/modules/services/`): Central service registry using dependency injection +- **Common Library** (`src/lib/`): Platform-independent sync logic, shared with other tools + +### File Structure Conventions + +- **Platform-specific code**: Use `.platform.ts` suffix (replaced with `.obsidian.ts` in production builds via esbuild) +- **Development code**: Use `.dev.ts` suffix (replaced with `.prod.ts` in production) +- **Path aliases**: `@/*` maps to `src/*`, `@lib/*` maps to `src/lib/src/*` + +## Build & Development Workflow + +### Commands + +```bash +npm run check # TypeScript and svelte type checking +npm run dev # Development build with auto-rebuild (uses .env for test vault paths) +npm run build # Production build +npm run buildDev # Development build (one-time) +npm run bakei18n # Pre-build step: compile i18n resources (YAML → JSON → TS) +npm test # Run vitest tests (requires Docker services) +``` + +### Environment Setup + +- Create `.env` file with `PATHS_TEST_INSTALL` pointing to test vault plug-in directories (`:` separated on Unix, `;` on Windows) +- Development builds auto-copy to these paths on build + +### Testing Infrastructure + +- **Deno Tests**: Unit tests for platform-independent code (e.g., `HashManager.test.ts`) +- **Vitest** (`vitest.config.ts`): E2E test by Browser-based-harness using Playwright +- **Docker Services**: Tests require CouchDB, MinIO (S3), and P2P services: + ```bash + npm run test:docker-all:start # Start all test services + npm run test:full # Run tests with coverage + npm run test:docker-all:stop # Stop services + ``` + If some services are not needed, start only required ones (e.g., `test:docker-couchdb:start`) + Note that if services are already running, starting script will fail. Please stop them first. +- **Test Structure**: + - `test/suite/` - Integration tests for sync operations + - `test/unit/` - Unit tests (via vitest, as harness is browser-based) + - `test/harness/` - Mock implementations (e.g., `obsidian-mock.ts`) + +## Code Conventions + +### Internationalisation (i18n) + +- **Translation Workflow**: + 1. Edit YAML files in `src/lib/src/common/messagesYAML/` (human-editable) + 2. Run `npm run bakei18n` to compile: YAML → JSON → TypeScript constants + 3. Use `$t()`, `$msg()` functions for translations + You can also use `$f` for formatted messages with Tagged Template Literals. +- **Usage**: + ```typescript + $msg("dialog.someKey"); // Typed key with autocomplete + $t("Some message"); // Direct translation + $f`Hello, ${userName}`; // Formatted message + ``` +- **Supported languages**: `def` (English), `de`, `es`, `ja`, `ko`, `ru`, `zh`, `zh-tw` + +### File Path Handling + +- Use tagged types from `types.ts`: `FilePath`, `FilePathWithPrefix`, `DocumentID` +- Prefix constants: `CHeader` (chunks), `ICHeader`/`ICHeaderEnd` (internal data) +- Path utilities in `src/lib/src/string_and_binary/path.ts`: `addPrefix()`, `stripAllPrefixes()`, `shouldBeIgnored()` + +### Logging & Debugging + +- Use `this._log(msg, LOG_LEVEL_INFO)` in modules (automatically prefixes with module name) +- Log levels: `LOG_LEVEL_DEBUG`, `LOG_LEVEL_VERBOSE`, `LOG_LEVEL_INFO`, `LOG_LEVEL_NOTICE`, `LOG_LEVEL_URGENT` + - LOG_LEVEL_NOTICE and above are reported to the user via Obsidian notices + - LOG_LEVEL_DEBUG is for debug only and not shown in default builds +- Dev mode creates `ls-debug/` folder in `.obsidian/` for debug outputs (e.g., missing translations) + - This causes pretty significant performance overhead. + +## Common Patterns + +### Module Implementation + +```typescript +export class ModuleExample extends AbstractObsidianModule { + async _everyOnloadStart(): Promise { + /* ... */ + } + + onBindFunction(core: LiveSyncCore, services: typeof core.services): void { + services.appLifecycle.handleOnInitialise(this._everyOnloadStart.bind(this)); + } +} +``` + +### Settings Management + +- Settings defined in `src/lib/src/common/types.ts` (`ObsidianLiveSyncSettings`) +- Configuration metadata in `src/lib/src/common/settingConstants.ts` +- Use `this.services.setting.saveSettingData()` instead of using plugin methods directly + +### Database Operations + +- Local database operations through `LiveSyncLocalDB` (wraps PouchDB) +- Document types: `EntryDoc` (files), `EntryLeaf` (chunks), `PluginDataEntry` (plugin sync) + +## Important Files + +- [main.ts](src/main.ts) - Plugin entry point, module registration +- [esbuild.config.mjs](esbuild.config.mjs) - Build configuration with platform/dev file replacement +- [package.json](package.json) - Scripts reference and dependencies + +## Contribution Guidelines + +- Follow existing code style and conventions +- Please bump dependencies with care, check artifacts after updates, with diff-tools and only expected changes in the build output (to avoid unexpected vulnerabilities). +- When adding new features, please consider it has an OSS implementation, and avoid using proprietary services or APIs that may limit usage. + - For example, any functionality to connect to a new type of server is expected to either have an OSS implementation available for that server, or to be managed under some responsibilities and/or limitations without disrupting existing functionality, and scope for surveillance reduced by some means (e.g., by client-side encryption, auditing the server ourselves).