mirror of
https://github.com/vrtmrz/obsidian-livesync.git
synced 2025-12-13 17:55:56 +00:00
Refactored and touched up some.
Not available on iOS yet, be careful!
This commit is contained in:
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
[submodule "src/lib"]
|
||||||
|
path = src/lib
|
||||||
|
url = https://github.com/vrtmrz/livesync-commonlib
|
||||||
1
lib
Submodule
1
lib
Submodule
Submodule lib added at 315ef99845
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"id": "obsidian-livesync",
|
"id": "obsidian-livesync",
|
||||||
"name": "Self-hosted LiveSync",
|
"name": "Self-hosted LiveSync",
|
||||||
"version": "0.8.3",
|
"version": "0.8.4",
|
||||||
"minAppVersion": "0.9.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.",
|
"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",
|
"author": "vorotamoroz",
|
||||||
|
|||||||
684
package-lock.json
generated
684
package-lock.json
generated
@@ -1,15 +1,23 @@
|
|||||||
{
|
{
|
||||||
"name": "obsidian-livesync",
|
"name": "obsidian-livesync",
|
||||||
"version": "0.8.3",
|
"version": "0.8.4",
|
||||||
"lockfileVersion": 2,
|
"lockfileVersion": 2,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "obsidian-livesync",
|
"name": "obsidian-livesync",
|
||||||
"version": "0.8.3",
|
"version": "0.8.4",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"diff-match-patch": "^1.0.5",
|
"diff-match-patch": "^1.0.5",
|
||||||
|
"esbuild": "0.13.12",
|
||||||
|
"esbuild-svelte": "^0.6.0",
|
||||||
|
"pouchdb-adapter-http": "^7.3.0",
|
||||||
|
"pouchdb-adapter-idb": "^7.3.0",
|
||||||
|
"pouchdb-core": "^7.3.0",
|
||||||
|
"pouchdb-mapreduce": "^7.3.0",
|
||||||
|
"pouchdb-replication": "^7.3.0",
|
||||||
|
"svelte-preprocess": "^4.10.2",
|
||||||
"xxhash-wasm": "^0.4.2"
|
"xxhash-wasm": "^0.4.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
@@ -791,6 +799,17 @@
|
|||||||
"url": "https://opencollective.com/typescript-eslint"
|
"url": "https://opencollective.com/typescript-eslint"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/abort-controller": {
|
||||||
|
"version": "3.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz",
|
||||||
|
"integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==",
|
||||||
|
"dependencies": {
|
||||||
|
"event-target-shim": "^5.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6.5"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/acorn": {
|
"node_modules/acorn": {
|
||||||
"version": "7.4.1",
|
"version": "7.4.1",
|
||||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz",
|
||||||
@@ -870,6 +889,11 @@
|
|||||||
"sprintf-js": "~1.0.2"
|
"sprintf-js": "~1.0.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/argsarray": {
|
||||||
|
"version": "0.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/argsarray/-/argsarray-0.0.1.tgz",
|
||||||
|
"integrity": "sha1-bnIHtOzbObCviDA/pa4ivajfYcs="
|
||||||
|
},
|
||||||
"node_modules/array-includes": {
|
"node_modules/array-includes": {
|
||||||
"version": "3.1.4",
|
"version": "3.1.4",
|
||||||
"resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.4.tgz",
|
"resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.4.tgz",
|
||||||
@@ -961,6 +985,11 @@
|
|||||||
"node": "*"
|
"node": "*"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/buffer-from": {
|
||||||
|
"version": "1.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
|
||||||
|
"integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ=="
|
||||||
|
},
|
||||||
"node_modules/builtin-modules": {
|
"node_modules/builtin-modules": {
|
||||||
"version": "3.2.0",
|
"version": "3.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.2.0.tgz",
|
||||||
@@ -1011,6 +1040,14 @@
|
|||||||
"url": "https://github.com/chalk/chalk?sponsor=1"
|
"url": "https://github.com/chalk/chalk?sponsor=1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/clone-buffer": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/clone-buffer/-/clone-buffer-1.0.0.tgz",
|
||||||
|
"integrity": "sha1-4+JbIHrE5wGvch4staFnksrD3Fg=",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.10"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/color-convert": {
|
"node_modules/color-convert": {
|
||||||
"version": "2.0.1",
|
"version": "2.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
|
||||||
@@ -1832,6 +1869,14 @@
|
|||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/event-target-shim": {
|
||||||
|
"version": "5.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz",
|
||||||
|
"integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/fast-deep-equal": {
|
"node_modules/fast-deep-equal": {
|
||||||
"version": "3.1.3",
|
"version": "3.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
|
||||||
@@ -1875,6 +1920,17 @@
|
|||||||
"reusify": "^1.0.4"
|
"reusify": "^1.0.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/fetch-cookie": {
|
||||||
|
"version": "0.11.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/fetch-cookie/-/fetch-cookie-0.11.0.tgz",
|
||||||
|
"integrity": "sha512-BQm7iZLFhMWFy5CZ/162sAGjBfdNWb7a8LEqqnzsHFhxT/X/SVj/z2t2nu3aJvjlbQkrAlTUApplPRjWyH4mhA==",
|
||||||
|
"dependencies": {
|
||||||
|
"tough-cookie": "^2.3.3 || ^3.0.1 || ^4.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/file-entry-cache": {
|
"node_modules/file-entry-cache": {
|
||||||
"version": "6.0.1",
|
"version": "6.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz",
|
||||||
@@ -2131,6 +2187,11 @@
|
|||||||
"node": ">= 4"
|
"node": ">= 4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/immediate": {
|
||||||
|
"version": "3.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/immediate/-/immediate-3.3.0.tgz",
|
||||||
|
"integrity": "sha512-HR7EVodfFUdQCTIeySw+WDRFJlPcLOJbXfwwZ7Oom6tjsvZ3bOkCDJHehQC3nxJrv7+f9XecwazynjU8e4Vw3Q=="
|
||||||
|
},
|
||||||
"node_modules/import-fresh": {
|
"node_modules/import-fresh": {
|
||||||
"version": "3.3.0",
|
"version": "3.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
|
||||||
@@ -2169,8 +2230,7 @@
|
|||||||
"node_modules/inherits": {
|
"node_modules/inherits": {
|
||||||
"version": "2.0.4",
|
"version": "2.0.4",
|
||||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
|
||||||
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
|
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"node_modules/internal-slot": {
|
"node_modules/internal-slot": {
|
||||||
"version": "1.0.3",
|
"version": "1.0.3",
|
||||||
@@ -2591,6 +2651,25 @@
|
|||||||
"integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=",
|
"integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/node-fetch": {
|
||||||
|
"version": "2.6.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz",
|
||||||
|
"integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"whatwg-url": "^5.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "4.x || >=6.0.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"encoding": "^0.1.0"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"encoding": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/object-inspect": {
|
"node_modules/object-inspect": {
|
||||||
"version": "1.11.1",
|
"version": "1.11.1",
|
||||||
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.11.1.tgz",
|
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.11.1.tgz",
|
||||||
@@ -2807,6 +2886,218 @@
|
|||||||
"node": ">=4"
|
"node": ">=4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/pouchdb-abstract-mapreduce": {
|
||||||
|
"version": "7.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/pouchdb-abstract-mapreduce/-/pouchdb-abstract-mapreduce-7.3.0.tgz",
|
||||||
|
"integrity": "sha512-+2fVt3SDh7D776lIGbYZOsKX5js1aUyUw7iJaTGitxSdQ2ObWSTrr3SUrj5Qo1CkgPXwRM3Tdoq/53JYAa2qCA==",
|
||||||
|
"dependencies": {
|
||||||
|
"pouchdb-binary-utils": "7.3.0",
|
||||||
|
"pouchdb-collate": "7.3.0",
|
||||||
|
"pouchdb-collections": "7.3.0",
|
||||||
|
"pouchdb-errors": "7.3.0",
|
||||||
|
"pouchdb-fetch": "7.3.0",
|
||||||
|
"pouchdb-mapreduce-utils": "7.3.0",
|
||||||
|
"pouchdb-md5": "7.3.0",
|
||||||
|
"pouchdb-utils": "7.3.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/pouchdb-adapter-http": {
|
||||||
|
"version": "7.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/pouchdb-adapter-http/-/pouchdb-adapter-http-7.3.0.tgz",
|
||||||
|
"integrity": "sha512-7nNfpbvL0MEu3RtwKkhi3VTxWDrSfEKyrWspSAhsFsn980okth5SRsEIQw0eJ4yNgJaVd47B/mUYVNphpyMTyQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"argsarray": "0.0.1",
|
||||||
|
"pouchdb-binary-utils": "7.3.0",
|
||||||
|
"pouchdb-errors": "7.3.0",
|
||||||
|
"pouchdb-fetch": "7.3.0",
|
||||||
|
"pouchdb-utils": "7.3.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/pouchdb-adapter-idb": {
|
||||||
|
"version": "7.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/pouchdb-adapter-idb/-/pouchdb-adapter-idb-7.3.0.tgz",
|
||||||
|
"integrity": "sha512-qMy0lrB+LyOFyFUo7Gfr5VvSM1IXyP2c9N2XwmMSSaTib/OsNnBqLj8AWrgPEnzvEkDgImBkk34e5F6MlUFRyA==",
|
||||||
|
"dependencies": {
|
||||||
|
"pouchdb-adapter-utils": "7.3.0",
|
||||||
|
"pouchdb-binary-utils": "7.3.0",
|
||||||
|
"pouchdb-collections": "7.3.0",
|
||||||
|
"pouchdb-errors": "7.3.0",
|
||||||
|
"pouchdb-json": "7.3.0",
|
||||||
|
"pouchdb-merge": "7.3.0",
|
||||||
|
"pouchdb-utils": "7.3.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/pouchdb-adapter-utils": {
|
||||||
|
"version": "7.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/pouchdb-adapter-utils/-/pouchdb-adapter-utils-7.3.0.tgz",
|
||||||
|
"integrity": "sha512-mU1+smcagWSpInVx/VQk7VVjjnJlyagKtusUS3OdCMFZY35L6RbXC8eIhoNVDbkBfEv3cIwqQ3t7fdvkaa1odQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"pouchdb-binary-utils": "7.3.0",
|
||||||
|
"pouchdb-collections": "7.3.0",
|
||||||
|
"pouchdb-errors": "7.3.0",
|
||||||
|
"pouchdb-md5": "7.3.0",
|
||||||
|
"pouchdb-merge": "7.3.0",
|
||||||
|
"pouchdb-utils": "7.3.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/pouchdb-binary-utils": {
|
||||||
|
"version": "7.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/pouchdb-binary-utils/-/pouchdb-binary-utils-7.3.0.tgz",
|
||||||
|
"integrity": "sha512-xvBH/XGHGcou2vkEzszJxkCc7YElfRUrkLUg51Jbdmh1mogLDUO0bU3Tj6TOIIJfRkQrU/HV+dDkMAhsil0amQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"buffer-from": "1.1.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/pouchdb-changes-filter": {
|
||||||
|
"version": "7.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/pouchdb-changes-filter/-/pouchdb-changes-filter-7.3.0.tgz",
|
||||||
|
"integrity": "sha512-9E/EC9BP9dH9sfqUBdcWlR5HHeDdWqP82MmdEtg5c8spgxttYPwqrPfSHa7T2n55IRnaIoQbVyndmfAoz9GsOw==",
|
||||||
|
"dependencies": {
|
||||||
|
"pouchdb-errors": "7.3.0",
|
||||||
|
"pouchdb-selector-core": "7.3.0",
|
||||||
|
"pouchdb-utils": "7.3.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/pouchdb-checkpointer": {
|
||||||
|
"version": "7.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/pouchdb-checkpointer/-/pouchdb-checkpointer-7.3.0.tgz",
|
||||||
|
"integrity": "sha512-ioK7O9iBM/VJ4lJ0hAQ9zt57wZyBcVJnraEX0uN+FVTVh07xNIM8GhMRNE/rfHYXcT5a5uS0Ody6Q66JXaDzZA==",
|
||||||
|
"dependencies": {
|
||||||
|
"pouchdb-collate": "7.3.0",
|
||||||
|
"pouchdb-utils": "7.3.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/pouchdb-collate": {
|
||||||
|
"version": "7.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/pouchdb-collate/-/pouchdb-collate-7.3.0.tgz",
|
||||||
|
"integrity": "sha512-ys7rXKtEr6cfghgUjknwFJiOkITebV6JmeTybJKCzMV0r2luXu0OoPQsKVpE/wbM/3F5LxfpbFKGFpPcfGMvTA=="
|
||||||
|
},
|
||||||
|
"node_modules/pouchdb-collections": {
|
||||||
|
"version": "7.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/pouchdb-collections/-/pouchdb-collections-7.3.0.tgz",
|
||||||
|
"integrity": "sha512-Xr54m2+fErShXn+qAT4xwqJ+8NwddNPeTMJT4z4k1sZsrwfHmZsWbsKAyGPMF04eQaaU+7DDRMciu2VzaBUXyg=="
|
||||||
|
},
|
||||||
|
"node_modules/pouchdb-core": {
|
||||||
|
"version": "7.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/pouchdb-core/-/pouchdb-core-7.3.0.tgz",
|
||||||
|
"integrity": "sha512-fpEbjrYzmZivSupl7V0Aa2vHivyJHi9gx7+d021Wxajx4br515eYcN6Whk/L0L4xgoDVKoqUwmv+XgEF8EZhwg==",
|
||||||
|
"dependencies": {
|
||||||
|
"argsarray": "0.0.1",
|
||||||
|
"inherits": "2.0.4",
|
||||||
|
"pouchdb-changes-filter": "7.3.0",
|
||||||
|
"pouchdb-collections": "7.3.0",
|
||||||
|
"pouchdb-errors": "7.3.0",
|
||||||
|
"pouchdb-fetch": "7.3.0",
|
||||||
|
"pouchdb-merge": "7.3.0",
|
||||||
|
"pouchdb-utils": "7.3.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/pouchdb-errors": {
|
||||||
|
"version": "7.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/pouchdb-errors/-/pouchdb-errors-7.3.0.tgz",
|
||||||
|
"integrity": "sha512-dTBbIC1BbCy6J9W/Csg5xROgb3wJN3HpbgAJHHSEtAkb8oA45KZmU3ZwEpNhf0AfPuQm4XgW1936PvlDlGgJiw==",
|
||||||
|
"dependencies": {
|
||||||
|
"inherits": "2.0.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/pouchdb-fetch": {
|
||||||
|
"version": "7.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/pouchdb-fetch/-/pouchdb-fetch-7.3.0.tgz",
|
||||||
|
"integrity": "sha512-8/lcg8iMDG+GVs1dHNXA4ktJSEpH71dHU3xesMJ25tNQOqfAaaWrkfz9j71ZYDDkveLYE6UjUzl/sDacu2hSjw==",
|
||||||
|
"dependencies": {
|
||||||
|
"abort-controller": "3.0.0",
|
||||||
|
"fetch-cookie": "0.11.0",
|
||||||
|
"node-fetch": "2.6.7"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/pouchdb-generate-replication-id": {
|
||||||
|
"version": "7.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/pouchdb-generate-replication-id/-/pouchdb-generate-replication-id-7.3.0.tgz",
|
||||||
|
"integrity": "sha512-7a9rMlmnZeffRhDyvyn5syGddO2fVrKAKrLEe3Nw/y5Ns7/j/XRfQdFu5xjwwsdudA3L7niA2DpLoANeBDpm/Q==",
|
||||||
|
"dependencies": {
|
||||||
|
"pouchdb-collate": "7.3.0",
|
||||||
|
"pouchdb-md5": "7.3.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/pouchdb-json": {
|
||||||
|
"version": "7.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/pouchdb-json/-/pouchdb-json-7.3.0.tgz",
|
||||||
|
"integrity": "sha512-D4wyi20ltyiFpuziQeMk3CbXs/Q58VoGTYTJQY8MWBw37OidtHGQAt1Kh5yJ435wJqDzJZyxMA5RxGZxEOBDVg==",
|
||||||
|
"dependencies": {
|
||||||
|
"vuvuzela": "1.0.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/pouchdb-mapreduce": {
|
||||||
|
"version": "7.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/pouchdb-mapreduce/-/pouchdb-mapreduce-7.3.0.tgz",
|
||||||
|
"integrity": "sha512-lhSQvUvHTt9c5Sd1stqqsSB8AYoKx99BHCRy2YxNEKbWCQdEIZqiPfRJcSlm2BtPz8hsA6yHMbPz20nXMep2yg==",
|
||||||
|
"dependencies": {
|
||||||
|
"pouchdb-abstract-mapreduce": "7.3.0",
|
||||||
|
"pouchdb-mapreduce-utils": "7.3.0",
|
||||||
|
"pouchdb-utils": "7.3.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/pouchdb-mapreduce-utils": {
|
||||||
|
"version": "7.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/pouchdb-mapreduce-utils/-/pouchdb-mapreduce-utils-7.3.0.tgz",
|
||||||
|
"integrity": "sha512-KDVSd+H2r+XWTrQfKWV71SknDDYRjYXoeWs0ZQl3xITHCcTl+fIgqyagg/XN+Zy/U9LeLPGMe2JdgPx9H8lJgw==",
|
||||||
|
"dependencies": {
|
||||||
|
"argsarray": "0.0.1",
|
||||||
|
"inherits": "2.0.4",
|
||||||
|
"pouchdb-collections": "7.3.0",
|
||||||
|
"pouchdb-utils": "7.3.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/pouchdb-md5": {
|
||||||
|
"version": "7.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/pouchdb-md5/-/pouchdb-md5-7.3.0.tgz",
|
||||||
|
"integrity": "sha512-wL04QgoKyd/L/TV5gxgcvlEyCJiZoXCOEFJklTzkdza/kBQNJGPH7i0ZhKa7Sb+AvZYoWZHddf1Zgv7rBScHkA==",
|
||||||
|
"dependencies": {
|
||||||
|
"pouchdb-binary-utils": "7.3.0",
|
||||||
|
"spark-md5": "3.0.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/pouchdb-merge": {
|
||||||
|
"version": "7.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/pouchdb-merge/-/pouchdb-merge-7.3.0.tgz",
|
||||||
|
"integrity": "sha512-E7LmchMzwYFm6V8OBxejzARLisanpksOju2LEfuiYnotGfNDeW7MByP0qBH0/zF8BfUyyjA1cl7ByaEpsapkeQ=="
|
||||||
|
},
|
||||||
|
"node_modules/pouchdb-replication": {
|
||||||
|
"version": "7.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/pouchdb-replication/-/pouchdb-replication-7.3.0.tgz",
|
||||||
|
"integrity": "sha512-Z3kwrka9EXrE9kIm0Dw3h8wf8ErKzBJlhlXpDqDmETjC8V7TlEc2EbVXEH6veIt6XdsNQGHMfStVm2HERvTmNA==",
|
||||||
|
"dependencies": {
|
||||||
|
"inherits": "2.0.4",
|
||||||
|
"pouchdb-checkpointer": "7.3.0",
|
||||||
|
"pouchdb-errors": "7.3.0",
|
||||||
|
"pouchdb-generate-replication-id": "7.3.0",
|
||||||
|
"pouchdb-utils": "7.3.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/pouchdb-selector-core": {
|
||||||
|
"version": "7.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/pouchdb-selector-core/-/pouchdb-selector-core-7.3.0.tgz",
|
||||||
|
"integrity": "sha512-sK/cCrIGeL9ImcMhKGcwa54+bzX7Wv4hhVV+oUW3T1Nasaoxh+Muem1GuA+x1+SbTCE8y37rUg8i6DIOhX51ew==",
|
||||||
|
"dependencies": {
|
||||||
|
"pouchdb-collate": "7.3.0",
|
||||||
|
"pouchdb-utils": "7.3.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/pouchdb-utils": {
|
||||||
|
"version": "7.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/pouchdb-utils/-/pouchdb-utils-7.3.0.tgz",
|
||||||
|
"integrity": "sha512-HH+5IXXWn/ZgVCSnrlydBMYn6MabT7RS7SNoo9w8qVH9efpZSp3eLchw6yMQNLw8LQefWmbbskiHV9VgJmSVWQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"argsarray": "0.0.1",
|
||||||
|
"clone-buffer": "1.0.0",
|
||||||
|
"immediate": "3.3.0",
|
||||||
|
"inherits": "2.0.4",
|
||||||
|
"pouchdb-collections": "7.3.0",
|
||||||
|
"pouchdb-errors": "7.3.0",
|
||||||
|
"pouchdb-md5": "7.3.0",
|
||||||
|
"uuid": "8.3.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/prelude-ls": {
|
"node_modules/prelude-ls": {
|
||||||
"version": "1.2.1",
|
"version": "1.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
|
||||||
@@ -2825,11 +3116,15 @@
|
|||||||
"node": ">=0.4.0"
|
"node": ">=0.4.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/psl": {
|
||||||
|
"version": "1.8.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz",
|
||||||
|
"integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ=="
|
||||||
|
},
|
||||||
"node_modules/punycode": {
|
"node_modules/punycode": {
|
||||||
"version": "2.1.1",
|
"version": "2.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
|
||||||
"integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
|
"integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
|
||||||
"dev": true,
|
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6"
|
"node": ">=6"
|
||||||
}
|
}
|
||||||
@@ -3081,6 +3376,11 @@
|
|||||||
"integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==",
|
"integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/spark-md5": {
|
||||||
|
"version": "3.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/spark-md5/-/spark-md5-3.0.2.tgz",
|
||||||
|
"integrity": "sha512-wcFzz9cDfbuqe0FZzfi2or1sgyIrsDwmPwfZC4hiNidPdPINjeUwNfv5kldczoEAcjl9Y1L3SM7Uz2PUEQzxQw=="
|
||||||
|
},
|
||||||
"node_modules/sprintf-js": {
|
"node_modules/sprintf-js": {
|
||||||
"version": "1.0.3",
|
"version": "1.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
|
||||||
@@ -3321,6 +3621,24 @@
|
|||||||
"node": ">=8.0"
|
"node": ">=8.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/tough-cookie": {
|
||||||
|
"version": "4.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.0.0.tgz",
|
||||||
|
"integrity": "sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg==",
|
||||||
|
"dependencies": {
|
||||||
|
"psl": "^1.1.33",
|
||||||
|
"punycode": "^2.1.1",
|
||||||
|
"universalify": "^0.1.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/tr46": {
|
||||||
|
"version": "0.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
|
||||||
|
"integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o="
|
||||||
|
},
|
||||||
"node_modules/tsconfig-paths": {
|
"node_modules/tsconfig-paths": {
|
||||||
"version": "3.12.0",
|
"version": "3.12.0",
|
||||||
"resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.12.0.tgz",
|
"resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.12.0.tgz",
|
||||||
@@ -3412,6 +3730,14 @@
|
|||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/universalify": {
|
||||||
|
"version": "0.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
|
||||||
|
"integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 4.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/uri-js": {
|
"node_modules/uri-js": {
|
||||||
"version": "4.4.1",
|
"version": "4.4.1",
|
||||||
"resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
|
||||||
@@ -3421,18 +3747,45 @@
|
|||||||
"punycode": "^2.1.0"
|
"punycode": "^2.1.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/uuid": {
|
||||||
|
"version": "8.3.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
|
||||||
|
"integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
|
||||||
|
"bin": {
|
||||||
|
"uuid": "dist/bin/uuid"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/v8-compile-cache": {
|
"node_modules/v8-compile-cache": {
|
||||||
"version": "2.3.0",
|
"version": "2.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz",
|
||||||
"integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==",
|
"integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/vuvuzela": {
|
||||||
|
"version": "1.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/vuvuzela/-/vuvuzela-1.0.3.tgz",
|
||||||
|
"integrity": "sha1-O+FF5YJxxzylUnndhR8SpoIRSws="
|
||||||
|
},
|
||||||
"node_modules/w3c-keyname": {
|
"node_modules/w3c-keyname": {
|
||||||
"version": "2.2.4",
|
"version": "2.2.4",
|
||||||
"resolved": "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.4.tgz",
|
"resolved": "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.4.tgz",
|
||||||
"integrity": "sha512-tOhfEwEzFLJzf6d1ZPkYfGj+FWhIpBux9ppoP3rlclw3Z0BZv3N7b7030Z1kYth+6rDuAsXUFr+d0VE6Ed1ikw==",
|
"integrity": "sha512-tOhfEwEzFLJzf6d1ZPkYfGj+FWhIpBux9ppoP3rlclw3Z0BZv3N7b7030Z1kYth+6rDuAsXUFr+d0VE6Ed1ikw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/webidl-conversions": {
|
||||||
|
"version": "3.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
|
||||||
|
"integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE="
|
||||||
|
},
|
||||||
|
"node_modules/whatwg-url": {
|
||||||
|
"version": "5.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
|
||||||
|
"integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=",
|
||||||
|
"dependencies": {
|
||||||
|
"tr46": "~0.0.3",
|
||||||
|
"webidl-conversions": "^3.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/which": {
|
"node_modules/which": {
|
||||||
"version": "2.0.2",
|
"version": "2.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
|
||||||
@@ -4108,6 +4461,14 @@
|
|||||||
"eslint-visitor-keys": "^3.0.0"
|
"eslint-visitor-keys": "^3.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"abort-controller": {
|
||||||
|
"version": "3.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz",
|
||||||
|
"integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==",
|
||||||
|
"requires": {
|
||||||
|
"event-target-shim": "^5.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"acorn": {
|
"acorn": {
|
||||||
"version": "7.4.1",
|
"version": "7.4.1",
|
||||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz",
|
||||||
@@ -4163,6 +4524,11 @@
|
|||||||
"sprintf-js": "~1.0.2"
|
"sprintf-js": "~1.0.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"argsarray": {
|
||||||
|
"version": "0.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/argsarray/-/argsarray-0.0.1.tgz",
|
||||||
|
"integrity": "sha1-bnIHtOzbObCviDA/pa4ivajfYcs="
|
||||||
|
},
|
||||||
"array-includes": {
|
"array-includes": {
|
||||||
"version": "3.1.4",
|
"version": "3.1.4",
|
||||||
"resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.4.tgz",
|
"resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.4.tgz",
|
||||||
@@ -4230,6 +4596,11 @@
|
|||||||
"integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=",
|
"integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"buffer-from": {
|
||||||
|
"version": "1.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
|
||||||
|
"integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ=="
|
||||||
|
},
|
||||||
"builtin-modules": {
|
"builtin-modules": {
|
||||||
"version": "3.2.0",
|
"version": "3.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.2.0.tgz",
|
||||||
@@ -4262,6 +4633,11 @@
|
|||||||
"supports-color": "^7.1.0"
|
"supports-color": "^7.1.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"clone-buffer": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/clone-buffer/-/clone-buffer-1.0.0.tgz",
|
||||||
|
"integrity": "sha1-4+JbIHrE5wGvch4staFnksrD3Fg="
|
||||||
|
},
|
||||||
"color-convert": {
|
"color-convert": {
|
||||||
"version": "2.0.1",
|
"version": "2.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
|
||||||
@@ -4857,6 +5233,11 @@
|
|||||||
"integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
|
"integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"event-target-shim": {
|
||||||
|
"version": "5.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz",
|
||||||
|
"integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ=="
|
||||||
|
},
|
||||||
"fast-deep-equal": {
|
"fast-deep-equal": {
|
||||||
"version": "3.1.3",
|
"version": "3.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
|
||||||
@@ -4897,6 +5278,14 @@
|
|||||||
"reusify": "^1.0.4"
|
"reusify": "^1.0.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"fetch-cookie": {
|
||||||
|
"version": "0.11.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/fetch-cookie/-/fetch-cookie-0.11.0.tgz",
|
||||||
|
"integrity": "sha512-BQm7iZLFhMWFy5CZ/162sAGjBfdNWb7a8LEqqnzsHFhxT/X/SVj/z2t2nu3aJvjlbQkrAlTUApplPRjWyH4mhA==",
|
||||||
|
"requires": {
|
||||||
|
"tough-cookie": "^2.3.3 || ^3.0.1 || ^4.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"file-entry-cache": {
|
"file-entry-cache": {
|
||||||
"version": "6.0.1",
|
"version": "6.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz",
|
||||||
@@ -5080,6 +5469,11 @@
|
|||||||
"integrity": "sha512-2zeMQpbKz5dhZ9IwL0gbxSW5w0NK/MSAMtNuhgIHEPmaU3vPdKPL0UdvUCXs5SS4JAwsBxysK5sFMW8ocFiVjQ==",
|
"integrity": "sha512-2zeMQpbKz5dhZ9IwL0gbxSW5w0NK/MSAMtNuhgIHEPmaU3vPdKPL0UdvUCXs5SS4JAwsBxysK5sFMW8ocFiVjQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"immediate": {
|
||||||
|
"version": "3.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/immediate/-/immediate-3.3.0.tgz",
|
||||||
|
"integrity": "sha512-HR7EVodfFUdQCTIeySw+WDRFJlPcLOJbXfwwZ7Oom6tjsvZ3bOkCDJHehQC3nxJrv7+f9XecwazynjU8e4Vw3Q=="
|
||||||
|
},
|
||||||
"import-fresh": {
|
"import-fresh": {
|
||||||
"version": "3.3.0",
|
"version": "3.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
|
||||||
@@ -5109,8 +5503,7 @@
|
|||||||
"inherits": {
|
"inherits": {
|
||||||
"version": "2.0.4",
|
"version": "2.0.4",
|
||||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
|
||||||
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
|
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"internal-slot": {
|
"internal-slot": {
|
||||||
"version": "1.0.3",
|
"version": "1.0.3",
|
||||||
@@ -5423,6 +5816,14 @@
|
|||||||
"integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=",
|
"integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node-fetch": {
|
||||||
|
"version": "2.6.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz",
|
||||||
|
"integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==",
|
||||||
|
"requires": {
|
||||||
|
"whatwg-url": "^5.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"object-inspect": {
|
"object-inspect": {
|
||||||
"version": "1.11.1",
|
"version": "1.11.1",
|
||||||
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.11.1.tgz",
|
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.11.1.tgz",
|
||||||
@@ -5582,6 +5983,218 @@
|
|||||||
"find-up": "^2.1.0"
|
"find-up": "^2.1.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"pouchdb-abstract-mapreduce": {
|
||||||
|
"version": "7.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/pouchdb-abstract-mapreduce/-/pouchdb-abstract-mapreduce-7.3.0.tgz",
|
||||||
|
"integrity": "sha512-+2fVt3SDh7D776lIGbYZOsKX5js1aUyUw7iJaTGitxSdQ2ObWSTrr3SUrj5Qo1CkgPXwRM3Tdoq/53JYAa2qCA==",
|
||||||
|
"requires": {
|
||||||
|
"pouchdb-binary-utils": "7.3.0",
|
||||||
|
"pouchdb-collate": "7.3.0",
|
||||||
|
"pouchdb-collections": "7.3.0",
|
||||||
|
"pouchdb-errors": "7.3.0",
|
||||||
|
"pouchdb-fetch": "7.3.0",
|
||||||
|
"pouchdb-mapreduce-utils": "7.3.0",
|
||||||
|
"pouchdb-md5": "7.3.0",
|
||||||
|
"pouchdb-utils": "7.3.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"pouchdb-adapter-http": {
|
||||||
|
"version": "7.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/pouchdb-adapter-http/-/pouchdb-adapter-http-7.3.0.tgz",
|
||||||
|
"integrity": "sha512-7nNfpbvL0MEu3RtwKkhi3VTxWDrSfEKyrWspSAhsFsn980okth5SRsEIQw0eJ4yNgJaVd47B/mUYVNphpyMTyQ==",
|
||||||
|
"requires": {
|
||||||
|
"argsarray": "0.0.1",
|
||||||
|
"pouchdb-binary-utils": "7.3.0",
|
||||||
|
"pouchdb-errors": "7.3.0",
|
||||||
|
"pouchdb-fetch": "7.3.0",
|
||||||
|
"pouchdb-utils": "7.3.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"pouchdb-adapter-idb": {
|
||||||
|
"version": "7.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/pouchdb-adapter-idb/-/pouchdb-adapter-idb-7.3.0.tgz",
|
||||||
|
"integrity": "sha512-qMy0lrB+LyOFyFUo7Gfr5VvSM1IXyP2c9N2XwmMSSaTib/OsNnBqLj8AWrgPEnzvEkDgImBkk34e5F6MlUFRyA==",
|
||||||
|
"requires": {
|
||||||
|
"pouchdb-adapter-utils": "7.3.0",
|
||||||
|
"pouchdb-binary-utils": "7.3.0",
|
||||||
|
"pouchdb-collections": "7.3.0",
|
||||||
|
"pouchdb-errors": "7.3.0",
|
||||||
|
"pouchdb-json": "7.3.0",
|
||||||
|
"pouchdb-merge": "7.3.0",
|
||||||
|
"pouchdb-utils": "7.3.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"pouchdb-adapter-utils": {
|
||||||
|
"version": "7.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/pouchdb-adapter-utils/-/pouchdb-adapter-utils-7.3.0.tgz",
|
||||||
|
"integrity": "sha512-mU1+smcagWSpInVx/VQk7VVjjnJlyagKtusUS3OdCMFZY35L6RbXC8eIhoNVDbkBfEv3cIwqQ3t7fdvkaa1odQ==",
|
||||||
|
"requires": {
|
||||||
|
"pouchdb-binary-utils": "7.3.0",
|
||||||
|
"pouchdb-collections": "7.3.0",
|
||||||
|
"pouchdb-errors": "7.3.0",
|
||||||
|
"pouchdb-md5": "7.3.0",
|
||||||
|
"pouchdb-merge": "7.3.0",
|
||||||
|
"pouchdb-utils": "7.3.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"pouchdb-binary-utils": {
|
||||||
|
"version": "7.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/pouchdb-binary-utils/-/pouchdb-binary-utils-7.3.0.tgz",
|
||||||
|
"integrity": "sha512-xvBH/XGHGcou2vkEzszJxkCc7YElfRUrkLUg51Jbdmh1mogLDUO0bU3Tj6TOIIJfRkQrU/HV+dDkMAhsil0amQ==",
|
||||||
|
"requires": {
|
||||||
|
"buffer-from": "1.1.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"pouchdb-changes-filter": {
|
||||||
|
"version": "7.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/pouchdb-changes-filter/-/pouchdb-changes-filter-7.3.0.tgz",
|
||||||
|
"integrity": "sha512-9E/EC9BP9dH9sfqUBdcWlR5HHeDdWqP82MmdEtg5c8spgxttYPwqrPfSHa7T2n55IRnaIoQbVyndmfAoz9GsOw==",
|
||||||
|
"requires": {
|
||||||
|
"pouchdb-errors": "7.3.0",
|
||||||
|
"pouchdb-selector-core": "7.3.0",
|
||||||
|
"pouchdb-utils": "7.3.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"pouchdb-checkpointer": {
|
||||||
|
"version": "7.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/pouchdb-checkpointer/-/pouchdb-checkpointer-7.3.0.tgz",
|
||||||
|
"integrity": "sha512-ioK7O9iBM/VJ4lJ0hAQ9zt57wZyBcVJnraEX0uN+FVTVh07xNIM8GhMRNE/rfHYXcT5a5uS0Ody6Q66JXaDzZA==",
|
||||||
|
"requires": {
|
||||||
|
"pouchdb-collate": "7.3.0",
|
||||||
|
"pouchdb-utils": "7.3.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"pouchdb-collate": {
|
||||||
|
"version": "7.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/pouchdb-collate/-/pouchdb-collate-7.3.0.tgz",
|
||||||
|
"integrity": "sha512-ys7rXKtEr6cfghgUjknwFJiOkITebV6JmeTybJKCzMV0r2luXu0OoPQsKVpE/wbM/3F5LxfpbFKGFpPcfGMvTA=="
|
||||||
|
},
|
||||||
|
"pouchdb-collections": {
|
||||||
|
"version": "7.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/pouchdb-collections/-/pouchdb-collections-7.3.0.tgz",
|
||||||
|
"integrity": "sha512-Xr54m2+fErShXn+qAT4xwqJ+8NwddNPeTMJT4z4k1sZsrwfHmZsWbsKAyGPMF04eQaaU+7DDRMciu2VzaBUXyg=="
|
||||||
|
},
|
||||||
|
"pouchdb-core": {
|
||||||
|
"version": "7.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/pouchdb-core/-/pouchdb-core-7.3.0.tgz",
|
||||||
|
"integrity": "sha512-fpEbjrYzmZivSupl7V0Aa2vHivyJHi9gx7+d021Wxajx4br515eYcN6Whk/L0L4xgoDVKoqUwmv+XgEF8EZhwg==",
|
||||||
|
"requires": {
|
||||||
|
"argsarray": "0.0.1",
|
||||||
|
"inherits": "2.0.4",
|
||||||
|
"pouchdb-changes-filter": "7.3.0",
|
||||||
|
"pouchdb-collections": "7.3.0",
|
||||||
|
"pouchdb-errors": "7.3.0",
|
||||||
|
"pouchdb-fetch": "7.3.0",
|
||||||
|
"pouchdb-merge": "7.3.0",
|
||||||
|
"pouchdb-utils": "7.3.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"pouchdb-errors": {
|
||||||
|
"version": "7.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/pouchdb-errors/-/pouchdb-errors-7.3.0.tgz",
|
||||||
|
"integrity": "sha512-dTBbIC1BbCy6J9W/Csg5xROgb3wJN3HpbgAJHHSEtAkb8oA45KZmU3ZwEpNhf0AfPuQm4XgW1936PvlDlGgJiw==",
|
||||||
|
"requires": {
|
||||||
|
"inherits": "2.0.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"pouchdb-fetch": {
|
||||||
|
"version": "7.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/pouchdb-fetch/-/pouchdb-fetch-7.3.0.tgz",
|
||||||
|
"integrity": "sha512-8/lcg8iMDG+GVs1dHNXA4ktJSEpH71dHU3xesMJ25tNQOqfAaaWrkfz9j71ZYDDkveLYE6UjUzl/sDacu2hSjw==",
|
||||||
|
"requires": {
|
||||||
|
"abort-controller": "3.0.0",
|
||||||
|
"fetch-cookie": "0.11.0",
|
||||||
|
"node-fetch": "2.6.7"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"pouchdb-generate-replication-id": {
|
||||||
|
"version": "7.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/pouchdb-generate-replication-id/-/pouchdb-generate-replication-id-7.3.0.tgz",
|
||||||
|
"integrity": "sha512-7a9rMlmnZeffRhDyvyn5syGddO2fVrKAKrLEe3Nw/y5Ns7/j/XRfQdFu5xjwwsdudA3L7niA2DpLoANeBDpm/Q==",
|
||||||
|
"requires": {
|
||||||
|
"pouchdb-collate": "7.3.0",
|
||||||
|
"pouchdb-md5": "7.3.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"pouchdb-json": {
|
||||||
|
"version": "7.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/pouchdb-json/-/pouchdb-json-7.3.0.tgz",
|
||||||
|
"integrity": "sha512-D4wyi20ltyiFpuziQeMk3CbXs/Q58VoGTYTJQY8MWBw37OidtHGQAt1Kh5yJ435wJqDzJZyxMA5RxGZxEOBDVg==",
|
||||||
|
"requires": {
|
||||||
|
"vuvuzela": "1.0.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"pouchdb-mapreduce": {
|
||||||
|
"version": "7.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/pouchdb-mapreduce/-/pouchdb-mapreduce-7.3.0.tgz",
|
||||||
|
"integrity": "sha512-lhSQvUvHTt9c5Sd1stqqsSB8AYoKx99BHCRy2YxNEKbWCQdEIZqiPfRJcSlm2BtPz8hsA6yHMbPz20nXMep2yg==",
|
||||||
|
"requires": {
|
||||||
|
"pouchdb-abstract-mapreduce": "7.3.0",
|
||||||
|
"pouchdb-mapreduce-utils": "7.3.0",
|
||||||
|
"pouchdb-utils": "7.3.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"pouchdb-mapreduce-utils": {
|
||||||
|
"version": "7.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/pouchdb-mapreduce-utils/-/pouchdb-mapreduce-utils-7.3.0.tgz",
|
||||||
|
"integrity": "sha512-KDVSd+H2r+XWTrQfKWV71SknDDYRjYXoeWs0ZQl3xITHCcTl+fIgqyagg/XN+Zy/U9LeLPGMe2JdgPx9H8lJgw==",
|
||||||
|
"requires": {
|
||||||
|
"argsarray": "0.0.1",
|
||||||
|
"inherits": "2.0.4",
|
||||||
|
"pouchdb-collections": "7.3.0",
|
||||||
|
"pouchdb-utils": "7.3.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"pouchdb-md5": {
|
||||||
|
"version": "7.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/pouchdb-md5/-/pouchdb-md5-7.3.0.tgz",
|
||||||
|
"integrity": "sha512-wL04QgoKyd/L/TV5gxgcvlEyCJiZoXCOEFJklTzkdza/kBQNJGPH7i0ZhKa7Sb+AvZYoWZHddf1Zgv7rBScHkA==",
|
||||||
|
"requires": {
|
||||||
|
"pouchdb-binary-utils": "7.3.0",
|
||||||
|
"spark-md5": "3.0.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"pouchdb-merge": {
|
||||||
|
"version": "7.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/pouchdb-merge/-/pouchdb-merge-7.3.0.tgz",
|
||||||
|
"integrity": "sha512-E7LmchMzwYFm6V8OBxejzARLisanpksOju2LEfuiYnotGfNDeW7MByP0qBH0/zF8BfUyyjA1cl7ByaEpsapkeQ=="
|
||||||
|
},
|
||||||
|
"pouchdb-replication": {
|
||||||
|
"version": "7.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/pouchdb-replication/-/pouchdb-replication-7.3.0.tgz",
|
||||||
|
"integrity": "sha512-Z3kwrka9EXrE9kIm0Dw3h8wf8ErKzBJlhlXpDqDmETjC8V7TlEc2EbVXEH6veIt6XdsNQGHMfStVm2HERvTmNA==",
|
||||||
|
"requires": {
|
||||||
|
"inherits": "2.0.4",
|
||||||
|
"pouchdb-checkpointer": "7.3.0",
|
||||||
|
"pouchdb-errors": "7.3.0",
|
||||||
|
"pouchdb-generate-replication-id": "7.3.0",
|
||||||
|
"pouchdb-utils": "7.3.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"pouchdb-selector-core": {
|
||||||
|
"version": "7.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/pouchdb-selector-core/-/pouchdb-selector-core-7.3.0.tgz",
|
||||||
|
"integrity": "sha512-sK/cCrIGeL9ImcMhKGcwa54+bzX7Wv4hhVV+oUW3T1Nasaoxh+Muem1GuA+x1+SbTCE8y37rUg8i6DIOhX51ew==",
|
||||||
|
"requires": {
|
||||||
|
"pouchdb-collate": "7.3.0",
|
||||||
|
"pouchdb-utils": "7.3.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"pouchdb-utils": {
|
||||||
|
"version": "7.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/pouchdb-utils/-/pouchdb-utils-7.3.0.tgz",
|
||||||
|
"integrity": "sha512-HH+5IXXWn/ZgVCSnrlydBMYn6MabT7RS7SNoo9w8qVH9efpZSp3eLchw6yMQNLw8LQefWmbbskiHV9VgJmSVWQ==",
|
||||||
|
"requires": {
|
||||||
|
"argsarray": "0.0.1",
|
||||||
|
"clone-buffer": "1.0.0",
|
||||||
|
"immediate": "3.3.0",
|
||||||
|
"inherits": "2.0.4",
|
||||||
|
"pouchdb-collections": "7.3.0",
|
||||||
|
"pouchdb-errors": "7.3.0",
|
||||||
|
"pouchdb-md5": "7.3.0",
|
||||||
|
"uuid": "8.3.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
"prelude-ls": {
|
"prelude-ls": {
|
||||||
"version": "1.2.1",
|
"version": "1.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
|
||||||
@@ -5594,11 +6207,15 @@
|
|||||||
"integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==",
|
"integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"psl": {
|
||||||
|
"version": "1.8.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz",
|
||||||
|
"integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ=="
|
||||||
|
},
|
||||||
"punycode": {
|
"punycode": {
|
||||||
"version": "2.1.1",
|
"version": "2.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
|
||||||
"integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
|
"integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A=="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"queue-microtask": {
|
"queue-microtask": {
|
||||||
"version": "1.2.3",
|
"version": "1.2.3",
|
||||||
@@ -5760,6 +6377,11 @@
|
|||||||
"integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==",
|
"integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"spark-md5": {
|
||||||
|
"version": "3.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/spark-md5/-/spark-md5-3.0.2.tgz",
|
||||||
|
"integrity": "sha512-wcFzz9cDfbuqe0FZzfi2or1sgyIrsDwmPwfZC4hiNidPdPINjeUwNfv5kldczoEAcjl9Y1L3SM7Uz2PUEQzxQw=="
|
||||||
|
},
|
||||||
"sprintf-js": {
|
"sprintf-js": {
|
||||||
"version": "1.0.3",
|
"version": "1.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
|
||||||
@@ -5910,6 +6532,21 @@
|
|||||||
"is-number": "^7.0.0"
|
"is-number": "^7.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"tough-cookie": {
|
||||||
|
"version": "4.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.0.0.tgz",
|
||||||
|
"integrity": "sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg==",
|
||||||
|
"requires": {
|
||||||
|
"psl": "^1.1.33",
|
||||||
|
"punycode": "^2.1.1",
|
||||||
|
"universalify": "^0.1.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"tr46": {
|
||||||
|
"version": "0.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
|
||||||
|
"integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o="
|
||||||
|
},
|
||||||
"tsconfig-paths": {
|
"tsconfig-paths": {
|
||||||
"version": "3.12.0",
|
"version": "3.12.0",
|
||||||
"resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.12.0.tgz",
|
"resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.12.0.tgz",
|
||||||
@@ -5978,6 +6615,11 @@
|
|||||||
"which-boxed-primitive": "^1.0.2"
|
"which-boxed-primitive": "^1.0.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"universalify": {
|
||||||
|
"version": "0.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
|
||||||
|
"integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg=="
|
||||||
|
},
|
||||||
"uri-js": {
|
"uri-js": {
|
||||||
"version": "4.4.1",
|
"version": "4.4.1",
|
||||||
"resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
|
||||||
@@ -5987,18 +6629,42 @@
|
|||||||
"punycode": "^2.1.0"
|
"punycode": "^2.1.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"uuid": {
|
||||||
|
"version": "8.3.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
|
||||||
|
"integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg=="
|
||||||
|
},
|
||||||
"v8-compile-cache": {
|
"v8-compile-cache": {
|
||||||
"version": "2.3.0",
|
"version": "2.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz",
|
||||||
"integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==",
|
"integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"vuvuzela": {
|
||||||
|
"version": "1.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/vuvuzela/-/vuvuzela-1.0.3.tgz",
|
||||||
|
"integrity": "sha1-O+FF5YJxxzylUnndhR8SpoIRSws="
|
||||||
|
},
|
||||||
"w3c-keyname": {
|
"w3c-keyname": {
|
||||||
"version": "2.2.4",
|
"version": "2.2.4",
|
||||||
"resolved": "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.4.tgz",
|
"resolved": "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.4.tgz",
|
||||||
"integrity": "sha512-tOhfEwEzFLJzf6d1ZPkYfGj+FWhIpBux9ppoP3rlclw3Z0BZv3N7b7030Z1kYth+6rDuAsXUFr+d0VE6Ed1ikw==",
|
"integrity": "sha512-tOhfEwEzFLJzf6d1ZPkYfGj+FWhIpBux9ppoP3rlclw3Z0BZv3N7b7030Z1kYth+6rDuAsXUFr+d0VE6Ed1ikw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"webidl-conversions": {
|
||||||
|
"version": "3.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
|
||||||
|
"integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE="
|
||||||
|
},
|
||||||
|
"whatwg-url": {
|
||||||
|
"version": "5.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
|
||||||
|
"integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=",
|
||||||
|
"requires": {
|
||||||
|
"tr46": "~0.0.3",
|
||||||
|
"webidl-conversions": "^3.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"which": {
|
"which": {
|
||||||
"version": "2.0.2",
|
"version": "2.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
|
||||||
|
|||||||
10
package.json
10
package.json
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "obsidian-livesync",
|
"name": "obsidian-livesync",
|
||||||
"version": "0.8.3",
|
"version": "0.8.4",
|
||||||
"description": "Reflect your vault changes to some other devices immediately. Please make sure to disable other synchronize solutions to avoid content corruption or duplication.",
|
"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",
|
"main": "main.js",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
@@ -35,6 +35,14 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"diff-match-patch": "^1.0.5",
|
"diff-match-patch": "^1.0.5",
|
||||||
|
"esbuild": "0.13.12",
|
||||||
|
"esbuild-svelte": "^0.6.0",
|
||||||
|
"pouchdb-adapter-http": "^7.3.0",
|
||||||
|
"pouchdb-adapter-idb": "^7.3.0",
|
||||||
|
"pouchdb-core": "^7.3.0",
|
||||||
|
"pouchdb-mapreduce": "^7.3.0",
|
||||||
|
"pouchdb-replication": "^7.3.0",
|
||||||
|
"svelte-preprocess": "^4.10.2",
|
||||||
"xxhash-wasm": "^0.4.2"
|
"xxhash-wasm": "^0.4.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
1
pouchdb-browser-webpack/.gitignore
vendored
1
pouchdb-browser-webpack/.gitignore
vendored
@@ -1 +0,0 @@
|
|||||||
node_modules
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
# PouchDB-browser
|
|
||||||
just webpacked.
|
|
||||||
File diff suppressed because one or more lines are too long
9820
pouchdb-browser-webpack/package-lock.json
generated
9820
pouchdb-browser-webpack/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -1,23 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "pouchdb-browser-webpack",
|
|
||||||
"version": "1.0.0",
|
|
||||||
"description": "pouchdb-browser webpack",
|
|
||||||
"main": "index.js",
|
|
||||||
"scripts": {
|
|
||||||
"test": "echo \"Error: no test specified\" && exit 1",
|
|
||||||
"build": "webpack --mode=production --node-env=production",
|
|
||||||
"build:dev": "webpack --mode=development",
|
|
||||||
"build:prod": "webpack --mode=production --node-env=production",
|
|
||||||
"watch": "webpack --watch"
|
|
||||||
},
|
|
||||||
"keywords": [],
|
|
||||||
"author": "",
|
|
||||||
"license": "ISC",
|
|
||||||
"dependencies": {
|
|
||||||
"pouchdb-browser": "^7.2.2"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"webpack": "^5.58.1",
|
|
||||||
"webpack-cli": "^4.9.0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
// This module just webpacks pouchdb-browser
|
|
||||||
import * as PouchDB_src from "pouchdb-browser";
|
|
||||||
const PouchDB = PouchDB_src.default;
|
|
||||||
export { PouchDB };
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
// Generated using webpack-cli https://github.com/webpack/webpack-cli
|
|
||||||
|
|
||||||
const path = require("path");
|
|
||||||
|
|
||||||
const isProduction = process.env.NODE_ENV == "production";
|
|
||||||
|
|
||||||
const config = {
|
|
||||||
entry: "./src/index.js",
|
|
||||||
output: {
|
|
||||||
filename: "pouchdb-browser.js",
|
|
||||||
path: path.resolve(__dirname, "dist"),
|
|
||||||
library: {
|
|
||||||
type: "module",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
experiments: {
|
|
||||||
outputModule: true,
|
|
||||||
},
|
|
||||||
plugins: [],
|
|
||||||
module: {},
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports = () => {
|
|
||||||
if (isProduction) {
|
|
||||||
config.mode = "production";
|
|
||||||
} else {
|
|
||||||
config.mode = "development";
|
|
||||||
}
|
|
||||||
return config;
|
|
||||||
};
|
|
||||||
File diff suppressed because one or more lines are too long
@@ -1,7 +1,7 @@
|
|||||||
import { App, Modal } from "obsidian";
|
import { App, Modal } from "obsidian";
|
||||||
import { DIFF_DELETE, DIFF_EQUAL, DIFF_INSERT } from "diff-match-patch";
|
import { DIFF_DELETE, DIFF_EQUAL, DIFF_INSERT } from "diff-match-patch";
|
||||||
import { diff_result } from "./types";
|
import { diff_result } from "./lib/src/types";
|
||||||
import { escapeStringToHTML } from "./utils";
|
import { escapeStringToHTML } from "./lib/src/utils";
|
||||||
|
|
||||||
export class ConflictResolveModal extends Modal {
|
export class ConflictResolveModal extends Modal {
|
||||||
// result: Array<[number, string]>;
|
// result: Array<[number, string]>;
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
import { TFile, Modal, App } from "obsidian";
|
import { TFile, Modal, App } from "obsidian";
|
||||||
import { path2id, escapeStringToHTML } from "./utils";
|
import { path2id } from "./utils";
|
||||||
|
import { escapeStringToHTML } from "./lib/src/utils";
|
||||||
import ObsidianLiveSyncPlugin from "./main";
|
import ObsidianLiveSyncPlugin from "./main";
|
||||||
import { DIFF_DELETE, DIFF_EQUAL, DIFF_INSERT, diff_match_patch } from "diff-match-patch";
|
import { DIFF_DELETE, DIFF_EQUAL, DIFF_INSERT, diff_match_patch } from "diff-match-patch";
|
||||||
import { LOG_LEVEL } from "./types";
|
import { LOG_LEVEL } from "./lib/src/types";
|
||||||
import { Logger } from "./logger";
|
import { Logger } from "./lib/src/logger";
|
||||||
|
|
||||||
export class DocumentHistoryModal extends Modal {
|
export class DocumentHistoryModal extends Modal {
|
||||||
plugin: ObsidianLiveSyncPlugin;
|
plugin: ObsidianLiveSyncPlugin;
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import { Notice } from "obsidian";
|
import { PouchDB } from "./pouchdb-browser";
|
||||||
import { PouchDB } from "../pouchdb-browser-webpack/dist/pouchdb-browser.js";
|
|
||||||
import xxhash from "xxhash-wasm";
|
import xxhash from "xxhash-wasm";
|
||||||
import {
|
import {
|
||||||
Entry,
|
Entry,
|
||||||
@@ -10,7 +9,6 @@ import {
|
|||||||
NewEntry,
|
NewEntry,
|
||||||
PlainEntry,
|
PlainEntry,
|
||||||
LoadedEntry,
|
LoadedEntry,
|
||||||
ObsidianLiveSyncSettings,
|
|
||||||
Credential,
|
Credential,
|
||||||
EntryMilestoneInfo,
|
EntryMilestoneInfo,
|
||||||
LOG_LEVEL,
|
LOG_LEVEL,
|
||||||
@@ -22,16 +20,18 @@ import {
|
|||||||
VER,
|
VER,
|
||||||
MILSTONE_DOCID,
|
MILSTONE_DOCID,
|
||||||
DatabaseConnectingStatus,
|
DatabaseConnectingStatus,
|
||||||
} from "./types";
|
} from "./lib/src/types";
|
||||||
import { resolveWithIgnoreKnownError, delay, path2id, runWithLock, isPlainText } from "./utils";
|
import { decrypt, encrypt } from "./lib/src/e2ee";
|
||||||
import { Logger } from "./logger";
|
import { RemoteDBSettings } from "./lib/src/types";
|
||||||
|
import { resolveWithIgnoreKnownError, delay, runWithLock, isPlainText, splitPieces, NewNotice, WrappedNotice } from "./lib/src/utils";
|
||||||
|
import { path2id } from "./utils";
|
||||||
|
import { Logger } from "./lib/src/logger";
|
||||||
import { checkRemoteVersion, connectRemoteCouchDB, getLastPostFailedBySize } from "./utils_couchdb";
|
import { checkRemoteVersion, connectRemoteCouchDB, getLastPostFailedBySize } from "./utils_couchdb";
|
||||||
import { decrypt, encrypt } from "./e2ee";
|
|
||||||
|
|
||||||
export class LocalPouchDB {
|
export class LocalPouchDB {
|
||||||
auth: Credential;
|
auth: Credential;
|
||||||
dbname: string;
|
dbname: string;
|
||||||
settings: ObsidianLiveSyncSettings;
|
settings: RemoteDBSettings;
|
||||||
localDatabase: PouchDB.Database<EntryDoc>;
|
localDatabase: PouchDB.Database<EntryDoc>;
|
||||||
nodeid = "";
|
nodeid = "";
|
||||||
isReady = false;
|
isReady = false;
|
||||||
@@ -77,7 +77,7 @@ export class LocalPouchDB {
|
|||||||
this.localDatabase.removeAllListeners();
|
this.localDatabase.removeAllListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(settings: ObsidianLiveSyncSettings, dbname: string) {
|
constructor(settings: RemoteDBSettings, dbname: string) {
|
||||||
this.auth = {
|
this.auth = {
|
||||||
username: "",
|
username: "",
|
||||||
password: "",
|
password: "",
|
||||||
@@ -503,7 +503,7 @@ export class LocalPouchDB {
|
|||||||
}
|
}
|
||||||
async putDBEntry(note: LoadedEntry) {
|
async putDBEntry(note: LoadedEntry) {
|
||||||
await this.waitForGCComplete();
|
await this.waitForGCComplete();
|
||||||
let leftData = note.data;
|
// let leftData = note.data;
|
||||||
const savenNotes = [];
|
const savenNotes = [];
|
||||||
let processed = 0;
|
let processed = 0;
|
||||||
let made = 0;
|
let made = 0;
|
||||||
@@ -516,53 +516,22 @@ export class LocalPouchDB {
|
|||||||
pieceSize = MAX_DOC_SIZE;
|
pieceSize = MAX_DOC_SIZE;
|
||||||
plainSplit = true;
|
plainSplit = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
const newLeafs: EntryLeaf[] = [];
|
const newLeafs: EntryLeaf[] = [];
|
||||||
do {
|
// To keep low bandwith and database size,
|
||||||
// To keep low bandwith and database size,
|
// Dedup pieces on database.
|
||||||
// Dedup pieces on database.
|
// from 0.1.10, for best performance. we use markdown delimiters
|
||||||
// from 0.1.10, for best performance. we use markdown delimiters
|
// 1. \n[^\n]{longLineThreshold}[^\n]*\n -> long sentence shuld break.
|
||||||
// 1. \n[^\n]{longLineThreshold}[^\n]*\n -> long sentence shuld break.
|
// 2. \n\n shold break
|
||||||
// 2. \n\n shold break
|
// 3. \r\n\r\n should break
|
||||||
// 3. \r\n\r\n should break
|
// 4. \n# should break.
|
||||||
// 4. \n# should break.
|
let minimumChunkSize = this.settings.minimumChunkSize;
|
||||||
let cPieceSize = pieceSize;
|
if (minimumChunkSize < 10) minimumChunkSize = 10;
|
||||||
if (plainSplit) {
|
let longLineThreshold = this.settings.longLineThreshold;
|
||||||
let minimumChunkSize = this.settings.minimumChunkSize;
|
if (longLineThreshold < 100) longLineThreshold = 100;
|
||||||
if (minimumChunkSize < 10) minimumChunkSize = 10;
|
|
||||||
let longLineThreshold = this.settings.longLineThreshold;
|
|
||||||
if (longLineThreshold < 100) longLineThreshold = 100;
|
|
||||||
cPieceSize = 0;
|
|
||||||
// lookup for next splittion .
|
|
||||||
// we're standing on "\n"
|
|
||||||
do {
|
|
||||||
const n1 = leftData.indexOf("\n", cPieceSize + 1);
|
|
||||||
const n2 = leftData.indexOf("\n\n", cPieceSize + 1);
|
|
||||||
const n3 = leftData.indexOf("\r\n\r\n", cPieceSize + 1);
|
|
||||||
const n4 = leftData.indexOf("\n#", cPieceSize + 1);
|
|
||||||
if (n1 == -1 && n2 == -1 && n3 == -1 && n4 == -1) {
|
|
||||||
cPieceSize = MAX_DOC_SIZE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (n1 > longLineThreshold) {
|
const pieces = splitPieces(note.data, pieceSize, plainSplit, minimumChunkSize, longLineThreshold);
|
||||||
// long sentence is an established piece
|
for (const piece of pieces()) {
|
||||||
cPieceSize = n1;
|
|
||||||
} else {
|
|
||||||
// cPieceSize = Math.min.apply([n2, n3, n4].filter((e) => e > 1));
|
|
||||||
// ^ heavy.
|
|
||||||
if (n1 > 0 && cPieceSize < n1) cPieceSize = n1;
|
|
||||||
if (n2 > 0 && cPieceSize < n2) cPieceSize = n2 + 1;
|
|
||||||
if (n3 > 0 && cPieceSize < n3) cPieceSize = n3 + 3;
|
|
||||||
// Choose shorter, empty line and \n#
|
|
||||||
if (n4 > 0 && cPieceSize > n4) cPieceSize = n4 + 0;
|
|
||||||
cPieceSize++;
|
|
||||||
}
|
|
||||||
} while (cPieceSize < minimumChunkSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
// piece size determined.
|
|
||||||
const piece = leftData.substring(0, cPieceSize);
|
|
||||||
leftData = leftData.substring(cPieceSize);
|
|
||||||
processed++;
|
processed++;
|
||||||
let leafid = "";
|
let leafid = "";
|
||||||
// Get hash of piece.
|
// Get hash of piece.
|
||||||
@@ -646,7 +615,7 @@ export class LocalPouchDB {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
savenNotes.push(leafid);
|
savenNotes.push(leafid);
|
||||||
} while (leftData != "");
|
}
|
||||||
let saved = true;
|
let saved = true;
|
||||||
if (newLeafs.length > 0) {
|
if (newLeafs.length > 0) {
|
||||||
try {
|
try {
|
||||||
@@ -727,14 +696,14 @@ export class LocalPouchDB {
|
|||||||
// no op now,
|
// no op now,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
replicateAllToServer(setting: ObsidianLiveSyncSettings, showingNotice?: boolean) {
|
replicateAllToServer(setting: RemoteDBSettings, showingNotice?: boolean) {
|
||||||
return new Promise(async (res, rej) => {
|
return new Promise(async (res, rej) => {
|
||||||
await this.waitForGCComplete();
|
await this.waitForGCComplete();
|
||||||
this.closeReplication();
|
this.closeReplication();
|
||||||
Logger("send all data to server", LOG_LEVEL.NOTICE);
|
Logger("send all data to server", LOG_LEVEL.NOTICE);
|
||||||
let notice: Notice = null;
|
let notice: WrappedNotice = null;
|
||||||
if (showingNotice) {
|
if (showingNotice) {
|
||||||
notice = new Notice("Initializing", 0);
|
notice = NewNotice("Initializing", 0);
|
||||||
}
|
}
|
||||||
this.syncStatus = "STARTED";
|
this.syncStatus = "STARTED";
|
||||||
this.updateInfo();
|
this.updateInfo();
|
||||||
@@ -800,7 +769,7 @@ export class LocalPouchDB {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async checkReplicationConnectivity(setting: ObsidianLiveSyncSettings, keepAlive: boolean, skipCheck: boolean) {
|
async checkReplicationConnectivity(setting: RemoteDBSettings, keepAlive: boolean, skipCheck: boolean) {
|
||||||
if (!this.isReady) {
|
if (!this.isReady) {
|
||||||
Logger("Database is not ready.");
|
Logger("Database is not ready.");
|
||||||
return false;
|
return false;
|
||||||
@@ -808,7 +777,7 @@ export class LocalPouchDB {
|
|||||||
|
|
||||||
await this.waitForGCComplete();
|
await this.waitForGCComplete();
|
||||||
if (setting.versionUpFlash != "") {
|
if (setting.versionUpFlash != "") {
|
||||||
new Notice("Open settings and check message, please.");
|
NewNotice("Open settings and check message, please.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const uri = setting.couchDB_URI + (setting.couchDB_DBNAME == "" ? "" : "/" + setting.couchDB_DBNAME);
|
const uri = setting.couchDB_URI + (setting.couchDB_DBNAME == "" ? "" : "/" + setting.couchDB_DBNAME);
|
||||||
@@ -839,15 +808,6 @@ export class LocalPouchDB {
|
|||||||
locked: false,
|
locked: false,
|
||||||
accepted_nodes: [this.nodeid],
|
accepted_nodes: [this.nodeid],
|
||||||
};
|
};
|
||||||
// const remoteInfo = dbret.info;
|
|
||||||
// const localInfo = await this.localDatabase.info();
|
|
||||||
// const remoteDocsCount = remoteInfo.doc_count;
|
|
||||||
// const localDocsCount = localInfo.doc_count;
|
|
||||||
// const remoteUpdSeq = typeof remoteInfo.update_seq == "string" ? Number(remoteInfo.update_seq.split("-")[0]) : remoteInfo.update_seq;
|
|
||||||
// const localUpdSeq = typeof localInfo.update_seq == "string" ? Number(localInfo.update_seq.split("-")[0]) : localInfo.update_seq;
|
|
||||||
|
|
||||||
// Logger(`Database diffences: remote:${remoteDocsCount} docs / last update ${remoteUpdSeq}`);
|
|
||||||
// Logger(`Database diffences: local :${localDocsCount} docs / last update ${localUpdSeq}`);
|
|
||||||
|
|
||||||
const remoteMilestone: EntryMilestoneInfo = await resolveWithIgnoreKnownError(dbret.db.get(MILSTONE_DOCID), defMilestonePoint);
|
const remoteMilestone: EntryMilestoneInfo = await resolveWithIgnoreKnownError(dbret.db.get(MILSTONE_DOCID), defMilestonePoint);
|
||||||
this.remoteLocked = remoteMilestone.locked;
|
this.remoteLocked = remoteMilestone.locked;
|
||||||
@@ -870,20 +830,20 @@ export class LocalPouchDB {
|
|||||||
return { db: dbret.db, info: dbret.info, syncOptionBase, syncOption };
|
return { db: dbret.db, info: dbret.info, syncOptionBase, syncOption };
|
||||||
}
|
}
|
||||||
|
|
||||||
async openReplication(setting: ObsidianLiveSyncSettings, keepAlive: boolean, showResult: boolean, callback: (e: PouchDB.Core.ExistingDocument<EntryDoc>[]) => Promise<void>): Promise<boolean> {
|
async openReplication(setting: RemoteDBSettings, keepAlive: boolean, showResult: boolean, callback: (e: PouchDB.Core.ExistingDocument<EntryDoc>[]) => Promise<void>): Promise<boolean> {
|
||||||
return await runWithLock("replicate", false, () => {
|
return await runWithLock("replicate", false, () => {
|
||||||
return this._openReplication(setting, keepAlive, showResult, callback, false);
|
return this._openReplication(setting, keepAlive, showResult, callback, false);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
originalSetting: ObsidianLiveSyncSettings = null;
|
originalSetting: RemoteDBSettings = null;
|
||||||
// last_seq: number = 200;
|
// last_seq: number = 200;
|
||||||
async _openReplication(setting: ObsidianLiveSyncSettings, keepAlive: boolean, showResult: boolean, callback: (e: PouchDB.Core.ExistingDocument<EntryDoc>[]) => Promise<void>, retrying: boolean): Promise<boolean> {
|
async _openReplication(setting: RemoteDBSettings, keepAlive: boolean, showResult: boolean, callback: (e: PouchDB.Core.ExistingDocument<EntryDoc>[]) => Promise<void>, retrying: boolean): Promise<boolean> {
|
||||||
const ret = await this.checkReplicationConnectivity(setting, keepAlive, retrying);
|
const ret = await this.checkReplicationConnectivity(setting, keepAlive, retrying);
|
||||||
if (ret === false) return false;
|
if (ret === false) return false;
|
||||||
let notice: Notice = null;
|
let notice: WrappedNotice = null;
|
||||||
if (showResult) {
|
if (showResult) {
|
||||||
notice = new Notice("Looking for the point last synchronized point.", 0);
|
notice = NewNotice("Looking for the point last synchronized point.", 0);
|
||||||
}
|
}
|
||||||
const { db, syncOptionBase, syncOption } = ret;
|
const { db, syncOptionBase, syncOption } = ret;
|
||||||
//replicate once
|
//replicate once
|
||||||
@@ -919,12 +879,10 @@ export class LocalPouchDB {
|
|||||||
.on("change", async (e) => {
|
.on("change", async (e) => {
|
||||||
try {
|
try {
|
||||||
if (e.direction == "pull") {
|
if (e.direction == "pull") {
|
||||||
// console.log(`pulled data:${e.change.docs.map((e) => e._id).join(",")}`);
|
|
||||||
await callback(e.change.docs);
|
await callback(e.change.docs);
|
||||||
Logger(`replicated ${e.change.docs_read} doc(s)`);
|
Logger(`replicated ${e.change.docs_read} doc(s)`);
|
||||||
this.docArrived += e.change.docs.length;
|
this.docArrived += e.change.docs.length;
|
||||||
} else {
|
} else {
|
||||||
// console.log(`put data:${e.change.docs.map((e) => e._id).join(",")}`);
|
|
||||||
this.docSent += e.change.docs.length;
|
this.docSent += e.change.docs.length;
|
||||||
}
|
}
|
||||||
if (notice != null) {
|
if (notice != null) {
|
||||||
@@ -974,7 +932,7 @@ export class LocalPouchDB {
|
|||||||
Logger("Replication stopped.", LOG_LEVEL.NOTICE);
|
Logger("Replication stopped.", LOG_LEVEL.NOTICE);
|
||||||
} else {
|
} else {
|
||||||
// Duplicate settings for smaller batch.
|
// Duplicate settings for smaller batch.
|
||||||
const xsetting: ObsidianLiveSyncSettings = JSON.parse(JSON.stringify(setting));
|
const xsetting: RemoteDBSettings = JSON.parse(JSON.stringify(setting));
|
||||||
xsetting.batch_size = Math.ceil(xsetting.batch_size / 2);
|
xsetting.batch_size = Math.ceil(xsetting.batch_size / 2);
|
||||||
xsetting.batches_limit = Math.ceil(xsetting.batches_limit / 2);
|
xsetting.batches_limit = Math.ceil(xsetting.batches_limit / 2);
|
||||||
if (xsetting.batch_size <= 3 || xsetting.batches_limit <= 3) {
|
if (xsetting.batch_size <= 3 || xsetting.batches_limit <= 3) {
|
||||||
@@ -1074,7 +1032,7 @@ export class LocalPouchDB {
|
|||||||
this.disposeHashCache();
|
this.disposeHashCache();
|
||||||
Logger("Local Database Reset", LOG_LEVEL.NOTICE);
|
Logger("Local Database Reset", LOG_LEVEL.NOTICE);
|
||||||
}
|
}
|
||||||
async tryResetRemoteDatabase(setting: ObsidianLiveSyncSettings) {
|
async tryResetRemoteDatabase(setting: RemoteDBSettings) {
|
||||||
await this.closeReplication();
|
await this.closeReplication();
|
||||||
const uri = setting.couchDB_URI + (setting.couchDB_DBNAME == "" ? "" : "/" + setting.couchDB_DBNAME);
|
const uri = setting.couchDB_URI + (setting.couchDB_DBNAME == "" ? "" : "/" + setting.couchDB_DBNAME);
|
||||||
const auth: Credential = {
|
const auth: Credential = {
|
||||||
@@ -1092,7 +1050,7 @@ export class LocalPouchDB {
|
|||||||
Logger(ex, LOG_LEVEL.NOTICE);
|
Logger(ex, LOG_LEVEL.NOTICE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
async tryCreateRemoteDatabase(setting: ObsidianLiveSyncSettings) {
|
async tryCreateRemoteDatabase(setting: RemoteDBSettings) {
|
||||||
await this.closeReplication();
|
await this.closeReplication();
|
||||||
const uri = setting.couchDB_URI + (setting.couchDB_DBNAME == "" ? "" : "/" + setting.couchDB_DBNAME);
|
const uri = setting.couchDB_URI + (setting.couchDB_DBNAME == "" ? "" : "/" + setting.couchDB_DBNAME);
|
||||||
const auth: Credential = {
|
const auth: Credential = {
|
||||||
@@ -1103,7 +1061,7 @@ export class LocalPouchDB {
|
|||||||
if (typeof con2 === "string") return;
|
if (typeof con2 === "string") return;
|
||||||
Logger("Remote Database Created or Connected", LOG_LEVEL.NOTICE);
|
Logger("Remote Database Created or Connected", LOG_LEVEL.NOTICE);
|
||||||
}
|
}
|
||||||
async markRemoteLocked(setting: ObsidianLiveSyncSettings, locked: boolean) {
|
async markRemoteLocked(setting: RemoteDBSettings, locked: boolean) {
|
||||||
const uri = setting.couchDB_URI + (setting.couchDB_DBNAME == "" ? "" : "/" + setting.couchDB_DBNAME);
|
const uri = setting.couchDB_URI + (setting.couchDB_DBNAME == "" ? "" : "/" + setting.couchDB_DBNAME);
|
||||||
const auth: Credential = {
|
const auth: Credential = {
|
||||||
username: setting.couchDB_USER,
|
username: setting.couchDB_USER,
|
||||||
@@ -1137,7 +1095,7 @@ export class LocalPouchDB {
|
|||||||
}
|
}
|
||||||
await dbret.db.put(remoteMilestone);
|
await dbret.db.put(remoteMilestone);
|
||||||
}
|
}
|
||||||
async markRemoteResolved(setting: ObsidianLiveSyncSettings) {
|
async markRemoteResolved(setting: RemoteDBSettings) {
|
||||||
const uri = setting.couchDB_URI + (setting.couchDB_DBNAME == "" ? "" : "/" + setting.couchDB_DBNAME);
|
const uri = setting.couchDB_URI + (setting.couchDB_DBNAME == "" ? "" : "/" + setting.couchDB_DBNAME);
|
||||||
const auth: Credential = {
|
const auth: Credential = {
|
||||||
username: setting.couchDB_USER,
|
username: setting.couchDB_USER,
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { App, Modal } from "obsidian";
|
import { App, Modal } from "obsidian";
|
||||||
import { escapeStringToHTML } from "./utils";
|
import { escapeStringToHTML } from "./lib/src/utils";
|
||||||
import ObsidianLiveSyncPlugin from "./main";
|
import ObsidianLiveSyncPlugin from "./main";
|
||||||
|
|
||||||
export class LogDisplayModal extends Modal {
|
export class LogDisplayModal extends Modal {
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
import { App, Notice, PluginSettingTab, Setting, sanitizeHTMLToDom } from "obsidian";
|
import { App, PluginSettingTab, Setting, sanitizeHTMLToDom } from "obsidian";
|
||||||
import { EntryDoc, LOG_LEVEL } from "./types";
|
import { EntryDoc, LOG_LEVEL } from "./lib/src/types";
|
||||||
import { path2id, id2path, runWithLock } from "./utils";
|
import { path2id, id2path } from "./utils";
|
||||||
import { Logger } from "./logger";
|
import { NewNotice, runWithLock } from "./lib/src/utils";
|
||||||
|
import { Logger } from "./lib/src/logger";
|
||||||
import { connectRemoteCouchDB } from "./utils_couchdb";
|
import { connectRemoteCouchDB } from "./utils_couchdb";
|
||||||
import { testCrypt } from "./e2ee";
|
import { testCrypt } from "./lib/src/e2ee";
|
||||||
import ObsidianLiveSyncPlugin from "./main";
|
import ObsidianLiveSyncPlugin from "./main";
|
||||||
|
|
||||||
export class ObsidianLiveSyncSettingTab extends PluginSettingTab {
|
export class ObsidianLiveSyncSettingTab extends PluginSettingTab {
|
||||||
@@ -688,7 +689,7 @@ export class ObsidianLiveSyncSettingTab extends PluginSettingTab {
|
|||||||
.onClick(async () => {
|
.onClick(async () => {
|
||||||
const files = this.app.vault.getFiles();
|
const files = this.app.vault.getFiles();
|
||||||
Logger("Verify and repair all files started", LOG_LEVEL.NOTICE);
|
Logger("Verify and repair all files started", LOG_LEVEL.NOTICE);
|
||||||
const notice = new Notice("", 0);
|
const notice = NewNotice("", 0);
|
||||||
let i = 0;
|
let i = 0;
|
||||||
for (const file of files) {
|
for (const file of files) {
|
||||||
i++;
|
i++;
|
||||||
@@ -714,7 +715,7 @@ export class ObsidianLiveSyncSettingTab extends PluginSettingTab {
|
|||||||
.setDisabled(false)
|
.setDisabled(false)
|
||||||
.setWarning()
|
.setWarning()
|
||||||
.onClick(async () => {
|
.onClick(async () => {
|
||||||
const notice = new Notice("", 0);
|
const notice = NewNotice("", 0);
|
||||||
Logger(`Begin sanity check`, LOG_LEVEL.INFO);
|
Logger(`Begin sanity check`, LOG_LEVEL.INFO);
|
||||||
notice.setMessage(`Begin sanity check`);
|
notice.setMessage(`Begin sanity check`);
|
||||||
await runWithLock("sancheck", true, async () => {
|
await runWithLock("sancheck", true, async () => {
|
||||||
@@ -834,7 +835,7 @@ export class ObsidianLiveSyncSettingTab extends PluginSettingTab {
|
|||||||
|
|
||||||
const updateDisabledOfDeviceAndVaultName = () => {
|
const updateDisabledOfDeviceAndVaultName = () => {
|
||||||
vaultName.setDisabled(this.plugin.settings.autoSweepPlugins || this.plugin.settings.autoSweepPluginsPeriodic);
|
vaultName.setDisabled(this.plugin.settings.autoSweepPlugins || this.plugin.settings.autoSweepPluginsPeriodic);
|
||||||
vaultName.setTooltip(this.plugin.settings.autoSweepPlugins || this.plugin.settings.autoSweepPluginsPeriodic ? "You could not change when you enabling auto sweep." : "");
|
vaultName.setTooltip(this.plugin.settings.autoSweepPlugins || this.plugin.settings.autoSweepPluginsPeriodic ? "You could not change when you enabling auto scan." : "");
|
||||||
};
|
};
|
||||||
new Setting(containerPluginSettings).setName("Enable plugin synchronization").addToggle((toggle) =>
|
new Setting(containerPluginSettings).setName("Enable plugin synchronization").addToggle((toggle) =>
|
||||||
toggle.setValue(this.plugin.settings.usePluginSync).onChange(async (value) => {
|
toggle.setValue(this.plugin.settings.usePluginSync).onChange(async (value) => {
|
||||||
@@ -844,8 +845,8 @@ export class ObsidianLiveSyncSettingTab extends PluginSettingTab {
|
|||||||
);
|
);
|
||||||
|
|
||||||
new Setting(containerPluginSettings)
|
new Setting(containerPluginSettings)
|
||||||
.setName("Sweep plugins automatically")
|
.setName("Scan plugins automatically")
|
||||||
.setDesc("Sweep plugins before replicating.")
|
.setDesc("Scan plugins before replicating.")
|
||||||
.addToggle((toggle) =>
|
.addToggle((toggle) =>
|
||||||
toggle.setValue(this.plugin.settings.autoSweepPlugins).onChange(async (value) => {
|
toggle.setValue(this.plugin.settings.autoSweepPlugins).onChange(async (value) => {
|
||||||
this.plugin.settings.autoSweepPlugins = value;
|
this.plugin.settings.autoSweepPlugins = value;
|
||||||
@@ -855,8 +856,8 @@ export class ObsidianLiveSyncSettingTab extends PluginSettingTab {
|
|||||||
);
|
);
|
||||||
|
|
||||||
new Setting(containerPluginSettings)
|
new Setting(containerPluginSettings)
|
||||||
.setName("Sweep plugins periodically")
|
.setName("Scan plugins periodically")
|
||||||
.setDesc("Sweep plugins each 1 minutes.")
|
.setDesc("Scan plugins each 1 minutes.")
|
||||||
.addToggle((toggle) =>
|
.addToggle((toggle) =>
|
||||||
toggle.setValue(this.plugin.settings.autoSweepPluginsPeriodic).onChange(async (value) => {
|
toggle.setValue(this.plugin.settings.autoSweepPluginsPeriodic).onChange(async (value) => {
|
||||||
this.plugin.settings.autoSweepPluginsPeriodic = value;
|
this.plugin.settings.autoSweepPluginsPeriodic = value;
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
import ObsidianLiveSyncPlugin from "./main";
|
import ObsidianLiveSyncPlugin from "./main";
|
||||||
import { onMount } from "svelte";
|
import { onMount } from "svelte";
|
||||||
import { DevicePluginList, PluginDataEntry } from "./types";
|
import { DevicePluginList, PluginDataEntry } from "./types";
|
||||||
import { versionNumberString2Number } from "./utils";
|
import { versionNumberString2Number } from "./lib/src/utils";
|
||||||
|
|
||||||
type JudgeResult = "" | "NEWER" | "EVEN" | "EVEN_BUT_DIFFERENT" | "OLDER" | "REMOTE_ONLY";
|
type JudgeResult = "" | "NEWER" | "EVEN" | "EVEN_BUT_DIFFERENT" | "OLDER" | "REMOTE_ONLY";
|
||||||
|
|
||||||
@@ -266,7 +266,7 @@
|
|||||||
|
|
||||||
<div class="ols-plugins-div-buttons">
|
<div class="ols-plugins-div-buttons">
|
||||||
<button class="mod-cta" on:click={checkUpdates}>Check Updates</button>
|
<button class="mod-cta" on:click={checkUpdates}>Check Updates</button>
|
||||||
<button class="mod-cta" on:click={sweepPlugins}>Sweep installed</button>
|
<button class="mod-cta" on:click={sweepPlugins}>Scan installed</button>
|
||||||
<button class="mod-cta" on:click={applyPlugins}>Apply all</button>
|
<button class="mod-cta" on:click={applyPlugins}>Apply all</button>
|
||||||
</div>
|
</div>
|
||||||
<!-- <div class="ols-plugins-div-buttons">-->
|
<!-- <div class="ols-plugins-div-buttons">-->
|
||||||
|
|||||||
168
src/e2ee.ts
168
src/e2ee.ts
@@ -1,168 +0,0 @@
|
|||||||
import { Logger } from "./logger";
|
|
||||||
import { LOG_LEVEL } from "./types";
|
|
||||||
|
|
||||||
export type encodedData = [encryptedData: string, iv: string, salt: string];
|
|
||||||
export type KeyBuffer = {
|
|
||||||
index: string;
|
|
||||||
key: CryptoKey;
|
|
||||||
salt: Uint8Array;
|
|
||||||
};
|
|
||||||
|
|
||||||
const KeyBuffs: KeyBuffer[] = [];
|
|
||||||
const decKeyBuffs: KeyBuffer[] = [];
|
|
||||||
|
|
||||||
const KEY_RECYCLE_COUNT = 100;
|
|
||||||
let recycleCount = KEY_RECYCLE_COUNT;
|
|
||||||
|
|
||||||
let semiStaticFieldBuffer: Uint8Array = null;
|
|
||||||
const nonceBuffer: Uint32Array = new Uint32Array(1);
|
|
||||||
|
|
||||||
export async function getKeyForEncrypt(passphrase: string): Promise<[CryptoKey, Uint8Array]> {
|
|
||||||
// For performance, the plugin reuses the key KEY_RECYCLE_COUNT times.
|
|
||||||
const f = KeyBuffs.find((e) => e.index == passphrase);
|
|
||||||
if (f) {
|
|
||||||
recycleCount--;
|
|
||||||
if (recycleCount > 0) {
|
|
||||||
return [f.key, f.salt];
|
|
||||||
}
|
|
||||||
KeyBuffs.remove(f);
|
|
||||||
recycleCount = KEY_RECYCLE_COUNT;
|
|
||||||
}
|
|
||||||
const xpassphrase = new TextEncoder().encode(passphrase);
|
|
||||||
const digest = await crypto.subtle.digest({ name: "SHA-256" }, xpassphrase);
|
|
||||||
const keyMaterial = await crypto.subtle.importKey("raw", digest, { name: "PBKDF2" }, false, ["deriveKey"]);
|
|
||||||
const salt = crypto.getRandomValues(new Uint8Array(16));
|
|
||||||
const key = await crypto.subtle.deriveKey(
|
|
||||||
{
|
|
||||||
name: "PBKDF2",
|
|
||||||
salt,
|
|
||||||
iterations: 100000,
|
|
||||||
hash: "SHA-256",
|
|
||||||
},
|
|
||||||
keyMaterial,
|
|
||||||
{ name: "AES-GCM", length: 256 },
|
|
||||||
false,
|
|
||||||
["encrypt"]
|
|
||||||
);
|
|
||||||
KeyBuffs.push({
|
|
||||||
index: passphrase,
|
|
||||||
key,
|
|
||||||
salt,
|
|
||||||
});
|
|
||||||
while (KeyBuffs.length > 50) {
|
|
||||||
KeyBuffs.shift();
|
|
||||||
}
|
|
||||||
return [key, salt];
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function getKeyForDecryption(passphrase: string, salt: Uint8Array): Promise<[CryptoKey, Uint8Array]> {
|
|
||||||
const bufKey = passphrase + uint8ArrayToHexString(salt);
|
|
||||||
const f = decKeyBuffs.find((e) => e.index == bufKey);
|
|
||||||
if (f) {
|
|
||||||
return [f.key, f.salt];
|
|
||||||
}
|
|
||||||
const xpassphrase = new TextEncoder().encode(passphrase);
|
|
||||||
const digest = await crypto.subtle.digest({ name: "SHA-256" }, xpassphrase);
|
|
||||||
const keyMaterial = await crypto.subtle.importKey("raw", digest, { name: "PBKDF2" }, false, ["deriveKey"]);
|
|
||||||
const key = await crypto.subtle.deriveKey(
|
|
||||||
{
|
|
||||||
name: "PBKDF2",
|
|
||||||
salt,
|
|
||||||
iterations: 100000,
|
|
||||||
hash: "SHA-256",
|
|
||||||
},
|
|
||||||
keyMaterial,
|
|
||||||
{ name: "AES-GCM", length: 256 },
|
|
||||||
false,
|
|
||||||
["decrypt"]
|
|
||||||
);
|
|
||||||
decKeyBuffs.push({
|
|
||||||
index: bufKey,
|
|
||||||
key,
|
|
||||||
salt,
|
|
||||||
});
|
|
||||||
while (decKeyBuffs.length > 50) {
|
|
||||||
decKeyBuffs.shift();
|
|
||||||
}
|
|
||||||
return [key, salt];
|
|
||||||
}
|
|
||||||
|
|
||||||
function getSemiStaticField(reset?: boolean) {
|
|
||||||
// return fixed field of iv.
|
|
||||||
if (semiStaticFieldBuffer != null && !reset) {
|
|
||||||
return semiStaticFieldBuffer;
|
|
||||||
}
|
|
||||||
semiStaticFieldBuffer = crypto.getRandomValues(new Uint8Array(12));
|
|
||||||
return semiStaticFieldBuffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
function getNonce() {
|
|
||||||
// This is nonce, so do not send same thing.
|
|
||||||
nonceBuffer[0]++;
|
|
||||||
if (nonceBuffer[0] > 10000) {
|
|
||||||
// reset semi-static field.
|
|
||||||
getSemiStaticField(true);
|
|
||||||
}
|
|
||||||
return nonceBuffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
function uint8ArrayToHexString(src: Uint8Array): string {
|
|
||||||
return Array.from(src)
|
|
||||||
.map((e: number): string => `00${e.toString(16)}`.slice(-2))
|
|
||||||
.join("");
|
|
||||||
}
|
|
||||||
function hexStringToUint8Array(src: string): Uint8Array {
|
|
||||||
const srcArr = [...src];
|
|
||||||
const arr = srcArr.reduce((acc, _, i) => (i % 2 ? acc : [...acc, srcArr.slice(i, i + 2).join("")]), []).map((e) => parseInt(e, 16));
|
|
||||||
return Uint8Array.from(arr);
|
|
||||||
}
|
|
||||||
export async function encrypt(input: string, passphrase: string) {
|
|
||||||
const [key, salt] = await getKeyForEncrypt(passphrase);
|
|
||||||
// Create initial vector with semifixed part and incremental part
|
|
||||||
// I think it's not good against related-key attacks.
|
|
||||||
const fixedPart = getSemiStaticField();
|
|
||||||
const invocationPart = getNonce();
|
|
||||||
const iv = Uint8Array.from([...fixedPart, ...new Uint8Array(invocationPart.buffer)]);
|
|
||||||
const plainStringified: string = JSON.stringify(input);
|
|
||||||
const plainStringBuffer: Uint8Array = new TextEncoder().encode(plainStringified);
|
|
||||||
const encryptedDataArrayBuffer = await crypto.subtle.encrypt({ name: "AES-GCM", iv }, key, plainStringBuffer);
|
|
||||||
|
|
||||||
const encryptedData = window.btoa(Array.from(new Uint8Array(encryptedDataArrayBuffer), (char) => String.fromCharCode(char)).join(""));
|
|
||||||
|
|
||||||
//return data with iv and salt.
|
|
||||||
const response: encodedData = [encryptedData, uint8ArrayToHexString(iv), uint8ArrayToHexString(salt)];
|
|
||||||
const ret = JSON.stringify(response);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function decrypt(encryptedResult: string, passphrase: string): Promise<string> {
|
|
||||||
try {
|
|
||||||
const [encryptedData, ivString, salt]: encodedData = JSON.parse(encryptedResult);
|
|
||||||
const [key] = await getKeyForDecryption(passphrase, hexStringToUint8Array(salt));
|
|
||||||
const iv = hexStringToUint8Array(ivString);
|
|
||||||
// decode base 64, it should increase speed and i should with in MAX_DOC_SIZE_BIN, so it won't OOM.
|
|
||||||
const encryptedDataBin = window.atob(encryptedData);
|
|
||||||
const encryptedDataArrayBuffer = Uint8Array.from(encryptedDataBin.split(""), (char) => char.charCodeAt(0));
|
|
||||||
const plainStringBuffer: ArrayBuffer = await crypto.subtle.decrypt({ name: "AES-GCM", iv }, key, encryptedDataArrayBuffer);
|
|
||||||
const plainStringified = new TextDecoder().decode(plainStringBuffer);
|
|
||||||
const plain = JSON.parse(plainStringified);
|
|
||||||
return plain;
|
|
||||||
} catch (ex) {
|
|
||||||
Logger("Couldn't decode! You should wrong the passphrases", LOG_LEVEL.VERBOSE);
|
|
||||||
Logger(ex, LOG_LEVEL.VERBOSE);
|
|
||||||
throw ex;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function testCrypt() {
|
|
||||||
const src = "supercalifragilisticexpialidocious";
|
|
||||||
const encoded = await encrypt(src, "passwordTest");
|
|
||||||
const decrypted = await decrypt(encoded, "passwordTest");
|
|
||||||
if (src != decrypted) {
|
|
||||||
Logger("WARNING! Your device would not support encryption.", LOG_LEVEL.VERBOSE);
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
Logger("CRYPT LOGIC OK", LOG_LEVEL.VERBOSE);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
import { LOG_LEVEL } from "./types";
|
|
||||||
|
|
||||||
// eslint-disable-next-line require-await
|
|
||||||
export let Logger: (message: any, levlel?: LOG_LEVEL) => Promise<void> = async (message, _) => {
|
|
||||||
const timestamp = new Date().toLocaleString();
|
|
||||||
const messagecontent = typeof message == "string" ? message : message instanceof Error ? `${message.name}:${message.message}` : JSON.stringify(message, null, 2);
|
|
||||||
const newmessage = timestamp + "->" + messagecontent;
|
|
||||||
console.log(newmessage);
|
|
||||||
};
|
|
||||||
|
|
||||||
export function setLogger(loggerFun: (message: any, levlel?: LOG_LEVEL) => Promise<void>) {
|
|
||||||
Logger = loggerFun;
|
|
||||||
}
|
|
||||||
83
src/main.ts
83
src/main.ts
@@ -1,25 +1,24 @@
|
|||||||
import { debounce, Notice, Plugin, TFile, addIcon, TFolder, normalizePath, TAbstractFile, Editor, MarkdownView, PluginManifest, Modal, App } from "obsidian";
|
import { debounce, Notice, Plugin, TFile, addIcon, TFolder, normalizePath, TAbstractFile, Editor, MarkdownView, PluginManifest, Modal, App } from "obsidian";
|
||||||
import { diff_match_patch } from "diff-match-patch";
|
import { diff_match_patch } from "diff-match-patch";
|
||||||
|
|
||||||
|
import { EntryDoc, LoadedEntry, ObsidianLiveSyncSettings, diff_check_result, diff_result_leaf, EntryBody, LOG_LEVEL, VER, DEFAULT_SETTINGS, diff_result, FLAGMD_REDFLAG } from "./lib/src/types";
|
||||||
|
import { PluginDataEntry, PERIODIC_PLUGIN_SWEEP, PluginList, DevicePluginList } from "./types";
|
||||||
import {
|
import {
|
||||||
EntryDoc,
|
base64ToString,
|
||||||
LoadedEntry,
|
arrayBufferToBase64,
|
||||||
ObsidianLiveSyncSettings,
|
base64ToArrayBuffer,
|
||||||
diff_check_result,
|
isValidPath,
|
||||||
diff_result_leaf,
|
versionNumberString2Number,
|
||||||
EntryBody,
|
runWithLock,
|
||||||
PluginDataEntry,
|
shouldBeIgnored,
|
||||||
LOG_LEVEL,
|
getProcessingCounts,
|
||||||
VER,
|
setLockNotifier,
|
||||||
PERIODIC_PLUGIN_SWEEP,
|
isPlainText,
|
||||||
DEFAULT_SETTINGS,
|
setNoticeClass,
|
||||||
PluginList,
|
NewNotice,
|
||||||
DevicePluginList,
|
allSettledWithConcurrencyLimit,
|
||||||
diff_result,
|
} from "./lib/src/utils";
|
||||||
FLAGMD_REDFLAG,
|
import { Logger, setLogger } from "./lib/src/logger";
|
||||||
} from "./types";
|
|
||||||
import { base64ToString, arrayBufferToBase64, base64ToArrayBuffer, isValidPath, versionNumberString2Number, id2path, path2id, runWithLock, shouldBeIgnored, getProcessingCounts, setLockNotifier, isPlainText } from "./utils";
|
|
||||||
import { Logger, setLogger } from "./logger";
|
|
||||||
import { LocalPouchDB } from "./LocalPouchDB";
|
import { LocalPouchDB } from "./LocalPouchDB";
|
||||||
import { LogDisplayModal } from "./LogDisplayModal";
|
import { LogDisplayModal } from "./LogDisplayModal";
|
||||||
import { ConflictResolveModal } from "./ConflictResolveModal";
|
import { ConflictResolveModal } from "./ConflictResolveModal";
|
||||||
@@ -27,7 +26,8 @@ import { ObsidianLiveSyncSettingTab } from "./ObsidianLiveSyncSettingTab";
|
|||||||
import { DocumentHistoryModal } from "./DocumentHistoryModal";
|
import { DocumentHistoryModal } from "./DocumentHistoryModal";
|
||||||
|
|
||||||
import PluginPane from "./PluginPane.svelte";
|
import PluginPane from "./PluginPane.svelte";
|
||||||
|
import { id2path, path2id } from "./utils";
|
||||||
|
setNoticeClass(Notice);
|
||||||
class PluginDialogModal extends Modal {
|
class PluginDialogModal extends Modal {
|
||||||
plugin: ObsidianLiveSyncPlugin;
|
plugin: ObsidianLiveSyncPlugin;
|
||||||
logEl: HTMLDivElement;
|
logEl: HTMLDivElement;
|
||||||
@@ -702,7 +702,7 @@ export default class ObsidianLiveSyncPlugin extends Plugin {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async doc2storate_modify(docEntry: EntryBody, file: TFile, force?: boolean) {
|
async doc2storage_modify(docEntry: EntryBody, file: TFile, force?: boolean) {
|
||||||
const pathSrc = id2path(docEntry._id);
|
const pathSrc = id2path(docEntry._id);
|
||||||
if (shouldBeIgnored(pathSrc)) {
|
if (shouldBeIgnored(pathSrc)) {
|
||||||
return;
|
return;
|
||||||
@@ -781,7 +781,7 @@ export default class ObsidianLiveSyncPlugin extends Plugin {
|
|||||||
} else if (targetFile instanceof TFile) {
|
} else if (targetFile instanceof TFile) {
|
||||||
const doc = change;
|
const doc = change;
|
||||||
const file = targetFile;
|
const file = targetFile;
|
||||||
await this.doc2storate_modify(doc, file);
|
await this.doc2storage_modify(doc, file);
|
||||||
this.queueConflictedCheck(file);
|
this.queueConflictedCheck(file);
|
||||||
} else {
|
} else {
|
||||||
Logger(`${id2path(change._id)} is already exist as the folder`);
|
Logger(`${id2path(change._id)} is already exist as the folder`);
|
||||||
@@ -847,7 +847,7 @@ export default class ObsidianLiveSyncPlugin extends Plugin {
|
|||||||
a.addEventListener("click", () => this.showPluginSyncModal());
|
a.addEventListener("click", () => this.showPluginSyncModal());
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
new Notice(fragment, 10000);
|
NewNotice(fragment, 10000);
|
||||||
} else {
|
} else {
|
||||||
Logger("Everything is up to date.", LOG_LEVEL.NOTICE);
|
Logger("Everything is up to date.", LOG_LEVEL.NOTICE);
|
||||||
}
|
}
|
||||||
@@ -964,7 +964,7 @@ export default class ObsidianLiveSyncPlugin extends Plugin {
|
|||||||
|
|
||||||
async replicate(showMessage?: boolean) {
|
async replicate(showMessage?: boolean) {
|
||||||
if (this.settings.versionUpFlash != "") {
|
if (this.settings.versionUpFlash != "") {
|
||||||
new Notice("Open settings and check message, please.");
|
NewNotice("Open settings and check message, please.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
await this.applyBatchChange();
|
await this.applyBatchChange();
|
||||||
@@ -1002,7 +1002,7 @@ export default class ObsidianLiveSyncPlugin extends Plugin {
|
|||||||
// synchronize all files between database and storage.
|
// synchronize all files between database and storage.
|
||||||
let notice: Notice = null;
|
let notice: Notice = null;
|
||||||
if (showingNotice) {
|
if (showingNotice) {
|
||||||
notice = new Notice("Initializing", 0);
|
notice = NewNotice("Initializing", 0);
|
||||||
}
|
}
|
||||||
const filesStorage = this.app.vault.getFiles();
|
const filesStorage = this.app.vault.getFiles();
|
||||||
const filesStorageName = filesStorage.map((e) => e.path);
|
const filesStorageName = filesStorage.map((e) => e.path);
|
||||||
@@ -1024,12 +1024,14 @@ export default class ObsidianLiveSyncPlugin extends Plugin {
|
|||||||
Logger(procedurename);
|
Logger(procedurename);
|
||||||
let i = 0;
|
let i = 0;
|
||||||
// let lastTicks = performance.now() + 2000;
|
// let lastTicks = performance.now() + 2000;
|
||||||
|
let workProcs = 0;
|
||||||
const procs = objects.map(async (e) => {
|
const procs = objects.map(async (e) => {
|
||||||
try {
|
try {
|
||||||
|
workProcs++;
|
||||||
await callback(e);
|
await callback(e);
|
||||||
i++;
|
i++;
|
||||||
if (i % 25 == 0) {
|
if (i % 25 == 0) {
|
||||||
const notify = `${procedurename} : ${i}/${count}`;
|
const notify = `${procedurename} : ${workProcs}/${count} (Pending:${workProcs})`;
|
||||||
if (notice != null) notice.setMessage(notify);
|
if (notice != null) notice.setMessage(notify);
|
||||||
Logger(notify);
|
Logger(notify);
|
||||||
this.setStatusBarText(notify);
|
this.setStatusBarText(notify);
|
||||||
@@ -1037,27 +1039,12 @@ export default class ObsidianLiveSyncPlugin extends Plugin {
|
|||||||
} catch (ex) {
|
} catch (ex) {
|
||||||
Logger(`Error while ${procedurename}`, LOG_LEVEL.NOTICE);
|
Logger(`Error while ${procedurename}`, LOG_LEVEL.NOTICE);
|
||||||
Logger(ex);
|
Logger(ex);
|
||||||
|
} finally {
|
||||||
|
workProcs--;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
// @ts-ignore
|
|
||||||
if (!Promise.allSettled) {
|
await allSettledWithConcurrencyLimit(procs, 10);
|
||||||
await Promise.all(
|
|
||||||
procs.map((p) =>
|
|
||||||
p
|
|
||||||
.then((value) => ({
|
|
||||||
status: "fulfilled",
|
|
||||||
value,
|
|
||||||
}))
|
|
||||||
.catch((reason) => ({
|
|
||||||
status: "rejected",
|
|
||||||
reason,
|
|
||||||
}))
|
|
||||||
)
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
// @ts-ignore
|
|
||||||
await Promise.allSettled(procs);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
await runAll("UPDATE DATABASE", onlyInStorage, async (e) => {
|
await runAll("UPDATE DATABASE", onlyInStorage, async (e) => {
|
||||||
Logger(`Update into ${e.path}`);
|
Logger(`Update into ${e.path}`);
|
||||||
@@ -1329,7 +1316,7 @@ export default class ObsidianLiveSyncPlugin extends Plugin {
|
|||||||
const file = targetFile;
|
const file = targetFile;
|
||||||
const doc = await this.localDatabase.getDBEntry(filename, rev ? { rev: rev } : null, false, waitForReady);
|
const doc = await this.localDatabase.getDBEntry(filename, rev ? { rev: rev } : null, false, waitForReady);
|
||||||
if (doc === false) return;
|
if (doc === false) return;
|
||||||
await this.doc2storate_modify(doc, file, force);
|
await this.doc2storage_modify(doc, file, force);
|
||||||
} else {
|
} else {
|
||||||
Logger(`target files:${filename} is exists as the folder`);
|
Logger(`target files:${filename} is exists as the folder`);
|
||||||
//something went wrong..
|
//something went wrong..
|
||||||
@@ -1354,7 +1341,7 @@ export default class ObsidianLiveSyncPlugin extends Plugin {
|
|||||||
Logger(`${storageMtime} < ${docMtime}`);
|
Logger(`${storageMtime} < ${docMtime}`);
|
||||||
const docx = await this.localDatabase.getDBEntry(file.path, null, false, false);
|
const docx = await this.localDatabase.getDBEntry(file.path, null, false, false);
|
||||||
if (docx != false) {
|
if (docx != false) {
|
||||||
await this.doc2storate_modify(docx, file);
|
await this.doc2storage_modify(docx, file);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Logger("EVEN :" + file.path, LOG_LEVEL.VERBOSE);
|
// Logger("EVEN :" + file.path, LOG_LEVEL.VERBOSE);
|
||||||
@@ -1471,7 +1458,7 @@ export default class ObsidianLiveSyncPlugin extends Plugin {
|
|||||||
Logger("You have to set your device and vault name.", LOG_LEVEL.NOTICE);
|
Logger("You have to set your device and vault name.", LOG_LEVEL.NOTICE);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Logger("Sweeping plugins", logLevel);
|
Logger("Scanning plugins", logLevel);
|
||||||
const db = this.localDatabase.localDatabase;
|
const db = this.localDatabase.localDatabase;
|
||||||
const oldDocs = await db.allDocs({
|
const oldDocs = await db.allDocs({
|
||||||
startkey: `ps:${this.deviceAndVaultName}-`,
|
startkey: `ps:${this.deviceAndVaultName}-`,
|
||||||
@@ -1543,7 +1530,7 @@ export default class ObsidianLiveSyncPlugin extends Plugin {
|
|||||||
return e.doc;
|
return e.doc;
|
||||||
});
|
});
|
||||||
await db.bulkDocs(delDocs);
|
await db.bulkDocs(delDocs);
|
||||||
Logger(`Sweep plugin done.`, logLevel);
|
Logger(`Scan plugin done.`, logLevel);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
9
src/pouchdb-browser.ts
Normal file
9
src/pouchdb-browser.ts
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
import PouchDB from "pouchdb-core";
|
||||||
|
import IDBPouch from "pouchdb-adapter-idb";
|
||||||
|
import HttpPouch from "pouchdb-adapter-http";
|
||||||
|
import mapreduce from "pouchdb-mapreduce";
|
||||||
|
import replication from "pouchdb-replication";
|
||||||
|
|
||||||
|
PouchDB.plugin(IDBPouch).plugin(HttpPouch).plugin(mapreduce).plugin(replication);
|
||||||
|
|
||||||
|
export { PouchDB };
|
||||||
217
src/types.ts
217
src/types.ts
@@ -1,154 +1,7 @@
|
|||||||
// docs should be encoded as base64, so 1 char -> 1 bytes
|
|
||||||
// and cloudant limitation is 1MB , we use 900kb;
|
|
||||||
|
|
||||||
import { PluginManifest } from "obsidian";
|
import { PluginManifest } from "obsidian";
|
||||||
import * as PouchDB from "pouchdb";
|
import { DatabaseEntry } from "./lib/src/types";
|
||||||
|
|
||||||
export const MAX_DOC_SIZE = 1000; // for .md file, but if delimiters exists. use that before.
|
export interface PluginDataEntry extends DatabaseEntry {
|
||||||
export const MAX_DOC_SIZE_BIN = 102400; // 100kb
|
|
||||||
export const VER = 10;
|
|
||||||
|
|
||||||
export const RECENT_MOFIDIED_DOCS_QTY = 30;
|
|
||||||
export const LEAF_WAIT_TIMEOUT = 90000; // in synchronization, waiting missing leaf time out.
|
|
||||||
export const LOG_LEVEL = {
|
|
||||||
VERBOSE: 1,
|
|
||||||
INFO: 10,
|
|
||||||
NOTICE: 100,
|
|
||||||
URGENT: 1000,
|
|
||||||
} as const;
|
|
||||||
export type LOG_LEVEL = typeof LOG_LEVEL[keyof typeof LOG_LEVEL];
|
|
||||||
export const VERSIONINFO_DOCID = "obsydian_livesync_version";
|
|
||||||
export const MILSTONE_DOCID = "_local/obsydian_livesync_milestone";
|
|
||||||
export const NODEINFO_DOCID = "_local/obsydian_livesync_nodeinfo";
|
|
||||||
|
|
||||||
export interface ObsidianLiveSyncSettings {
|
|
||||||
couchDB_URI: string;
|
|
||||||
couchDB_USER: string;
|
|
||||||
couchDB_PASSWORD: string;
|
|
||||||
couchDB_DBNAME: string;
|
|
||||||
liveSync: boolean;
|
|
||||||
syncOnSave: boolean;
|
|
||||||
syncOnStart: boolean;
|
|
||||||
syncOnFileOpen: boolean;
|
|
||||||
savingDelay: number;
|
|
||||||
lessInformationInLog: boolean;
|
|
||||||
gcDelay: number;
|
|
||||||
versionUpFlash: string;
|
|
||||||
minimumChunkSize: number;
|
|
||||||
longLineThreshold: number;
|
|
||||||
showVerboseLog: boolean;
|
|
||||||
suspendFileWatching: boolean;
|
|
||||||
trashInsteadDelete: boolean;
|
|
||||||
periodicReplication: boolean;
|
|
||||||
periodicReplicationInterval: number;
|
|
||||||
encrypt: boolean;
|
|
||||||
passphrase: string;
|
|
||||||
workingEncrypt: boolean;
|
|
||||||
workingPassphrase: string;
|
|
||||||
doNotDeleteFolder: boolean;
|
|
||||||
resolveConflictsByNewerFile: boolean;
|
|
||||||
batchSave: boolean;
|
|
||||||
deviceAndVaultName: string;
|
|
||||||
usePluginSettings: boolean;
|
|
||||||
showOwnPlugins: boolean;
|
|
||||||
showStatusOnEditor: boolean;
|
|
||||||
usePluginSync: boolean;
|
|
||||||
autoSweepPlugins: boolean;
|
|
||||||
autoSweepPluginsPeriodic: boolean;
|
|
||||||
notifyPluginOrSettingUpdated: boolean;
|
|
||||||
checkIntegrityOnSave: boolean;
|
|
||||||
batch_size: number;
|
|
||||||
batches_limit: number;
|
|
||||||
useHistory: boolean;
|
|
||||||
disableRequestURI: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const DEFAULT_SETTINGS: ObsidianLiveSyncSettings = {
|
|
||||||
couchDB_URI: "",
|
|
||||||
couchDB_USER: "",
|
|
||||||
couchDB_PASSWORD: "",
|
|
||||||
couchDB_DBNAME: "",
|
|
||||||
liveSync: false,
|
|
||||||
syncOnSave: false,
|
|
||||||
syncOnStart: false,
|
|
||||||
savingDelay: 200,
|
|
||||||
lessInformationInLog: false,
|
|
||||||
gcDelay: 300,
|
|
||||||
versionUpFlash: "",
|
|
||||||
minimumChunkSize: 20,
|
|
||||||
longLineThreshold: 250,
|
|
||||||
showVerboseLog: false,
|
|
||||||
suspendFileWatching: false,
|
|
||||||
trashInsteadDelete: true,
|
|
||||||
periodicReplication: false,
|
|
||||||
periodicReplicationInterval: 60,
|
|
||||||
syncOnFileOpen: false,
|
|
||||||
encrypt: false,
|
|
||||||
passphrase: "",
|
|
||||||
workingEncrypt: false,
|
|
||||||
workingPassphrase: "",
|
|
||||||
doNotDeleteFolder: false,
|
|
||||||
resolveConflictsByNewerFile: false,
|
|
||||||
batchSave: false,
|
|
||||||
deviceAndVaultName: "",
|
|
||||||
usePluginSettings: false,
|
|
||||||
showOwnPlugins: false,
|
|
||||||
showStatusOnEditor: false,
|
|
||||||
usePluginSync: false,
|
|
||||||
autoSweepPlugins: false,
|
|
||||||
autoSweepPluginsPeriodic: false,
|
|
||||||
notifyPluginOrSettingUpdated: false,
|
|
||||||
checkIntegrityOnSave: false,
|
|
||||||
batch_size: 250,
|
|
||||||
batches_limit: 40,
|
|
||||||
useHistory: false,
|
|
||||||
disableRequestURI: false,
|
|
||||||
};
|
|
||||||
|
|
||||||
export const PERIODIC_PLUGIN_SWEEP = 60;
|
|
||||||
|
|
||||||
export interface Entry {
|
|
||||||
_id: string;
|
|
||||||
data: string;
|
|
||||||
_rev?: string;
|
|
||||||
ctime: number;
|
|
||||||
mtime: number;
|
|
||||||
size: number;
|
|
||||||
_deleted?: boolean;
|
|
||||||
_conflicts?: string[];
|
|
||||||
type?: "notes";
|
|
||||||
}
|
|
||||||
export interface NewEntry {
|
|
||||||
_id: string;
|
|
||||||
children: string[];
|
|
||||||
_rev?: string;
|
|
||||||
ctime: number;
|
|
||||||
mtime: number;
|
|
||||||
size: number;
|
|
||||||
_deleted?: boolean;
|
|
||||||
_conflicts?: string[];
|
|
||||||
NewNote: true;
|
|
||||||
type: "newnote";
|
|
||||||
}
|
|
||||||
export interface PlainEntry {
|
|
||||||
_id: string;
|
|
||||||
children: string[];
|
|
||||||
_rev?: string;
|
|
||||||
ctime: number;
|
|
||||||
mtime: number;
|
|
||||||
size: number;
|
|
||||||
_deleted?: boolean;
|
|
||||||
NewNote: true;
|
|
||||||
_conflicts?: string[];
|
|
||||||
type: "plain";
|
|
||||||
}
|
|
||||||
export type LoadedEntry = Entry & {
|
|
||||||
children: string[];
|
|
||||||
datatype: "plain" | "newnote";
|
|
||||||
};
|
|
||||||
|
|
||||||
export interface PluginDataEntry {
|
|
||||||
_id: string;
|
|
||||||
deviceVaultName: string;
|
deviceVaultName: string;
|
||||||
mtime: number;
|
mtime: number;
|
||||||
manifest: PluginManifest;
|
manifest: PluginManifest;
|
||||||
@@ -157,73 +10,10 @@ export interface PluginDataEntry {
|
|||||||
styleCss?: string;
|
styleCss?: string;
|
||||||
// it must be encrypted.
|
// it must be encrypted.
|
||||||
dataJson?: string;
|
dataJson?: string;
|
||||||
_rev?: string;
|
|
||||||
_deleted?: boolean;
|
|
||||||
_conflicts?: string[];
|
_conflicts?: string[];
|
||||||
type: "plugin";
|
type: "plugin";
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface EntryLeaf {
|
|
||||||
_id: string;
|
|
||||||
data: string;
|
|
||||||
_deleted?: boolean;
|
|
||||||
type: "leaf";
|
|
||||||
_rev?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface EntryVersionInfo {
|
|
||||||
_id: typeof VERSIONINFO_DOCID;
|
|
||||||
_rev?: string;
|
|
||||||
type: "versioninfo";
|
|
||||||
version: number;
|
|
||||||
_deleted?: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface EntryMilestoneInfo {
|
|
||||||
_id: typeof MILSTONE_DOCID;
|
|
||||||
_rev?: string;
|
|
||||||
type: "milestoneinfo";
|
|
||||||
_deleted?: boolean;
|
|
||||||
created: number;
|
|
||||||
accepted_nodes: string[];
|
|
||||||
locked: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface EntryNodeInfo {
|
|
||||||
_id: typeof NODEINFO_DOCID;
|
|
||||||
_rev?: string;
|
|
||||||
_deleted?: boolean;
|
|
||||||
type: "nodeinfo";
|
|
||||||
nodeid: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export type EntryBody = Entry | NewEntry | PlainEntry;
|
|
||||||
export type EntryDoc = EntryBody | LoadedEntry | EntryLeaf | EntryVersionInfo | EntryMilestoneInfo | EntryNodeInfo;
|
|
||||||
|
|
||||||
export type diff_result_leaf = {
|
|
||||||
rev: string;
|
|
||||||
data: string;
|
|
||||||
ctime: number;
|
|
||||||
mtime: number;
|
|
||||||
};
|
|
||||||
export type dmp_result = Array<[number, string]>;
|
|
||||||
|
|
||||||
export type diff_result = {
|
|
||||||
left: diff_result_leaf;
|
|
||||||
right: diff_result_leaf;
|
|
||||||
diff: dmp_result;
|
|
||||||
};
|
|
||||||
export type diff_check_result = boolean | diff_result;
|
|
||||||
|
|
||||||
export type Credential = {
|
|
||||||
username: string;
|
|
||||||
password: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type EntryDocResponse = EntryDoc & PouchDB.Core.IdMeta & PouchDB.Core.GetMeta;
|
|
||||||
|
|
||||||
export type DatabaseConnectingStatus = "STARTED" | "NOT_CONNECTED" | "PAUSED" | "CONNECTED" | "COMPLETED" | "CLOSED" | "ERRORED";
|
|
||||||
|
|
||||||
export interface PluginList {
|
export interface PluginList {
|
||||||
[key: string]: PluginDataEntry[];
|
[key: string]: PluginDataEntry[];
|
||||||
}
|
}
|
||||||
@@ -231,5 +21,4 @@ export interface PluginList {
|
|||||||
export interface DevicePluginList {
|
export interface DevicePluginList {
|
||||||
[key: string]: PluginDataEntry;
|
[key: string]: PluginDataEntry;
|
||||||
}
|
}
|
||||||
|
export const PERIODIC_PLUGIN_SWEEP = 60;
|
||||||
export const FLAGMD_REDFLAG = "redflag.md";
|
|
||||||
|
|||||||
243
src/utils.ts
243
src/utils.ts
@@ -1,249 +1,14 @@
|
|||||||
import { normalizePath } from "obsidian";
|
import { normalizePath } from "obsidian";
|
||||||
import { Logger } from "./logger";
|
|
||||||
import { FLAGMD_REDFLAG, LOG_LEVEL } from "./types";
|
|
||||||
|
|
||||||
export function arrayBufferToBase64(buffer: ArrayBuffer): Promise<string> {
|
import { path2id_base, id2path_base } from "./lib/src/utils";
|
||||||
return new Promise((res) => {
|
|
||||||
const blob = new Blob([buffer], { type: "application/octet-binary" });
|
|
||||||
const reader = new FileReader();
|
|
||||||
reader.onload = function (evt) {
|
|
||||||
const dataurl = evt.target.result.toString();
|
|
||||||
res(dataurl.substr(dataurl.indexOf(",") + 1));
|
|
||||||
};
|
|
||||||
reader.readAsDataURL(blob);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
export function base64ToString(base64: string): string {
|
|
||||||
try {
|
|
||||||
const binary_string = window.atob(base64);
|
|
||||||
const len = binary_string.length;
|
|
||||||
const bytes = new Uint8Array(len);
|
|
||||||
for (let i = 0; i < len; i++) {
|
|
||||||
bytes[i] = binary_string.charCodeAt(i);
|
|
||||||
}
|
|
||||||
return new TextDecoder().decode(bytes);
|
|
||||||
} catch (ex) {
|
|
||||||
return base64;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
export function base64ToArrayBuffer(base64: string): ArrayBuffer {
|
|
||||||
try {
|
|
||||||
const binary_string = window.atob(base64);
|
|
||||||
const len = binary_string.length;
|
|
||||||
const bytes = new Uint8Array(len);
|
|
||||||
for (let i = 0; i < len; i++) {
|
|
||||||
bytes[i] = binary_string.charCodeAt(i);
|
|
||||||
}
|
|
||||||
return bytes.buffer;
|
|
||||||
} catch (ex) {
|
|
||||||
try {
|
|
||||||
return new Uint16Array(
|
|
||||||
[].map.call(base64, function (c: string) {
|
|
||||||
return c.charCodeAt(0);
|
|
||||||
})
|
|
||||||
).buffer;
|
|
||||||
} catch (ex2) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export const escapeStringToHTML = (str: string) => {
|
|
||||||
if (!str) return "";
|
|
||||||
return str.replace(/[<>&"'`]/g, (match) => {
|
|
||||||
const escape: any = {
|
|
||||||
"<": "<",
|
|
||||||
">": ">",
|
|
||||||
"&": "&",
|
|
||||||
'"': """,
|
|
||||||
"'": "'",
|
|
||||||
"`": "`",
|
|
||||||
};
|
|
||||||
return escape[match];
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
export function resolveWithIgnoreKnownError<T>(p: Promise<T>, def: T): Promise<T> {
|
|
||||||
return new Promise((res, rej) => {
|
|
||||||
p.then(res).catch((ex) => (ex.status && ex.status == 404 ? res(def) : rej(ex)));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
export function isValidPath(filename: string): boolean {
|
|
||||||
// eslint-disable-next-line no-control-regex
|
|
||||||
const regex = /[\u0000-\u001f]|[\\":?<>|*#]/g;
|
|
||||||
let x = filename.replace(regex, "_");
|
|
||||||
const win = /(\\|\/)(COM\d|LPT\d|CON|PRN|AUX|NUL|CLOCK$)($|\.)/gi;
|
|
||||||
const sx = (x = x.replace(win, "/_"));
|
|
||||||
return sx == filename;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function shouldBeIgnored(filename: string): boolean {
|
|
||||||
if (filename == FLAGMD_REDFLAG) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function versionNumberString2Number(version: string): number {
|
|
||||||
return version // "1.23.45"
|
|
||||||
.split(".") // 1 23 45
|
|
||||||
.reverse() // 45 23 1
|
|
||||||
.map((e, i) => ((e as any) / 1) * 1000 ** i) // 45 23000 1000000
|
|
||||||
.reduce((prev, current) => prev + current, 0); // 1023045
|
|
||||||
}
|
|
||||||
|
|
||||||
export const delay = (ms: number): Promise<void> => {
|
|
||||||
return new Promise((res) => {
|
|
||||||
setTimeout(() => {
|
|
||||||
res();
|
|
||||||
}, ms);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
// For backward compatibility, using the path for determining id.
|
// For backward compatibility, using the path for determining id.
|
||||||
// Only CouchDB nonacceptable ID (that starts with an underscore) has been prefixed with "/".
|
// Only CouchDB nonacceptable ID (that starts with an underscore) has been prefixed with "/".
|
||||||
// The first slash will be deleted when the path is normalized.
|
// The first slash will be deleted when the path is normalized.
|
||||||
export function path2id(filename: string): string {
|
export function path2id(filename: string): string {
|
||||||
let x = normalizePath(filename);
|
const x = normalizePath(filename);
|
||||||
if (x.startsWith("_")) x = "/" + x;
|
return path2id_base(x);
|
||||||
return x;
|
|
||||||
}
|
}
|
||||||
export function id2path(filename: string): string {
|
export function id2path(filename: string): string {
|
||||||
return normalizePath(filename);
|
return id2path_base(normalizePath(filename));
|
||||||
}
|
|
||||||
|
|
||||||
const runningProcs: string[] = [];
|
|
||||||
const pendingProcs: { [key: string]: (() => Promise<void>)[] } = {};
|
|
||||||
function objectToKey(key: any): string {
|
|
||||||
if (typeof key === "string") return key;
|
|
||||||
const keys = Object.keys(key).sort((a, b) => a.localeCompare(b));
|
|
||||||
return keys.map((e) => e + objectToKey(key[e])).join(":");
|
|
||||||
}
|
|
||||||
export function getProcessingCounts() {
|
|
||||||
let count = 0;
|
|
||||||
for (const v in pendingProcs) {
|
|
||||||
count += pendingProcs[v].length;
|
|
||||||
}
|
|
||||||
count += runningProcs.length;
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
|
|
||||||
let externalNotifier: () => void = () => {};
|
|
||||||
let notifyTimer: number = null;
|
|
||||||
export function setLockNotifier(fn: () => void) {
|
|
||||||
externalNotifier = fn;
|
|
||||||
}
|
|
||||||
function notifyLock() {
|
|
||||||
if (notifyTimer != null) {
|
|
||||||
window.clearTimeout(notifyTimer);
|
|
||||||
}
|
|
||||||
notifyTimer = window.setTimeout(() => {
|
|
||||||
externalNotifier();
|
|
||||||
}, 100);
|
|
||||||
}
|
|
||||||
// Just run async/await as like transacion ISOLATION SERIALIZABLE
|
|
||||||
export function runWithLock<T>(key: unknown, ignoreWhenRunning: boolean, proc: () => Promise<T>): Promise<T> {
|
|
||||||
// Logger(`Lock:${key}:enter`, LOG_LEVEL.VERBOSE);
|
|
||||||
const lockKey = typeof key === "string" ? key : objectToKey(key);
|
|
||||||
const handleNextProcs = () => {
|
|
||||||
if (typeof pendingProcs[lockKey] === "undefined") {
|
|
||||||
//simply unlock
|
|
||||||
runningProcs.remove(lockKey);
|
|
||||||
notifyLock();
|
|
||||||
// Logger(`Lock:${lockKey}:released`, LOG_LEVEL.VERBOSE);
|
|
||||||
} else {
|
|
||||||
Logger(`Lock:${lockKey}:left ${pendingProcs[lockKey].length}`, LOG_LEVEL.VERBOSE);
|
|
||||||
let nextProc = null;
|
|
||||||
nextProc = pendingProcs[lockKey].shift();
|
|
||||||
notifyLock();
|
|
||||||
if (nextProc) {
|
|
||||||
// left some
|
|
||||||
nextProc()
|
|
||||||
.then()
|
|
||||||
.catch((err) => {
|
|
||||||
Logger(err);
|
|
||||||
})
|
|
||||||
.finally(() => {
|
|
||||||
if (pendingProcs && lockKey in pendingProcs && pendingProcs[lockKey].length == 0) {
|
|
||||||
delete pendingProcs[lockKey];
|
|
||||||
notifyLock();
|
|
||||||
}
|
|
||||||
queueMicrotask(() => {
|
|
||||||
handleNextProcs();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
if (pendingProcs && lockKey in pendingProcs && pendingProcs[lockKey].length == 0) {
|
|
||||||
delete pendingProcs[lockKey];
|
|
||||||
notifyLock();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
if (runningProcs.contains(lockKey)) {
|
|
||||||
if (ignoreWhenRunning) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
if (typeof pendingProcs[lockKey] === "undefined") {
|
|
||||||
pendingProcs[lockKey] = [];
|
|
||||||
}
|
|
||||||
let responderRes: (value: T | PromiseLike<T>) => void;
|
|
||||||
let responderRej: (reason?: unknown) => void;
|
|
||||||
const responder = new Promise<T>((res, rej) => {
|
|
||||||
responderRes = res;
|
|
||||||
responderRej = rej;
|
|
||||||
//wait for subproc resolved
|
|
||||||
});
|
|
||||||
const subproc = () =>
|
|
||||||
new Promise<void>((res, rej) => {
|
|
||||||
proc()
|
|
||||||
.then((v) => {
|
|
||||||
// Logger(`Lock:${key}:processed`, LOG_LEVEL.VERBOSE);
|
|
||||||
handleNextProcs();
|
|
||||||
responderRes(v);
|
|
||||||
res();
|
|
||||||
})
|
|
||||||
.catch((reason) => {
|
|
||||||
Logger(`Lock:${key}:rejected`, LOG_LEVEL.VERBOSE);
|
|
||||||
handleNextProcs();
|
|
||||||
rej(reason);
|
|
||||||
responderRej(reason);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
pendingProcs[lockKey].push(subproc);
|
|
||||||
notifyLock();
|
|
||||||
// Logger(`Lock:${lockKey}:queud:left${pendingProcs[lockKey].length}`, LOG_LEVEL.VERBOSE);
|
|
||||||
return responder;
|
|
||||||
} else {
|
|
||||||
runningProcs.push(lockKey);
|
|
||||||
notifyLock();
|
|
||||||
// Logger(`Lock:${lockKey}:aqquired`, LOG_LEVEL.VERBOSE);
|
|
||||||
return new Promise((res, rej) => {
|
|
||||||
proc()
|
|
||||||
.then((v) => {
|
|
||||||
handleNextProcs();
|
|
||||||
res(v);
|
|
||||||
})
|
|
||||||
.catch((reason) => {
|
|
||||||
handleNextProcs();
|
|
||||||
rej(reason);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function isPlainText(filename: string): boolean {
|
|
||||||
if (filename.endsWith(".md")) return true;
|
|
||||||
if (filename.endsWith(".txt")) return true;
|
|
||||||
if (filename.endsWith(".svg")) return true;
|
|
||||||
if (filename.endsWith(".html")) return true;
|
|
||||||
if (filename.endsWith(".csv")) return true;
|
|
||||||
if (filename.endsWith(".css")) return true;
|
|
||||||
if (filename.endsWith(".js")) return true;
|
|
||||||
if (filename.endsWith(".xml")) return true;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { Logger } from "./logger";
|
import { Logger } from "./lib/src/logger";
|
||||||
import { LOG_LEVEL, VER, VERSIONINFO_DOCID, EntryVersionInfo, EntryDoc } from "./types";
|
import { LOG_LEVEL, VER, VERSIONINFO_DOCID, EntryVersionInfo, EntryDoc } from "./lib/src/types";
|
||||||
import { resolveWithIgnoreKnownError } from "./utils";
|
import { resolveWithIgnoreKnownError } from "./lib/src/utils";
|
||||||
import { PouchDB } from "../pouchdb-browser-webpack/dist/pouchdb-browser.js";
|
import { PouchDB } from "./pouchdb-browser";
|
||||||
import { requestUrl, RequestUrlParam, RequestUrlResponse } from "obsidian";
|
import { requestUrl, RequestUrlParam, RequestUrlResponse } from "obsidian";
|
||||||
|
|
||||||
export const isValidRemoteCouchDBURI = (uri: string): boolean => {
|
export const isValidRemoteCouchDBURI = (uri: string): boolean => {
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
// "importsNotUsedAsValues": "error",
|
// "importsNotUsedAsValues": "error",
|
||||||
"importHelpers": true,
|
"importHelpers": true,
|
||||||
"alwaysStrict": true,
|
"alwaysStrict": true,
|
||||||
|
"allowSyntheticDefaultImports": true,
|
||||||
"lib": ["es2018", "DOM", "ES5", "ES6", "ES7"]
|
"lib": ["es2018", "DOM", "ES5", "ES6", "ES7"]
|
||||||
},
|
},
|
||||||
"include": ["**/*.ts"],
|
"include": ["**/*.ts"],
|
||||||
|
|||||||
Reference in New Issue
Block a user