diff --git a/README.md b/README.md
index 755d96d..698872d 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,5 @@
# Self-hosted LiveSync
+
**Renamed from: obsidian-livesync**
This is the obsidian plugin that enables livesync between multi-devices with self-hosted database.
@@ -11,7 +12,7 @@ Community implementation, not compatible with official "Sync".
**It's getting almost stable now, But Please make sure to back your vault up!**
-Limitations: Folder deletion handling is not completed.
+Limitations: ~~Folder deletion handling is not completed.~~ **It would work now.**
## This plugin enables..
@@ -77,7 +78,6 @@ Note: The figure is drawn as single-directional, between two devices. But everyt

-
## Cloudant Setup
### Creating an Instance
@@ -105,7 +105,7 @@ Select Multitenant(it's the default) and the region as you like.

7. In resource details, there's information to connect from self-hosted-livesync.
- Copy the "External Endpoint(preferred)" address. (\*1)
+ Copy the "External Endpoint(preferred)" address. (\*1). We use this address later, with the database name.

### CouchDB setup
@@ -120,11 +120,13 @@ Select Multitenant(it's the default) and the region as you like.
_NOTE: of course We want to set "app://obsidian.md" but it's not acceptable on Cloudant._

-1. And open the "Databases" tab and hit the "Create Database" button.
+1. And open the "Databases" tab and hit the "Create Database" button.
Enter the name as you like (\*2) and Hit the "Create" button below.

-1. If the database was shown with joyful messages, then you can close this browser tab now.
+1. If the database was shown with joyful messages, setup is almost done.
+ And, once you have confirmed that you can create a database, usullay there is no need to open this screen.
+ You can create a database from Self-hosted LiveSync.

### Credentials Setup
@@ -135,7 +137,7 @@ Select Multitenant(it's the default) and the region as you like.
1. The dialog to create a credential will be shown.
type any name or leave it default, hit the "Add" button.

- _NOTE: This "name" is not related to your username that uses in self-hosted-livesync._
+ _NOTE: This "name" is not related to your username that uses in Self-hosted LiveSync._
1. Back to "Service credentials", the new credential should be created.
open details.
@@ -145,16 +147,16 @@ Select Multitenant(it's the default) and the region as you like.
follow the figure, it's
"apikey-v2-2unu15184f7o8emr90xlqgkm2ncwhbltml6tgnjl9sd5"(\*3) and "c2c11651d75497fa3d3c486e4c8bdf27"(\*4)
-### self-hosted-livesync setting
+### Self-hosted LiveSync setting

example values.
-| Items | Value | example |
-| ------------------- | ----------- | --------------------------------------------------------------------------- |
-| CouchDB Remote URI: | (\*1)/(\*2) | https://xxxxxxxxxxxxxxxxx-bluemix.cloudantnosqldb.appdomain.cloud/sync-test |
-| CouchDB Username | (\*3) | apikey-v2-2unu15184f7o8emr90xlqgkm2ncwhbltml6tgnjl9sd5 |
-| CouchDB Password | (\*4) | c2c11651d75497fa3d3c486e4c8bdf27 |
+| Items | Value | example |
+| ------------------- | -------------------------------- | --------------------------------------------------------------------------- |
+| CouchDB Remote URI: | (\*1)/(\*2) or any favorite name | https://xxxxxxxxxxxxxxxxx-bluemix.cloudantnosqldb.appdomain.cloud/sync-test |
+| CouchDB Username | (\*3) | apikey-v2-2unu15184f7o8emr90xlqgkm2ncwhbltml6tgnjl9sd5 |
+| CouchDB Password | (\*4) | c2c11651d75497fa3d3c486e4c8bdf27 |
# License
diff --git a/main.ts b/main.ts
index f0538d2..f17738a 100644
--- a/main.ts
+++ b/main.ts
@@ -1,4 +1,4 @@
-import { App, debounce, Modal, Notice, Plugin, PluginSettingTab, Setting, TFile, addIcon, TFolder, normalizePath } from "obsidian";
+import { App, debounce, Modal, Notice, Plugin, PluginSettingTab, Setting, TFile, addIcon, TFolder, normalizePath, TAbstractFile } from "obsidian";
import { PouchDB } from "./pouchdb-browser-webpack/dist/pouchdb-browser";
import { DIFF_DELETE, DIFF_EQUAL, DIFF_INSERT, diff_match_patch } from "diff-match-patch";
import xxhash from "xxhash-wasm";
@@ -663,7 +663,7 @@ class LocalPouchDB {
console.log("!" + v.id);
} else {
if (!v.id.startsWith("h:")) {
- console.log("?" + v.id);
+ // console.log("?" + v.id);
}
}
}
@@ -1285,9 +1285,14 @@ export default class ObsidianLiveSyncPlugin extends Plugin {
if (delay < 200) delay = 200;
if (delay > 5000) delay = 5000;
this.watchVaultChange = debounce(this.watchVaultChange.bind(this), delay, false);
- this.watchVaultDelete = debounce(this.watchVaultDelete.bind(this), delay, false);
- this.watchVaultRename = debounce(this.watchVaultRename.bind(this), delay, false);
+ // this.watchVaultDelete = debounce(this.watchVaultDelete.bind(this), delay, false);
+ // this.watchVaultRename = debounce(this.watchVaultRename.bind(this), delay, false);
+
+ // this.watchVaultChange = this.watchVaultChange.bind(this);
+ this.watchVaultDelete = this.watchVaultDelete.bind(this);
+ this.watchVaultRename = this.watchVaultRename.bind(this);
this.watchWorkspaceOpen = debounce(this.watchWorkspaceOpen.bind(this), delay, false);
+ this.watchWindowVisiblity = debounce(this.watchWindowVisiblity.bind(this), delay, false);
this.registerWatchEvents();
this.parseReplicationResult = this.parseReplicationResult.bind(this);
@@ -1409,16 +1414,19 @@ export default class ObsidianLiveSyncPlugin extends Plugin {
}
watchWindowVisiblity() {
+ this.watchWindowVisiblityAsync();
+ }
+ async watchWindowVisiblityAsync() {
if (this.settings.suspendFileWatching) return;
let isHidden = document.hidden;
if (isHidden) {
this.localDatabase.closeReplication();
} else {
if (this.settings.liveSync) {
- this.localDatabase.openReplication(this.settings, true, false, this.parseReplicationResult);
+ await this.localDatabase.openReplication(this.settings, true, false, this.parseReplicationResult);
}
if (this.settings.syncOnStart) {
- this.localDatabase.openReplication(this.settings, false, false, this.parseReplicationResult);
+ await this.localDatabase.openReplication(this.settings, false, false, this.parseReplicationResult);
}
}
this.gcHook();
@@ -1426,35 +1434,82 @@ export default class ObsidianLiveSyncPlugin extends Plugin {
watchWorkspaceOpen(file: TFile) {
if (this.settings.suspendFileWatching) return;
+ this.watchWorkspaceOpenAsync(file);
+ }
+ async watchWorkspaceOpenAsync(file: TFile) {
if (file == null) return;
this.localDatabase.disposeHashCache();
- this.showIfConflicted(file);
+ await this.showIfConflicted(file);
this.gcHook();
}
watchVaultChange(file: TFile, ...args: any[]) {
if (this.settings.suspendFileWatching) return;
- this.updateIntoDB(file);
+ this.watchVaultChangeAsync(file, ...args);
+ }
+ batchFileChange: string[] = [];
+ async watchVaultChangeAsync(file: TFile, ...args: any[]) {
+ await this.updateIntoDB(file);
this.gcHook();
}
- watchVaultDelete(file: TFile & TFolder) {
+ watchVaultDelete(file: TFile | TFolder) {
if (this.settings.suspendFileWatching) return;
- if (file.children) {
- //folder
- this.deleteFolderOnDB(file);
- // this.app.vault.delete(file);
- } else {
- this.deleteFromDB(file);
+ this.watchVaultDeleteAsync(file);
+ }
+ async watchVaultDeleteAsync(file: TFile | TFolder) {
+ if (file instanceof TFile) {
+ await this.deleteFromDB(file);
+ } else if (file instanceof TFolder) {
+ await this.deleteFolderOnDB(file);
}
this.gcHook();
}
- watchVaultRename(file: TFile & TFolder, oldFile: any) {
- if (this.settings.suspendFileWatching) return;
- if (file.children) {
- // this.renameFolder(file,oldFile);
- Logger(`folder name changed:(this operation is not supported) ${file.path}`, LOG_LEVEL.NOTICE);
+ GetAllFilesRecursively(file: TAbstractFile): TFile[] {
+ if (file instanceof TFile) {
+ return [file];
+ } else if (file instanceof TFolder) {
+ let result: TFile[] = [];
+ for (var v of file.children) {
+ result.push(...this.GetAllFilesRecursively(v));
+ }
+ return result;
} else {
- this.updateIntoDB(file);
- this.deleteFromDBbyPath(oldFile);
+ Logger(`Filetype error:${file.path}`, LOG_LEVEL.NOTICE);
+ throw new Error(`Filetype error:${file.path}`);
+ }
+ }
+ watchVaultRename(file: TFile | TFolder, oldFile: any) {
+ if (this.settings.suspendFileWatching) return;
+ this.watchVaultRenameAsync(file, oldFile);
+ }
+ getFilePath(file: TAbstractFile): string {
+ if (file instanceof TFolder) {
+ if (file.isRoot()) return "";
+ return this.getFilePath(file.parent) + "/" + file.name;
+ }
+ if (file instanceof TFile) {
+ return this.getFilePath(file.parent) + "/" + file.name;
+ }
+ }
+ async watchVaultRenameAsync(file: TFile | TFolder, oldFile: any) {
+ Logger(`${oldFile} renamed to ${file.path}`, LOG_LEVEL.VERBOSE);
+ if (file instanceof TFolder) {
+ const newFiles = this.GetAllFilesRecursively(file);
+ // for guard edge cases. this won't happen and each file's event will be raise.
+ for (const i of newFiles) {
+ let newFilePath = normalizePath(this.getFilePath(i));
+ let newFile = this.app.vault.getAbstractFileByPath(newFilePath);
+ if (newFile instanceof TFile) {
+ Logger(`save ${newFile.path} into db`);
+ await this.updateIntoDB(newFile);
+ }
+ }
+ Logger(`delete below ${oldFile} from db`);
+ await this.deleteFromDBbyPath(oldFile);
+ } else if (file instanceof TFile) {
+ Logger(`file save ${file.path} into db`);
+ await this.updateIntoDB(file);
+ Logger(`deleted ${oldFile} into db`);
+ await this.deleteFromDBbyPath(oldFile);
}
this.gcHook();
}
diff --git a/manifest.json b/manifest.json
index 0ecb60e..a1b44c6 100644
--- a/manifest.json
+++ b/manifest.json
@@ -1,7 +1,7 @@
{
"id": "obsidian-livesync",
"name": "Self-hosted LiveSync",
- "version": "0.1.11",
+ "version": "0.1.12",
"minAppVersion": "0.9.12",
"description": "Community implementation of self-hosted livesync. Reflect your vault changes to some other devices immediately. Please make sure to disable other synchronize solutions to avoid content corruption or duplication.",
"author": "vorotamoroz",
diff --git a/package-lock.json b/package-lock.json
index 337612e..16f2479 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "obsidian-livesync",
- "version": "0.1.11",
+ "version": "0.1.12",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "obsidian-livesync",
- "version": "0.1.11",
+ "version": "0.1.12",
"license": "MIT",
"dependencies": {
"diff-match-patch": "^1.0.5",
diff --git a/package.json b/package.json
index 20866f7..4e089c9 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "obsidian-livesync",
- "version": "0.1.11",
+ "version": "0.1.12",
"description": "Reflect your vault changes to some other devices immediately. Please make sure to disable other synchronize solutions to avoid content corruption or duplication.",
"main": "main.js",
"scripts": {