Compare commits
47 Commits
0.15.1
...
forprivacy
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
db68bc8e30 | ||
|
|
db3eb7e1a0 | ||
|
|
50f51393fc | ||
|
|
8a04e332d6 | ||
|
|
12ae17aa2f | ||
|
|
657f12f966 | ||
|
|
15a7bed448 | ||
|
|
420c3b94df | ||
|
|
239c087132 | ||
|
|
d1a633c799 | ||
|
|
1c07cd92fc | ||
|
|
adc84d53b1 | ||
|
|
c3a762ceed | ||
|
|
5945638633 | ||
|
|
331acd463d | ||
|
|
9d4f41bbf9 | ||
|
|
8831165965 | ||
|
|
ed62e9331b | ||
|
|
799e604eb2 | ||
|
|
d9b69d9a1b | ||
|
|
c18b5c24b4 | ||
|
|
07f16e3d7d | ||
|
|
486f1aa4a0 | ||
|
|
075c6beb68 | ||
|
|
d6121b0c1e | ||
|
|
3292a48054 | ||
|
|
ee37764040 | ||
|
|
b6f7fced22 | ||
|
|
13456c0854 | ||
|
|
2663a52fd7 | ||
|
|
d4bbf79514 | ||
|
|
5f96cc6b82 | ||
|
|
8c8f5d045f | ||
|
|
40cf8be890 | ||
|
|
6b03dbbe75 | ||
|
|
74425f75d2 | ||
|
|
ac7c622466 | ||
|
|
4b32365694 | ||
|
|
728edac283 | ||
|
|
ab9c0190bb | ||
|
|
5a7610d411 | ||
|
|
4691ae1463 | ||
|
|
0923ac3d85 | ||
|
|
ca100d6d9d | ||
|
|
bc373d4359 | ||
|
|
4038b683fe | ||
|
|
5e7b44d35a |
36
README.md
@@ -40,41 +40,9 @@ First, get your database ready. IBM Cloudant is preferred for testing. Or you ca
|
||||
|
||||
Note: More information about alternative hosting methods needed! Currently, [using fly.io](https://github.com/vrtmrz/obsidian-livesync/discussions/85) is being discussed.
|
||||
|
||||
### First device
|
||||
### Configure the plugin
|
||||
|
||||
1. Install the plugin on your device.
|
||||
2. Configure remote database information.
|
||||
1. Fill your server's information into the `Remote Database configuration` pane.
|
||||
2. Enabling `End to End Encryption` is recommended. After entering a passphrase, click `Apply`.
|
||||
3. Click `Test Database Connection` and make sure that the plugin says `Connected to (your-database-name)`.
|
||||
4. Click `Check database configuration` and make sure all tests have passed.
|
||||
3. Configure when should the synchronization happen in `Sync Settings` tab. (You can also leave them for later)
|
||||
1. If you want to synchronize in real-time, enable `LiveSync`.
|
||||
2. Or, set up the synchronization as you like. By default, none of the settings are enabled, meaning you would need to manually trigger the synchronization process.
|
||||
3. Additional configurations are also here. I recommend enabling `Use Trash for deleted files`, but you can also leave all configurations as-is.
|
||||
4. Configure miscellaneous features.
|
||||
1. Enabling `Show status inside editor` shows status at the top-right corner of the editor while in editing mode. (Recommended)
|
||||
5. Go back to the editor. Wait for the initial scan to complete.
|
||||
6. When the status no longer changes and shows a ⏹️ for COMPLETED (No ⏳ and 🧩 icons), you are ready to synchronize with the server.
|
||||
7. Press the replicate icon on the Ribbon or run `Replicate now` from the command palette. This will send all your data to the server.
|
||||
8. Open command palette, run `Copy setup URI`, and set a passphrase. This will export your configuration to clipboard as a link for you to import into your other devices.
|
||||
|
||||
**IMPORTANT: BE CAREFUL NOT TO SHARE THIS LINK. THE URI CONTAINS ALL YOUR CREDENTIALS.** (even though nobody could read them without the passphrase)
|
||||
|
||||
### Subsequent Devices
|
||||
|
||||
Note: If we are going to synchronize with a non-empty vault, the modification dates and times of the files must match between them. Otherwise, extra transfers may occur or files may become corrupted.
|
||||
For simplicity, we strongly recommend that we sync to an empty vault.
|
||||
|
||||
1. Install the plug-in.
|
||||
2. Open the link that you have exported from the first device.
|
||||
3. The plug-in will ask you whether you are sure to apply the configurations. Answer `Yes`, then follow these instructions:
|
||||
1. Answer `Yes` to `Keep local DB?`.
|
||||
*Note: If you start with an existing vault, you have to answer `No` to this question and also answer `No` to `Rebuild the database?`.*
|
||||
2. Answer `Yes` to `Keep remote DB?`.
|
||||
3. Answer `Yes` to `Replicate once?`.
|
||||
Then, all your settings should be successfully imported from the first device.
|
||||
4. Your notes should get synchronized soon.
|
||||
See [Quick setup guide](doccs/../docs/quick_setup.md)
|
||||
|
||||
## Something looks corrupted...
|
||||
|
||||
|
||||
21
README_ja.md
@@ -6,7 +6,7 @@
|
||||
**公式のSyncとは互換性はありません**
|
||||

|
||||
|
||||
**ほぼ動くようになってきましたが、Vaultのバックアップは確実に取得してください**
|
||||
**インストールする前に、Vaultのバックアップを確実に取得してください**
|
||||
|
||||
[英語版](./README.md)
|
||||
|
||||
@@ -30,28 +30,17 @@ NDAや類似の契約や義務、倫理を守る必要のある、研究者、
|
||||
これは、Vaultをクラウド管理下のフォルダに置くことも含みます。(例えば、iCloudの管理フォルダ内に入れたり)。
|
||||
- ⚠️このプラグインは、端末間でのノートの反映を目的として作成されました。バックアップ等が目的ではありません。そのため、バックアップは必ず別のソリューションで行うようにしてください。
|
||||
- ストレージの空き容量が枯渇した場合、データベースが破損することがあります。
|
||||
- 隠しファイルやObsidisanが認識できないファイルを編集した場合、そのファイルは削除されることがあります。
|
||||
|
||||
|
||||
# 補足
|
||||
|
||||
- レプリケーションなどでファイルがリモートデバイスから削除された場合、受信したデバイスでも、ファイルの削除が反映されます。
|
||||
- その際、Self-hosted LiveSyncは、フォルダが空になった際に、フォルダをデフォルトでは残しません。残す場合はオプションから設定してください。
|
||||
- LiveSyncはモバイルではバッテリーをかなり消費します。
|
||||
- モバイル端末からは、非httpsのエンドポイント、または独自CAが発行した証明書でホストされているhttpsのサーバーには接続できません。
|
||||
- 除外フォルダのような設定はありません。
|
||||
|
||||
|
||||
# このプラグインの使い方
|
||||
|
||||
1. Community Pluginsから、Self-holsted LiveSyncと検索しインストールするか、このリポジトリのReleasesから`main.js`, `manifest.json`, `style.css` をダウンロードしvaultの中の`.obsidian/plugins/obsidian-livesync`に入れて、Obsidianを再起動してください。
|
||||
2. サーバーを確保します。IBM Cloudantがお手軽かつ堅牢で便利です。完全にセルフホストする際にはお持ちのサーバーにCouchDBをインストールする必要があります。詳しくは下記を参照してください
|
||||
2. サーバーをセットアップします。IBM Cloudantがお手軽かつ堅牢で便利です。完全にセルフホストする際にはお持ちのサーバーにCouchDBをインストールする必要があります。詳しくは下記を参照してください
|
||||
1. [IBM Cloudantのセットアップ](docs/setup_cloudant_ja.md)
|
||||
2. [独自のCouchDBのセットアップ](docs/setup_own_server_ja.md)
|
||||
3. サーバー情報を入力します。初回のみ、Obsidianを再起動することをオススメします。
|
||||
設定内容の詳細は[このプラグインの設定](docs/settings_ja.md)を参照してください。
|
||||
|
||||
4. お好きな同期方法を選んで、利用を開始してください。
|
||||
備考: IBM Cloudantのアカウント登録が出来ないケースがあるようです。代替を探していて、今 [using fly.io](https://github.com/vrtmrz/obsidian-livesync/discussions/85)を検討しています。
|
||||
|
||||
1. [Quick setup](docs/quick_setup_ja.md)から、セットアップウィザード使ってセットアップしてください。
|
||||
|
||||
# テストサーバー
|
||||
|
||||
|
||||
97
docs/quick_setup.md
Normal file
@@ -0,0 +1,97 @@
|
||||
# Quick setup
|
||||
The Setup wizard has been implemented since v0.15.0. This simplifies the initial set-up.
|
||||
|
||||
Note: The subsequent devices should be set up using the `Copy setup URI` and `Open setup URI`.
|
||||
|
||||
## How to open and use wizard
|
||||
Open from `🪄 Setup wizard` in the setting dialogue. If there is no configuration or no synchronisation settings have been activated, it should already be open.
|
||||
|
||||

|
||||
|
||||
### Discard the existing configuration and set up
|
||||
If you have made any settings, this button allows you to discard them all before setting up.
|
||||
|
||||
### Do not discard the existing configuration and set up
|
||||
Simply reconfigure. Be careful. In wizard mode, you cannot see all configuration items, even if they have been configured.
|
||||
|
||||
Pressing `Next` on any of these will put the configuration dialog into wizard mode.
|
||||
|
||||
### Wizard mode
|
||||
|
||||

|
||||
|
||||
We can set it up step by step.
|
||||
|
||||
## Remote Database configuration
|
||||
|
||||
### Remote database configuration
|
||||
|
||||
Enter the information in the database we have set up.
|
||||
|
||||

|
||||
|
||||
### End to End Encryption
|
||||
|
||||

|
||||
|
||||
If End to End encryption is enabled, the possibility of a third party who does not know the Passphrase being able to read the contents of the Remote database in the event that they are leaked is reduced. So we strongly recommend to enable it.
|
||||
Encryption is based on 256-bit AES-GCM.
|
||||
This setting can be disabled if you are inside a closed network and it is clear that you will not be accessed by third parties.
|
||||
|
||||
### Test database connectionとCheck database configuraion
|
||||
|
||||
Here we can check the status of the connection to the database and the database settings.
|
||||
|
||||

|
||||
|
||||
#### Test Database Connection
|
||||
Check whether we can connect to the database. If it fails, there are a number of reasons, but once you have done the `Check database configuration`, check if it fails there too.
|
||||
|
||||
#### Check database configuration
|
||||
|
||||
Check the database settings and fix any deficiencies on the spot.
|
||||
|
||||

|
||||
|
||||
This item may vary depending on the connection. In the above case, press all three Fix buttons.
|
||||
If the Fix buttons disappear and all become check marks, we are done.
|
||||
|
||||

|
||||
|
||||
### Next
|
||||
Go to the Local Database configuration.
|
||||
|
||||
### Discard exist database and proceed
|
||||
Discard the contents of the Remote database and go to the Local Database configuration.
|
||||
|
||||
## Local Database confiuration
|
||||
|
||||

|
||||
|
||||
Configure the local database. If we already have a Vaults with Self-hosted LiveSync installed and having same directory name as currently we are setting up, please specify a different suffix than the Vault you have already set up here.
|
||||
|
||||
## Miscellaneous
|
||||
Finally, finish the miscellaneous configurations and select a preset for synchronisation.
|
||||
|
||||

|
||||
|
||||
The `Show status inside editor` can be enabled to your liking. If enabled, the status is displayed in the top right-hand corner of the editor.
|
||||
|
||||

|
||||
|
||||
From Presets, select the synchronisation method we want to use and `Apply` to initialise and build the local and remote databases as required.
|
||||
If `All done!' is displayed, we are done. Automatically, `Copy setup URI` will open and we will be asked for a passphrase to encrypt the `Setup URI`.
|
||||
|
||||

|
||||
|
||||
Set the passphrase as you like.
|
||||
The Setup URI will be copied to the clipboard, which you can then transfer to the second and subsequent devices in some way.
|
||||
|
||||
# How to set up the second and subsequent units
|
||||
After installing Self-hosted LiveSync on the device, select `Open setup URI` from the command palette and enter the setup URI you transferred. Afterwards, enter your passphrase and a setup wizard will open.
|
||||
Answer the following.
|
||||
|
||||
- `Yes` to `Importing LiveSync's conf, OK?`
|
||||
- `Set it up as secondary or subsequent device` to `How would you like to set it up?`.
|
||||
|
||||
Then, The configuration will now take effect and replication will start. Your files will be synchronised soon!
|
||||
94
docs/quick_setup_ja.md
Normal file
@@ -0,0 +1,94 @@
|
||||
# Quick setup
|
||||
v0.15.0からSetup wizardが実装されました。これで、初回セットアップがシンプルになります。
|
||||
※なお、次のデバイスからは、`Copy setup URI`と`Open setup URI`を使ってセットアップしてください。
|
||||
|
||||
|
||||
## Wizardの使い方
|
||||
`🪄 Setup wizard` から開きます。もしセットアップされていなかったり、同期設定が何も有効になっていない場合はデフォルトで開いています。
|
||||
|
||||

|
||||
|
||||
### Discard the existing configuration and set up
|
||||
今設定されている内容をいったん全部消してから、ウィザードを始めます。
|
||||
|
||||
### Do not discard the existing configuration and set up
|
||||
今の設定を消さずにウィザードを開始します。
|
||||
たとえ設定されていたとしても、ウィザードモードではすべての設定を見ることができません。
|
||||
|
||||
いずれかのNextを押すと、設定画面がウィザードモードになります。
|
||||
|
||||
### Wizardモード
|
||||
|
||||

|
||||
|
||||
順番に設定を行っていきます。
|
||||
|
||||
## Remote Database configuration
|
||||
|
||||
### Remote databaseの設定
|
||||
セットアップしたデータベースの情報を入力していきます。
|
||||
|
||||

|
||||
|
||||
これらはデータベースをセットアップした際に決めた情報です。
|
||||
|
||||
### End to End暗号化の設定
|
||||
|
||||

|
||||
|
||||
End to End暗号化を有効にした場合、万が一Remote databaseの内容が流出してもPassphraseを知らない第三者にそれを読まれる可能性が低くなります。そのため、有効化を強く推奨します。
|
||||
暗号化は256bitのAES-GCMを採用しています。
|
||||
この設定は、あなたが閉じたネットワークの内側にいて、かつ第三者からアクセスされない事が明確な場合には無効にできます。
|
||||
|
||||
### Test database connectionとCheck database configuraion
|
||||
ここで、データベースへの接続状況と、データベース設定を確認します。
|
||||

|
||||
|
||||
#### Test Database Connection
|
||||
データベースに接続出来るか自体を確認します。失敗する場合はいくつか理由がありますが、一度Check database configurationを行ってそちらでも失敗するか確認してください。
|
||||
|
||||
#### Check database configuration
|
||||
データベースの設定を確認し、不備がある場合はその場で修正します。
|
||||
|
||||

|
||||
|
||||
この項目は接続先によって異なる場合があります。上記の場合、みっつのFixボタンを順にすべて押してください。
|
||||
Fixボタンがなくなり、すべてチェックマークになれば完了です。
|
||||
|
||||

|
||||
|
||||
### Next
|
||||
次へ進みます
|
||||
|
||||
### Discard exist database and proceed
|
||||
すでにRemote databaseがある場合、Remote databaseの内容を破棄してから次へ進みます
|
||||
|
||||
## Local Database confiuration
|
||||

|
||||
ローカルのデータベースを設定します。もし、すでにSelf-hosted LiveSyncをインストールしたVaultがあり、そのVaultと同じデータベース名を使用している場合は、ここですでに設定したVaultとは異なるsuffixを指定してください。
|
||||
|
||||
## Miscellaneous
|
||||
最後にその他の設定を行います。
|
||||
|
||||

|
||||
|
||||
`Show status inside editor`はお好みで有効化してください。有効にするとエディターの右上にステータスが表示されます。
|
||||
|
||||

|
||||
|
||||
Presetsから、使用する同期方法を選び`Apply`を行うと、必要に応じてローカル・リモートのデータベースを初期化・構築します。
|
||||
All done! と表示されれば完了です。自動的に、`Copy setup URI`が開き、`Setup URI`を暗号化するパスフレーズを聞かれます。
|
||||
|
||||

|
||||
|
||||
お好みのパスフレーズを設定してください。
|
||||
クリップボードにSetup URIが保存されますので、これを2台目以降のデバイスに何らかの方法で転送してください。
|
||||
|
||||
# 2台目以降の設定方法
|
||||
2台目の端末にSelf-hosted LiveSyncをインストールしたあと、コマンドパレットから`Open setup URI`を選択し、転送したsetup URIを入力します。その後、パスフレーズを入力するとセットアップ用のウィザードが開きます。
|
||||
下記のように答えてください。
|
||||
|
||||
- `Importing LiveSync's conf, OK?` に `Yes`
|
||||
- `How would you like to set it up?` に `Set it up as secondary or subsequent device`
|
||||
|
||||
これで設定が反映され、レプリケーションが開始されます。
|
||||
@@ -10,9 +10,11 @@ But some additional configurations are required in `local.ini` to use from Self-
|
||||
```
|
||||
[couchdb]
|
||||
single_node=true
|
||||
max_document_size = 50000000
|
||||
|
||||
[chttpd]
|
||||
require_valid_user = true
|
||||
max_http_request_size = 4294967296
|
||||
|
||||
[chttpd_auth]
|
||||
require_valid_user = true
|
||||
@@ -32,16 +34,18 @@ max_age = 3600
|
||||
|
||||
Make `local.ini` and run with docker run like this, you can launch the CouchDB.
|
||||
```
|
||||
$ docker run --rm -it -e COUCHDB_USER=admin -e COUCHDB_PASSWORD=password -v .local.ini:/opt/couchdb/etc/local.ini -p 5984:5984 couchdb
|
||||
$ docker run --rm -it -e COUCHDB_USER=admin -e COUCHDB_PASSWORD=password -v /path/to/local.ini:/opt/couchdb/etc/local.ini -p 5984:5984 couchdb
|
||||
```
|
||||
*Remember to replace the path with the path to your local.ini*
|
||||
Note: At this time, the file owner of local.ini became 5984:5984. It's the limitation docker image. please change the owner before editing local.ini again.
|
||||
|
||||
If you could confirm that Self-hosted LiveSync can sync with the server, launch docker image as background as you like.
|
||||
|
||||
example)
|
||||
Example to run docker in detached mode:
|
||||
```
|
||||
$ docker run -d --restart always -e COUCHDB_USER=admin -e COUCHDB_PASSWORD=password -v .local.ini:/opt/couchdb/etc/local.ini -p 5984:5984 couchdb
|
||||
$ docker run -d --restart always -e COUCHDB_USER=admin -e COUCHDB_PASSWORD=password -v /path/to/local.ini:/opt/couchdb/etc/local.ini -p 5984:5984 couchdb
|
||||
```
|
||||
*Remember to replace the path with the path to your local.ini*
|
||||
|
||||
## Access from mobile device
|
||||
If you want to access Self-hosted LiveSync from mobile devices, you need a valid SSL certificate.
|
||||
@@ -92,4 +96,4 @@ Using Caddy is a handy way to serve the server with SSL automatically.
|
||||
|
||||
I have published [docker-compose.yml and ini files](https://github.com/vrtmrz/self-hosted-livesync-server) that launches Caddy and CouchDB at once. Please try it out.
|
||||
|
||||
And, be sure to check the server log and be careful of malicious access.
|
||||
And, be sure to check the server log and be careful of malicious access.
|
||||
|
||||
@@ -11,9 +11,11 @@
|
||||
```
|
||||
[couchdb]
|
||||
single_node=true
|
||||
max_document_size = 50000000
|
||||
|
||||
[chttpd]
|
||||
require_valid_user = true
|
||||
max_http_request_size = 4294967296
|
||||
|
||||
[chttpd_auth]
|
||||
require_valid_user = true
|
||||
@@ -92,4 +94,4 @@ Note: 不推荐将 CouchDB 挂载到根目录
|
||||
|
||||
提供了 [docker-compose.yml 和 ini 文件](https://github.com/vrtmrz/self-hosted-livesync-server) 可以同时启动 Caddy 和 CouchDB。
|
||||
|
||||
注意检查服务器日志,当心恶意访问。
|
||||
注意检查服务器日志,当心恶意访问。
|
||||
|
||||
@@ -8,12 +8,14 @@ CouchDBを構築するには、[Dockerのイメージ](https://hub.docker.com/_/
|
||||
```
|
||||
[couchdb]
|
||||
single_node=true
|
||||
max_document_size = 50000000
|
||||
|
||||
[chttpd]
|
||||
require_valid_user = true
|
||||
|
||||
[chttpd_auth]
|
||||
require_valid_user = true
|
||||
max_http_request_size = 4294967296
|
||||
authentication_redirect = /_utils/session.html
|
||||
|
||||
[httpd]
|
||||
|
||||
@@ -13,7 +13,7 @@ if you want to view the source, please visit the github repository of this plugi
|
||||
const prod = process.argv[2] === "production";
|
||||
const manifestJson = JSON.parse(fs.readFileSync("./manifest.json"));
|
||||
const packageJson = JSON.parse(fs.readFileSync("./package.json"));
|
||||
const updateInfo = JSON.stringify(fs.readFileSync("./updates.md") + "");
|
||||
const updateInfo = JSON.stringify("PATCHED-"+fs.readFileSync("./updates.md") + "");
|
||||
esbuild
|
||||
.build({
|
||||
banner: {
|
||||
|
||||
BIN
images/quick_setup_1.png
Normal file
|
After Width: | Height: | Size: 39 KiB |
BIN
images/quick_setup_10.png
Normal file
|
After Width: | Height: | Size: 13 KiB |
BIN
images/quick_setup_2.png
Normal file
|
After Width: | Height: | Size: 16 KiB |
BIN
images/quick_setup_3.png
Normal file
|
After Width: | Height: | Size: 24 KiB |
BIN
images/quick_setup_4.png
Normal file
|
After Width: | Height: | Size: 31 KiB |
BIN
images/quick_setup_5.png
Normal file
|
After Width: | Height: | Size: 36 KiB |
BIN
images/quick_setup_6.png
Normal file
|
After Width: | Height: | Size: 163 KiB |
BIN
images/quick_setup_7.png
Normal file
|
After Width: | Height: | Size: 10 KiB |
BIN
images/quick_setup_8.png
Normal file
|
After Width: | Height: | Size: 32 KiB |
BIN
images/quick_setup_9_1.png
Normal file
|
After Width: | Height: | Size: 35 KiB |
BIN
images/quick_setup_9_2.png
Normal file
|
After Width: | Height: | Size: 1.7 KiB |
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"id": "obsidian-livesync",
|
||||
"name": "Self-hosted LiveSync",
|
||||
"version": "0.15.1",
|
||||
"version": "0.16.8",
|
||||
"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",
|
||||
|
||||
2807
package-lock.json
generated
46
package.json
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "obsidian-livesync",
|
||||
"version": "0.15.1",
|
||||
"version": "0.16.8",
|
||||
"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",
|
||||
"type": "module",
|
||||
@@ -13,34 +13,32 @@
|
||||
"author": "vorotamoroz",
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"@rollup/plugin-commonjs": "^18.0.0",
|
||||
"@rollup/plugin-node-resolve": "^11.2.1",
|
||||
"@rollup/plugin-typescript": "^8.2.1",
|
||||
"@types/diff-match-patch": "^1.0.32",
|
||||
"@types/pouchdb": "^6.4.0",
|
||||
"@types/pouchdb-browser": "^6.1.3",
|
||||
"@typescript-eslint/eslint-plugin": "^5.7.0",
|
||||
"@typescript-eslint/parser": "^5.0.0",
|
||||
"builtin-modules": "^3.2.0",
|
||||
"esbuild": "0.13.12",
|
||||
"esbuild-svelte": "^0.7.0",
|
||||
"eslint": "^7.32.0",
|
||||
"eslint-config-airbnb-base": "^14.2.1",
|
||||
"eslint-plugin-import": "^2.25.2",
|
||||
"obsidian": "^0.15.4",
|
||||
"postcss": "^8.4.14",
|
||||
"postcss-load-config": "^3.1.4",
|
||||
"rollup": "^2.32.1",
|
||||
"svelte": "^3.49.0",
|
||||
"@types/xxhashjs": "^0.2.2",
|
||||
"@typescript-eslint/eslint-plugin": "^5.44.0",
|
||||
"@typescript-eslint/parser": "^5.44.0",
|
||||
"builtin-modules": "^3.3.0",
|
||||
"esbuild": "0.15.15",
|
||||
"esbuild-svelte": "^0.7.3",
|
||||
"eslint": "^8.28.0",
|
||||
"eslint-config-airbnb-base": "^15.0.0",
|
||||
"eslint-plugin-import": "^2.26.0",
|
||||
"obsidian": "^0.16.3",
|
||||
"postcss": "^8.4.19",
|
||||
"postcss-load-config": "^4.0.1",
|
||||
"svelte": "^3.53.1",
|
||||
"svelte-preprocess": "^4.10.7",
|
||||
"tslib": "^2.2.0",
|
||||
"typescript": "^4.2.4"
|
||||
"tslib": "^2.4.1",
|
||||
"typescript": "^4.9.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"diff-match-patch": "^1.0.5",
|
||||
"esbuild": "0.13.12",
|
||||
"esbuild-svelte": "^0.7.0",
|
||||
"idb": "^7.0.2",
|
||||
"xxhash-wasm": "^0.4.2"
|
||||
"esbuild": "0.15.15",
|
||||
"esbuild-svelte": "^0.7.3",
|
||||
"idb": "^7.1.1",
|
||||
"xxhash-wasm": "^0.4.2",
|
||||
"xxhashjs": "^0.2.2"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
import typescript from "@rollup/plugin-typescript";
|
||||
import { nodeResolve } from "@rollup/plugin-node-resolve";
|
||||
import commonjs from "@rollup/plugin-commonjs";
|
||||
|
||||
const isProd = process.env.BUILD === "production";
|
||||
|
||||
const banner = `/*
|
||||
THIS IS A GENERATED/BUNDLED FILE BY ROLLUP
|
||||
if you want to view the source visit the plugins github repository
|
||||
*/
|
||||
`;
|
||||
|
||||
export default {
|
||||
input: "./src/main.ts",
|
||||
output: {
|
||||
dir: ".",
|
||||
sourcemap: "inline",
|
||||
sourcemapExcludeSources: isProd,
|
||||
format: "cjs",
|
||||
exports: "default",
|
||||
banner,
|
||||
},
|
||||
external: ["obsidian"],
|
||||
plugins: [
|
||||
typescript({ exclude: ["pouchdb-browser.js", "pouchdb-browser-webpack"] }),
|
||||
nodeResolve({
|
||||
browser: true,
|
||||
}),
|
||||
commonjs(),
|
||||
],
|
||||
};
|
||||
@@ -38,8 +38,8 @@ export class ConflictResolveModal extends Modal {
|
||||
diff = diff.replace(/\n/g, "<br>");
|
||||
div.innerHTML = diff;
|
||||
const div2 = contentEl.createDiv("");
|
||||
const date1 = new Date(this.result.left.mtime).toLocaleString();
|
||||
const date2 = new Date(this.result.right.mtime).toLocaleString();
|
||||
const date1 = new Date(this.result.left.mtime).toLocaleString() + (this.result.left.deleted ? " (Deleted)" : "");
|
||||
const date2 = new Date(this.result.right.mtime).toLocaleString() + (this.result.right.deleted ? " (Deleted)" : "");
|
||||
div2.innerHTML = `
|
||||
<span class='deleted'>A:${date1}</span><br /><span class='added'>B:${date2}</span><br>
|
||||
`;
|
||||
|
||||
@@ -5,8 +5,9 @@ import { Logger } from "./lib/src/logger.js";
|
||||
import { PouchDB } from "./lib/src/pouchdb-browser.js";
|
||||
import { EntryDoc, LOG_LEVEL } from "./lib/src/types.js";
|
||||
import { enableEncryption } from "./lib/src/utils.js";
|
||||
import { isValidRemoteCouchDBURI } from "./lib/src/utils_couchdb.js";
|
||||
import { isCloudantURI, isValidRemoteCouchDBURI } from "./lib/src/utils_couchdb.js";
|
||||
import { id2path, path2id } from "./utils.js";
|
||||
import XXH from "xxhashjs";
|
||||
|
||||
export class LocalPouchDB extends LocalPouchDBBase {
|
||||
|
||||
@@ -33,9 +34,16 @@ export class LocalPouchDB extends LocalPouchDBBase {
|
||||
await this.kvDB.destroy();
|
||||
}
|
||||
|
||||
async prepareHashFunctions() {
|
||||
if (this.h32 != null) return;
|
||||
// const { h32, h32Raw } = await xxhash();
|
||||
this.h32 = (input: string, seed: number) => (XXH.h32(input, seed).toString(16))// h32;
|
||||
this.h32Raw = (input: Uint8Array, seed: number) => (XXH.h32(input.buffer, seed).toNumber())// h32;
|
||||
}
|
||||
|
||||
last_successful_post = false;
|
||||
getLastPostFailedBySize() {
|
||||
return this.last_successful_post;
|
||||
return !this.last_successful_post;
|
||||
}
|
||||
async fetchByAPI(request: RequestUrlParam): Promise<RequestUrlResponse> {
|
||||
const ret = await requestUrl(request);
|
||||
@@ -75,9 +83,9 @@ export class LocalPouchDB extends LocalPouchDBBase {
|
||||
const method = opts.method ?? "GET";
|
||||
if (opts.body) {
|
||||
const opts_length = opts.body.toString().length;
|
||||
if (opts_length > 1024 * 1024 * 10) {
|
||||
if (opts_length > 1000 * 1000 * 10) {
|
||||
// over 10MB
|
||||
if (uri.contains(".cloudantnosqldb.")) {
|
||||
if (isCloudantURI(uri)) {
|
||||
this.last_successful_post = false;
|
||||
Logger("This request should fail on IBM Cloudant.", LOG_LEVEL.VERBOSE);
|
||||
throw new Error("This request should fail on IBM Cloudant.");
|
||||
|
||||
@@ -1,12 +1,29 @@
|
||||
import { App, PluginSettingTab, Setting, sanitizeHTMLToDom, RequestUrlParam, requestUrl, TextAreaComponent, MarkdownRenderer } from "obsidian";
|
||||
import { DEFAULT_SETTINGS, LOG_LEVEL, RemoteDBSettings } from "./lib/src/types";
|
||||
import { App, PluginSettingTab, Setting, sanitizeHTMLToDom, RequestUrlParam, requestUrl, TextAreaComponent, MarkdownRenderer, stringifyYaml } from "obsidian";
|
||||
import { DEFAULT_SETTINGS, LOG_LEVEL, ObsidianLiveSyncSettings, RemoteDBSettings } from "./lib/src/types";
|
||||
import { path2id, id2path } from "./utils";
|
||||
import { delay, versionNumberString2Number } from "./lib/src/utils";
|
||||
import { Logger } from "./lib/src/logger";
|
||||
import { checkSyncInfo } from "./lib/src/utils_couchdb.js";
|
||||
import { checkSyncInfo, isCloudantURI } from "./lib/src/utils_couchdb.js";
|
||||
import { testCrypt } from "./lib/src/e2ee_v2";
|
||||
import ObsidianLiveSyncPlugin from "./main";
|
||||
|
||||
const requestToCouchDB = async (baseUri: string, username: string, password: string, origin: string, key?: string, body?: string) => {
|
||||
const utf8str = String.fromCharCode.apply(null, new TextEncoder().encode(`${username}:${password}`));
|
||||
const encoded = window.btoa(utf8str);
|
||||
const authHeader = "Basic " + encoded;
|
||||
// const origin = "capacitor://localhost";
|
||||
const transformedHeaders: Record<string, string> = { authorization: authHeader, origin: origin };
|
||||
const uri = `${baseUri}/_node/_local/_config${key ? "/" + key : ""}`;
|
||||
|
||||
const requestParam: RequestUrlParam = {
|
||||
url: uri,
|
||||
method: body ? "PUT" : "GET",
|
||||
headers: transformedHeaders,
|
||||
contentType: "application/json",
|
||||
body: body ? JSON.stringify(body) : undefined,
|
||||
};
|
||||
return await requestUrl(requestParam);
|
||||
};
|
||||
export class ObsidianLiveSyncSettingTab extends PluginSettingTab {
|
||||
plugin: ObsidianLiveSyncPlugin;
|
||||
|
||||
@@ -67,9 +84,7 @@ export class ObsidianLiveSyncSettingTab extends PluginSettingTab {
|
||||
element.removeClass("selected");
|
||||
(element.querySelector("input[type=radio]") as HTMLInputElement).checked = false;
|
||||
});
|
||||
console.log(`.sls-setting-label.c-${screen}`)
|
||||
w.querySelectorAll(`.sls-setting-label.c-${screen}`).forEach((element) => {
|
||||
console.log(element)
|
||||
element.addClass("selected");
|
||||
(element.querySelector("input[type=radio]") as HTMLInputElement).checked = true;
|
||||
});
|
||||
@@ -131,10 +146,13 @@ export class ObsidianLiveSyncSettingTab extends PluginSettingTab {
|
||||
.addButton((text) => {
|
||||
text.setButtonText("Next").onClick(async () => {
|
||||
if (JSON.stringify(this.plugin.settings) != JSON.stringify(DEFAULT_SETTINGS)) {
|
||||
this.plugin.localDatabase.closeReplication();
|
||||
this.plugin.settings = { ...DEFAULT_SETTINGS };
|
||||
this.plugin.saveSettings();
|
||||
|
||||
Logger("Configuration has been flushed, please open it again", LOG_LEVEL.NOTICE)
|
||||
this.hide();
|
||||
// @ts-ignore
|
||||
this.plugin.app.setting.close()
|
||||
} else {
|
||||
containerEl.addClass("isWizard");
|
||||
applyDisplayEnabled();
|
||||
@@ -147,12 +165,12 @@ export class ObsidianLiveSyncSettingTab extends PluginSettingTab {
|
||||
.setName("Do not discard the existing configuration and set up again")
|
||||
.addButton((text) => {
|
||||
text.setButtonText("Next").onClick(async () => {
|
||||
await this.plugin.resetLocalDatabase();
|
||||
this.plugin.settings.liveSync = false;
|
||||
this.plugin.settings.periodicReplication = false;
|
||||
this.plugin.settings.syncOnSave = false;
|
||||
this.plugin.settings.syncOnStart = false;
|
||||
this.plugin.settings.syncOnFileOpen = false;
|
||||
this.plugin.localDatabase.closeReplication();
|
||||
await this.plugin.saveSettings();
|
||||
containerEl.addClass("isWizard");
|
||||
applyDisplayEnabled();
|
||||
@@ -161,6 +179,24 @@ export class ObsidianLiveSyncSettingTab extends PluginSettingTab {
|
||||
|
||||
})
|
||||
})
|
||||
const infoWarnForSubsequent = setupWizardEl.createEl("div", { text: `To set up second or subsequent device, please use 'Copy setup URI' and 'Open setup URI'` });
|
||||
infoWarnForSubsequent.addClass("op-warn-info");
|
||||
new Setting(setupWizardEl)
|
||||
.setName("Copy setup URI")
|
||||
.addButton((text) => {
|
||||
text.setButtonText("Copy setup URI").onClick(() => {
|
||||
// @ts-ignore
|
||||
this.plugin.app.commands.executeCommandById("obsidian-livesync:livesync-copysetupuri")
|
||||
|
||||
})
|
||||
})
|
||||
.addButton((text) => {
|
||||
text.setButtonText("Open setup URI").onClick(() => {
|
||||
// @ts-ignore
|
||||
this.plugin.app.commands.executeCommandById("obsidian-livesync:livesync-opensetupuri")
|
||||
|
||||
})
|
||||
})
|
||||
|
||||
addScreenElement("110", setupWizardEl);
|
||||
|
||||
@@ -358,6 +394,16 @@ export class ObsidianLiveSyncSettingTab extends PluginSettingTab {
|
||||
.onClick(async () => {
|
||||
await applyEncryption(true);
|
||||
})
|
||||
)
|
||||
.addButton((button) =>
|
||||
button
|
||||
.setButtonText("Apply w/o rebuilding")
|
||||
.setWarning()
|
||||
.setDisabled(false)
|
||||
.setClass("sls-btn-right")
|
||||
.onClick(async () => {
|
||||
await applyEncryption(false);
|
||||
})
|
||||
);
|
||||
|
||||
|
||||
@@ -445,23 +491,10 @@ export class ObsidianLiveSyncSettingTab extends PluginSettingTab {
|
||||
.onClick(async () => {
|
||||
const checkConfig = async () => {
|
||||
try {
|
||||
const requestToCouchDB = async (baseUri: string, username: string, password: string, origin: string, key?: string, body?: string) => {
|
||||
const utf8str = String.fromCharCode.apply(null, new TextEncoder().encode(`${username}:${password}`));
|
||||
const encoded = window.btoa(utf8str);
|
||||
const authHeader = "Basic " + encoded;
|
||||
// const origin = "capacitor://localhost";
|
||||
const transformedHeaders: Record<string, string> = { authorization: authHeader, origin: origin };
|
||||
const uri = `${baseUri}/_node/_local/_config${key ? "/" + key : ""}`;
|
||||
|
||||
const requestParam: RequestUrlParam = {
|
||||
url: uri,
|
||||
method: body ? "PUT" : "GET",
|
||||
headers: transformedHeaders,
|
||||
contentType: "application/json",
|
||||
body: body ? JSON.stringify(body) : undefined,
|
||||
};
|
||||
return await requestUrl(requestParam);
|
||||
};
|
||||
if (isCloudantURI(this.plugin.settings.couchDB_URI)) {
|
||||
Logger("This feature cannot be used with IBM Cloudant.", LOG_LEVEL.NOTICE);
|
||||
return;
|
||||
}
|
||||
|
||||
const r = await requestToCouchDB(this.plugin.settings.couchDB_URI, this.plugin.settings.couchDB_USER, this.plugin.settings.couchDB_PASSWORD, window.origin);
|
||||
|
||||
@@ -544,7 +577,7 @@ export class ObsidianLiveSyncSettingTab extends PluginSettingTab {
|
||||
addResult("✔ httpd.enable_cors is ok.");
|
||||
}
|
||||
// If the server is not cloudant, configure request size
|
||||
if (!this.plugin.settings.couchDB_URI.contains(".cloudantnosqldb.")) {
|
||||
if (!isCloudantURI(this.plugin.settings.couchDB_URI)) {
|
||||
// REQUEST SIZE
|
||||
if (Number(responseConfig?.chttpd?.max_http_request_size ?? 0) < 4294967296) {
|
||||
addResult("❗ chttpd.max_http_request_size is low)");
|
||||
@@ -608,7 +641,7 @@ export class ObsidianLiveSyncSettingTab extends PluginSettingTab {
|
||||
addResult("--Done--", ["ob-btn-config-head"]);
|
||||
addResult("If you have some trouble with Connection-check even though all Config-check has been passed, Please check your reverse proxy's configuration.", ["ob-btn-config-info"]);
|
||||
} catch (ex) {
|
||||
Logger(`Checking configuration failed`);
|
||||
Logger(`Checking configuration failed`, LOG_LEVEL.NOTICE);
|
||||
Logger(ex);
|
||||
}
|
||||
};
|
||||
@@ -632,6 +665,7 @@ export class ObsidianLiveSyncSettingTab extends PluginSettingTab {
|
||||
await this.plugin.markRemoteLocked();
|
||||
})
|
||||
);
|
||||
let rebuildRemote = false;
|
||||
|
||||
new Setting(containerRemoteDatabaseEl)
|
||||
.setName("")
|
||||
@@ -645,12 +679,12 @@ export class ObsidianLiveSyncSettingTab extends PluginSettingTab {
|
||||
if (!this.plugin.settings.encrypt) {
|
||||
this.plugin.settings.passphrase = "";
|
||||
}
|
||||
if (this.plugin.settings.couchDB_URI.contains(".cloudantnosqldb.")) {
|
||||
if (isCloudantURI(this.plugin.settings.couchDB_URI)) {
|
||||
this.plugin.settings.customChunkSize = 0;
|
||||
} else {
|
||||
this.plugin.settings.customChunkSize = 100;
|
||||
}
|
||||
|
||||
rebuildRemote = false;
|
||||
changeDisplay("10")
|
||||
})
|
||||
);
|
||||
@@ -666,13 +700,12 @@ export class ObsidianLiveSyncSettingTab extends PluginSettingTab {
|
||||
if (!this.plugin.settings.encrypt) {
|
||||
this.plugin.settings.passphrase = "";
|
||||
}
|
||||
if (this.plugin.settings.couchDB_URI.contains(".cloudantnosqldb.")) {
|
||||
if (isCloudantURI(this.plugin.settings.couchDB_URI)) {
|
||||
this.plugin.settings.customChunkSize = 0;
|
||||
} else {
|
||||
this.plugin.settings.customChunkSize = 100;
|
||||
}
|
||||
this.plugin.saveSettings();
|
||||
await this.plugin.tryResetRemoteDatabase();
|
||||
rebuildRemote = true;
|
||||
changeDisplay("10")
|
||||
})
|
||||
);
|
||||
@@ -683,6 +716,7 @@ export class ObsidianLiveSyncSettingTab extends PluginSettingTab {
|
||||
new Setting(containerLocalDatabaseEl)
|
||||
.setName("Batch database update")
|
||||
.setDesc("Delay all changes, save once before replication or opening another file.")
|
||||
.setClass("wizardHidden")
|
||||
.addToggle((toggle) =>
|
||||
toggle.setValue(this.plugin.settings.batchSave).onChange(async (value) => {
|
||||
if (value && this.plugin.settings.liveSync) {
|
||||
@@ -779,6 +813,24 @@ export class ObsidianLiveSyncSettingTab extends PluginSettingTab {
|
||||
})
|
||||
}
|
||||
);
|
||||
new Setting(containerGeneralSettingsEl)
|
||||
.setName("Delete old metadata of deleted files on start-up")
|
||||
.setClass("wizardHidden")
|
||||
.setDesc("(Days passed, 0 to disable automatic-deletion)")
|
||||
.addText((text) => {
|
||||
text.setPlaceholder("")
|
||||
.setValue(this.plugin.settings.automaticallyDeleteMetadataOfDeletedFiles + "")
|
||||
.onChange(async (value) => {
|
||||
let v = Number(value);
|
||||
if (isNaN(v)) {
|
||||
v = 0;
|
||||
}
|
||||
this.plugin.settings.automaticallyDeleteMetadataOfDeletedFiles = v;
|
||||
await this.plugin.saveSettings();
|
||||
});
|
||||
text.inputEl.setAttribute("type", "number");
|
||||
});
|
||||
|
||||
|
||||
addScreenElement("20", containerGeneralSettingsEl);
|
||||
const containerSyncSettingEl = containerEl.createDiv();
|
||||
@@ -932,8 +984,17 @@ export class ObsidianLiveSyncSettingTab extends PluginSettingTab {
|
||||
await this.plugin.saveSettings();
|
||||
})
|
||||
);
|
||||
new Setting(containerSyncSettingEl)
|
||||
.setName("Monitor changes to internal files")
|
||||
.addToggle((toggle) =>
|
||||
toggle.setValue(this.plugin.settings.watchInternalFileChanges).onChange(async (value) => {
|
||||
this.plugin.settings.watchInternalFileChanges = value;
|
||||
await this.plugin.saveSettings();
|
||||
})
|
||||
);
|
||||
new Setting(containerSyncSettingEl)
|
||||
.setName("Scan for hidden files before replication")
|
||||
.setDesc("This configuration will be ignored if monitoring changes is enabled.")
|
||||
.addToggle((toggle) =>
|
||||
toggle.setValue(this.plugin.settings.syncInternalFilesBeforeReplication).onChange(async (value) => {
|
||||
this.plugin.settings.syncInternalFilesBeforeReplication = value;
|
||||
@@ -942,7 +1003,7 @@ export class ObsidianLiveSyncSettingTab extends PluginSettingTab {
|
||||
);
|
||||
new Setting(containerSyncSettingEl)
|
||||
.setName("Scan hidden files periodically")
|
||||
.setDesc("Seconds, 0 to disable.")
|
||||
.setDesc("Seconds, 0 to disable. This configuration will be ignored if monitoring changes is enabled.")
|
||||
.addText((text) => {
|
||||
text.setPlaceholder("")
|
||||
.setValue(this.plugin.settings.syncInternalFilesInterval + "")
|
||||
@@ -958,7 +1019,7 @@ export class ObsidianLiveSyncSettingTab extends PluginSettingTab {
|
||||
});
|
||||
let skipPatternTextArea: TextAreaComponent = null;
|
||||
const defaultSkipPattern = "\\/node_modules\\/, \\/\\.git\\/, \\/obsidian-livesync\\/";
|
||||
const defaultSkipPatternXPlat = defaultSkipPattern + ",\\/workspace$";
|
||||
const defaultSkipPatternXPlat = defaultSkipPattern + ",\\/workspace$ ,\\/workspace.json$";
|
||||
new Setting(containerSyncSettingEl)
|
||||
.setName("Skip patterns")
|
||||
.setDesc(
|
||||
@@ -977,7 +1038,7 @@ export class ObsidianLiveSyncSettingTab extends PluginSettingTab {
|
||||
}
|
||||
);
|
||||
new Setting(containerSyncSettingEl)
|
||||
.setName("Skip patterns defaults")
|
||||
.setName("Restore the skip pattern to default")
|
||||
.addButton((button) => {
|
||||
button.setButtonText("Default")
|
||||
.onClick(async () => {
|
||||
@@ -1193,11 +1254,21 @@ export class ObsidianLiveSyncSettingTab extends PluginSettingTab {
|
||||
this.plugin.saveSettings();
|
||||
await this.plugin.realizeSettingSyncMode();
|
||||
if (inWizard) {
|
||||
this.hide();
|
||||
// @ts-ignore
|
||||
this.plugin.app.setting.close()
|
||||
await this.plugin.resetLocalDatabase();
|
||||
await this.plugin.initializeDatabase(true)
|
||||
await this.plugin.initializeDatabase(true);
|
||||
if (rebuildRemote) {
|
||||
await this.plugin.markRemoteLocked();
|
||||
await this.plugin.tryResetRemoteDatabase();
|
||||
await this.plugin.markRemoteLocked();
|
||||
await this.plugin.markRemoteResolved();
|
||||
}
|
||||
await this.plugin.replicate(true);
|
||||
Logger("All done! Please set up subsequent devices with 'Copy setup URI' and 'Open setup URI'.", LOG_LEVEL.NOTICE)
|
||||
|
||||
Logger("All done! Please set up subsequent devices with 'Copy setup URI' and 'Open setup URI'.", LOG_LEVEL.NOTICE);
|
||||
// @ts-ignore
|
||||
this.plugin.app.commands.executeCommandById("obsidian-livesync:livesync-copysetupuri")
|
||||
}
|
||||
|
||||
|
||||
@@ -1214,6 +1285,50 @@ export class ObsidianLiveSyncSettingTab extends PluginSettingTab {
|
||||
|
||||
containerHatchEl.createEl("h3", { text: "Hatch" });
|
||||
|
||||
|
||||
new Setting(containerHatchEl)
|
||||
.setName("Make report to inform the issue")
|
||||
.setDesc("Verify and repair all files and update database without restoring")
|
||||
.addButton((button) =>
|
||||
button
|
||||
.setButtonText("Make report")
|
||||
.setDisabled(false)
|
||||
.onClick(async () => {
|
||||
let responseConfig: any = {};
|
||||
const REDACTED = "𝑅𝐸𝐷𝐴𝐶𝑇𝐸𝐷";
|
||||
try {
|
||||
const r = await requestToCouchDB(this.plugin.settings.couchDB_URI, this.plugin.settings.couchDB_USER, this.plugin.settings.couchDB_PASSWORD, window.origin);
|
||||
|
||||
Logger(JSON.stringify(r.json, null, 2));
|
||||
|
||||
responseConfig = r.json;
|
||||
responseConfig["couch_httpd_auth"].secret = REDACTED;
|
||||
responseConfig["couch_httpd_auth"].authentication_db = REDACTED;
|
||||
responseConfig["couch_httpd_auth"].authentication_redirect = REDACTED;
|
||||
responseConfig["couchdb"].uuid = REDACTED;
|
||||
responseConfig["admins"] = REDACTED;
|
||||
|
||||
} catch (ex) {
|
||||
responseConfig = "Requesting information to the remote CouchDB has been failed. If you are using IBM Cloudant, it is the normal behaviour."
|
||||
}
|
||||
const pluginConfig = JSON.parse(JSON.stringify(this.plugin.settings)) as ObsidianLiveSyncSettings;
|
||||
pluginConfig.couchDB_DBNAME = REDACTED;
|
||||
pluginConfig.couchDB_PASSWORD = REDACTED;
|
||||
pluginConfig.couchDB_URI = isCloudantURI(pluginConfig.couchDB_URI) ? "cloudant" : "self-hosted";
|
||||
pluginConfig.couchDB_USER = REDACTED;
|
||||
pluginConfig.passphrase = REDACTED;
|
||||
pluginConfig.workingPassphrase = REDACTED;
|
||||
|
||||
const msgConfig = `----remote config----
|
||||
${stringifyYaml(responseConfig)}
|
||||
---- Plug-in config ---
|
||||
${stringifyYaml(pluginConfig)}`;
|
||||
console.log(msgConfig);
|
||||
await navigator.clipboard.writeText(msgConfig);
|
||||
Logger(`Information has been copied to clipboard`, LOG_LEVEL.NOTICE);
|
||||
})
|
||||
);
|
||||
|
||||
if (this.plugin.localDatabase.remoteLockedAndDeviceNotAccepted) {
|
||||
const c = containerHatchEl.createEl("div", {
|
||||
text: "To prevent unwanted vault corruption, the remote database has been locked for synchronization, and this device was not marked as 'resolved'. it caused by some operations like this. re-initialized. Local database initialization should be required. please back your vault up, reset local database, and press 'Mark this device as resolved'. ",
|
||||
|
||||
@@ -98,7 +98,7 @@ export class PopoverSelectString extends FuzzySuggestModal<string> {
|
||||
constructor(app: App, note: string, placeholder: string | null, getItemsFun: () => string[], callback: (e: string) => void) {
|
||||
super(app);
|
||||
this.app = app;
|
||||
this.setPlaceholder(placeholder ?? "y/n) " + note);
|
||||
this.setPlaceholder((placeholder ?? "y/n) ") + note);
|
||||
if (getItemsFun) this.getItemsFun = getItemsFun;
|
||||
this.callback = callback;
|
||||
}
|
||||
|
||||
2
src/lib
712
src/main.ts
89
updates.md
@@ -1,50 +1,55 @@
|
||||
### 0.16.0
|
||||
- Now hidden files need not be scanned. Changes will be detected automatically.
|
||||
- If you want it to back to its previous behaviour, please disable `Monitor changes to internal files`.
|
||||
- Due to using an internal API, this feature may become unusable with a major update. If this happens, please disable this once.
|
||||
|
||||
#### Minors
|
||||
|
||||
- 0.16.1 Added missing log updates.
|
||||
- 0.16.2 Fixed many problems caused by combinations of `Sync On Save` and the tracking logic that changed at 0.15.6.
|
||||
- 0.16.3
|
||||
- Fixed detection of IBM Cloudant (And if there are some issues, be fixed automatically).
|
||||
- A configuration information reporting tool has been implemented.
|
||||
- 0.16.4 Fixed detection failure. Please set the `Chunk size` again when using a self-hosted database.
|
||||
- 0.16.5
|
||||
- Fixed
|
||||
- Conflict detection and merging now be able to treat deleted files.
|
||||
- Logs while the boot-up sequence has been tidied up.
|
||||
- Fixed incorrect log entries.
|
||||
- New Feature
|
||||
- The feature of automatically deleting old expired metadata has been implemented.
|
||||
We can configure it in `Delete old metadata of deleted files on start-up` in the `General Settings` pane.
|
||||
- 0.16.6
|
||||
- Fixed
|
||||
- Automatic (temporary) batch size adjustment has been restored to work correctly.
|
||||
- Chunk splitting has been backed to the previous behaviour for saving them correctly.
|
||||
- Improved
|
||||
- Corrupted chunks will be detected automatically.
|
||||
- Now on the case-insensitive system, `aaa.md` and `AAA.md` will be treated as the same file or path at applying changesets.
|
||||
- 0.16.7 Nothing has been changed except toolsets, framework library, and as like them. Please inform me if something had been getting strange!
|
||||
- 0.16.8 Now we can synchronise without `bad_request:invalid UTF-8 JSON` even while end-to-end encryption has been disabled.
|
||||
|
||||
Note:
|
||||
Before 0.16.5, LiveSync had some issues making chunks. In this case, synchronisation had became been always failing after a corrupted one should be made. After 0.16.6, the corrupted chunk is automatically detected. Sorry for troubling you but please do `rebuild everything` when this plug-in notified so.
|
||||
|
||||
### 0.15.0
|
||||
- Outdated configuration items have been removed.
|
||||
- Outdated configuration items have been removed.
|
||||
- Setup wizard has been implemented!
|
||||
|
||||
I appreciate for reviewing and giving me advice @Pouhon158!
|
||||
|
||||
#### Minors
|
||||
- 0.15.1 Missed the stylesheet.
|
||||
- 0.15.2 The wizard has been improved and documented!
|
||||
- 0.15.3 Fixed the issue about locking/unlocking remote database while rebuilding in the wizard.
|
||||
- 0.15.4 Fixed issues about asynchronous processing (e.g., Conflict check or hidden file detection)
|
||||
- 0.15.5 Add new features for setting Self-hosted LiveSync up more easier.
|
||||
- 0.15.6 File tracking logic has been refined.
|
||||
- 0.15.7 Fixed bug about renaming file.
|
||||
- 0.15.8 Fixed bug about deleting empty directory, weird behaviour on boot-sequence on mobile devices.
|
||||
- 0.15.9 Improved chunk retrieving, now chunks are retrieved in batch on continuous requests.
|
||||
- 0.15.10 Fixed:
|
||||
- The boot sequence has been corrected and now boots smoothly.
|
||||
- Auto applying of batch save will be processed earlier than before.
|
||||
|
||||
### 0.14.1
|
||||
- The target selecting filter was implemented.
|
||||
Now we can set what files are synchronised by regular expression.
|
||||
- We can configure the size of chunks.
|
||||
We can use larger chunks to improve performance.
|
||||
(This feature can not be used with IBM Cloudant)
|
||||
- Read chunks online.
|
||||
Now we can synchronise only metadata and retrieve chunks on demand. It reduces local database size and time for replication.
|
||||
- Added this note.
|
||||
- Use local chunks in preference to remote them if present,
|
||||
|
||||
#### Recommended configuration for Self-hosted CouchDB
|
||||
- Set chunk size to around 100 to 250 (10MB - 25MB per chunk)
|
||||
- *Set batch size to 100 and batch limit to 20 (0.14.2)*
|
||||
- Be sure to `Read chunks online` checked.
|
||||
|
||||
#### Minors
|
||||
- 0.14.2 Fixed issue about retrieving files if synchronisation has been interrupted or failed
|
||||
- 0.14.3 New test items have been added to `Check database configuration`.
|
||||
- 0.14.4 Fixed issue of importing configurations.
|
||||
- 0.14.5 Auto chunk size adjusting implemented.
|
||||
- 0.14.6 Change Target to ES2018
|
||||
- 0.14.7 Refactor and fix typos.
|
||||
- 0.14.8 Refactored again. There should be no change in behaviour, but please let me know if there is any.
|
||||
### 0.13.0
|
||||
|
||||
- The metadata of the deleted files will be kept on the database by default. If you want to delete this as the previous version, please turn on `Delete metadata of deleted files.`. And, if you have upgraded from the older version, please ensure every device has been upgraded.
|
||||
- Please turn on `Delete metadata of deleted files.` if you are using livesync-classroom or filesystem-livesync.
|
||||
- We can see the history of deleted files.
|
||||
- `Pick file to show` was renamed to `Pick a file to show.
|
||||
- Files in the `Pick a file to show` are now ordered by their modified date descent.
|
||||
- Update information became to be shown on the major upgrade.
|
||||
|
||||
#### Minors
|
||||
- 0.13.1 Fixed on conflict resolution.
|
||||
- 0.13.2 Fixed file deletion failures.
|
||||
- 0.13.4
|
||||
- Now, we can synchronise hidden files that conflicted on each devices.
|
||||
- We can search for conflicting docs.
|
||||
- Pending processes can now be run at any time.
|
||||
- Performance improved on synchronising large numbers of files at once.
|
||||
... To continue on to `updates_old.md`.
|
||||
42
updates_old.md
Normal file
@@ -0,0 +1,42 @@
|
||||
### 0.14.1
|
||||
- The target selecting filter was implemented.
|
||||
Now we can set what files are synchronised by regular expression.
|
||||
- We can configure the size of chunks.
|
||||
We can use larger chunks to improve performance.
|
||||
(This feature can not be used with IBM Cloudant)
|
||||
- Read chunks online.
|
||||
Now we can synchronise only metadata and retrieve chunks on demand. It reduces local database size and time for replication.
|
||||
- Added this note.
|
||||
- Use local chunks in preference to remote them if present,
|
||||
|
||||
#### Recommended configuration for Self-hosted CouchDB
|
||||
- Set chunk size to around 100 to 250 (10MB - 25MB per chunk)
|
||||
- *Set batch size to 100 and batch limit to 20 (0.14.2)*
|
||||
- Be sure to `Read chunks online` checked.
|
||||
|
||||
#### Minors
|
||||
- 0.14.2 Fixed issue about retrieving files if synchronisation has been interrupted or failed
|
||||
- 0.14.3 New test items have been added to `Check database configuration`.
|
||||
- 0.14.4 Fixed issue of importing configurations.
|
||||
- 0.14.5 Auto chunk size adjusting implemented.
|
||||
- 0.14.6 Change Target to ES2018
|
||||
- 0.14.7 Refactor and fix typos.
|
||||
- 0.14.8 Refactored again. There should be no change in behaviour, but please let me know if there is any.
|
||||
|
||||
### 0.13.0
|
||||
|
||||
- The metadata of the deleted files will be kept on the database by default. If you want to delete this as the previous version, please turn on `Delete metadata of deleted files.`. And, if you have upgraded from the older version, please ensure every device has been upgraded.
|
||||
- Please turn on `Delete metadata of deleted files.` if you are using livesync-classroom or filesystem-livesync.
|
||||
- We can see the history of deleted files.
|
||||
- `Pick file to show` was renamed to `Pick a file to show.
|
||||
- Files in the `Pick a file to show` are now ordered by their modified date descent.
|
||||
- Update information became to be shown on the major upgrade.
|
||||
|
||||
#### Minors
|
||||
- 0.13.1 Fixed on conflict resolution.
|
||||
- 0.13.2 Fixed file deletion failures.
|
||||
- 0.13.4
|
||||
- Now, we can synchronise hidden files that conflicted on each devices.
|
||||
- We can search for conflicting docs.
|
||||
- Pending processes can now be run at any time.
|
||||
- Performance improved on synchronising large numbers of files at once.
|
||||