mirror of
https://github.com/vrtmrz/obsidian-livesync.git
synced 2026-05-21 23:01:32 +00:00
Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
009f92c307 | ||
|
|
3e541bd061 |
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"id": "obsidian-livesync",
|
"id": "obsidian-livesync",
|
||||||
"name": "Self-hosted LiveSync",
|
"name": "Self-hosted LiveSync",
|
||||||
"version": "0.17.27",
|
"version": "0.17.28",
|
||||||
"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",
|
||||||
|
|||||||
4
package-lock.json
generated
4
package-lock.json
generated
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "obsidian-livesync",
|
"name": "obsidian-livesync",
|
||||||
"version": "0.17.27",
|
"version": "0.17.28",
|
||||||
"lockfileVersion": 2,
|
"lockfileVersion": 2,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "obsidian-livesync",
|
"name": "obsidian-livesync",
|
||||||
"version": "0.17.27",
|
"version": "0.17.28",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"diff-match-patch": "^1.0.5",
|
"diff-match-patch": "^1.0.5",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "obsidian-livesync",
|
"name": "obsidian-livesync",
|
||||||
"version": "0.17.27",
|
"version": "0.17.28",
|
||||||
"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",
|
||||||
|
|||||||
2
src/lib
2
src/lib
Submodule src/lib updated: fbb3fcd8b4...45169f72f4
61
src/main.ts
61
src/main.ts
@@ -64,7 +64,6 @@ function filename2idInternalMetadata(str: string): string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const CHeader = "h:";
|
const CHeader = "h:";
|
||||||
const CHeaderEnd = "h;";
|
|
||||||
// const CHeaderLength = CHeader.length;
|
// const CHeaderLength = CHeader.length;
|
||||||
function isChunk(str: string): boolean {
|
function isChunk(str: string): boolean {
|
||||||
return str.startsWith(CHeader);
|
return str.startsWith(CHeader);
|
||||||
@@ -235,30 +234,18 @@ export default class ObsidianLiveSyncPlugin extends Plugin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async collectDeletedFiles() {
|
async collectDeletedFiles() {
|
||||||
const pageLimit = 1000;
|
|
||||||
let nextKey = "";
|
|
||||||
const limitDays = this.settings.automaticallyDeleteMetadataOfDeletedFiles;
|
const limitDays = this.settings.automaticallyDeleteMetadataOfDeletedFiles;
|
||||||
if (limitDays <= 0) return;
|
if (limitDays <= 0) return;
|
||||||
Logger(`Checking expired file history`);
|
Logger(`Checking expired file history`);
|
||||||
const limit = Date.now() - (86400 * 1000 * limitDays);
|
const limit = Date.now() - (86400 * 1000 * limitDays);
|
||||||
const notes: { path: string, mtime: number, ttl: number, doc: PouchDB.Core.ExistingDocument<EntryDoc & PouchDB.Core.AllDocsMeta> }[] = [];
|
const notes: { path: string, mtime: number, ttl: number, doc: PouchDB.Core.ExistingDocument<EntryDoc & PouchDB.Core.AllDocsMeta> }[] = [];
|
||||||
do {
|
for await (const doc of this.localDatabase.findAllDocs({ conflicts: true })) {
|
||||||
const docs = await this.localDatabase.localDatabase.allDocs({ limit: pageLimit, startkey: nextKey, conflicts: true, include_docs: true });
|
if (doc.type == "newnote" || doc.type == "plain") {
|
||||||
nextKey = "";
|
if (doc.deleted && (doc.mtime - limit) < 0) {
|
||||||
for (const row of docs.rows) {
|
notes.push({ path: id2path(doc._id), mtime: doc.mtime, ttl: (doc.mtime - limit) / 1000 / 86400, doc: doc });
|
||||||
const doc = row.doc;
|
|
||||||
nextKey = `${row.id}\u{10ffff}`;
|
|
||||||
if (doc.type == "newnote" || doc.type == "plain") {
|
|
||||||
if (doc.deleted && (doc.mtime - limit) < 0) {
|
|
||||||
notes.push({ path: id2path(doc._id), mtime: doc.mtime, ttl: (doc.mtime - limit) / 1000 / 86400, doc: doc });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (isChunk(nextKey)) {
|
|
||||||
// skip the chunk zone.
|
|
||||||
nextKey = CHeaderEnd;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} while (nextKey != "");
|
}
|
||||||
if (notes.length == 0) {
|
if (notes.length == 0) {
|
||||||
Logger("There are no old documents");
|
Logger("There are no old documents");
|
||||||
Logger(`Checking expired file history done`);
|
Logger(`Checking expired file history done`);
|
||||||
@@ -331,7 +318,7 @@ export default class ObsidianLiveSyncPlugin extends Plugin {
|
|||||||
if (this.settings.suspendFileWatching) {
|
if (this.settings.suspendFileWatching) {
|
||||||
Logger("'Suspend file watching' turned on. Are you sure this is what you intended? Every modification on the vault will be ignored.", LOG_LEVEL.NOTICE);
|
Logger("'Suspend file watching' turned on. Are you sure this is what you intended? Every modification on the vault will be ignored.", LOG_LEVEL.NOTICE);
|
||||||
}
|
}
|
||||||
const isInitialized = await this.initializeDatabase();
|
const isInitialized = await this.initializeDatabase(false, false);
|
||||||
if (!isInitialized) {
|
if (!isInitialized) {
|
||||||
//TODO:stop all sync.
|
//TODO:stop all sync.
|
||||||
return false;
|
return false;
|
||||||
@@ -435,7 +422,6 @@ export default class ObsidianLiveSyncPlugin extends Plugin {
|
|||||||
this.settings = newSettingW;
|
this.settings = newSettingW;
|
||||||
this.usedPassphrase = "";
|
this.usedPassphrase = "";
|
||||||
await this.saveSettings();
|
await this.saveSettings();
|
||||||
await this.resetLocalOldDatabase();
|
|
||||||
await this.resetLocalDatabase();
|
await this.resetLocalDatabase();
|
||||||
await this.localDatabase.initializeDatabase();
|
await this.localDatabase.initializeDatabase();
|
||||||
await this.markRemoteResolved();
|
await this.markRemoteResolved();
|
||||||
@@ -448,7 +434,6 @@ export default class ObsidianLiveSyncPlugin extends Plugin {
|
|||||||
this.settings = newSettingW;
|
this.settings = newSettingW;
|
||||||
this.usedPassphrase = "";
|
this.usedPassphrase = "";
|
||||||
await this.saveSettings();
|
await this.saveSettings();
|
||||||
await this.resetLocalOldDatabase();
|
|
||||||
await this.resetLocalDatabase();
|
await this.resetLocalDatabase();
|
||||||
await this.localDatabase.initializeDatabase();
|
await this.localDatabase.initializeDatabase();
|
||||||
await this.initializeDatabase(true);
|
await this.initializeDatabase(true);
|
||||||
@@ -486,7 +471,6 @@ export default class ObsidianLiveSyncPlugin extends Plugin {
|
|||||||
this.usedPassphrase = "";
|
this.usedPassphrase = "";
|
||||||
await this.saveSettings();
|
await this.saveSettings();
|
||||||
if (keepLocalDB == "no") {
|
if (keepLocalDB == "no") {
|
||||||
this.resetLocalOldDatabase();
|
|
||||||
this.resetLocalDatabase();
|
this.resetLocalDatabase();
|
||||||
this.localDatabase.initializeDatabase();
|
this.localDatabase.initializeDatabase();
|
||||||
const rebuild = await askYesNo(this.app, "Rebuild the database?");
|
const rebuild = await askYesNo(this.app, "Rebuild the database?");
|
||||||
@@ -535,6 +519,7 @@ export default class ObsidianLiveSyncPlugin extends Plugin {
|
|||||||
const lsKey = "obsidian-live-sync-ver" + this.getVaultName();
|
const lsKey = "obsidian-live-sync-ver" + this.getVaultName();
|
||||||
const last_version = localStorage.getItem(lsKey);
|
const last_version = localStorage.getItem(lsKey);
|
||||||
await this.loadSettings();
|
await this.loadSettings();
|
||||||
|
|
||||||
const lastVersion = ~~(versionNumberString2Number(manifestVersion) / 1000);
|
const lastVersion = ~~(versionNumberString2Number(manifestVersion) / 1000);
|
||||||
if (lastVersion > this.settings.lastReadUpdates) {
|
if (lastVersion > this.settings.lastReadUpdates) {
|
||||||
Logger("Self-hosted LiveSync has undergone a major upgrade. Please open the setting dialog, and check the information pane.", LOG_LEVEL.NOTICE);
|
Logger("Self-hosted LiveSync has undergone a major upgrade. Please open the setting dialog, and check the information pane.", LOG_LEVEL.NOTICE);
|
||||||
@@ -785,7 +770,7 @@ export default class ObsidianLiveSyncPlugin extends Plugin {
|
|||||||
await this.localDatabase.close();
|
await this.localDatabase.close();
|
||||||
}
|
}
|
||||||
const vaultName = this.getVaultName();
|
const vaultName = this.getVaultName();
|
||||||
Logger("Open Database...");
|
Logger("Waiting for ready...");
|
||||||
//@ts-ignore
|
//@ts-ignore
|
||||||
const isMobile = this.app.isMobile;
|
const isMobile = this.app.isMobile;
|
||||||
this.localDatabase = new LocalPouchDB(this.settings, vaultName, isMobile);
|
this.localDatabase = new LocalPouchDB(this.settings, vaultName, isMobile);
|
||||||
@@ -1925,9 +1910,9 @@ export default class ObsidianLiveSyncPlugin extends Plugin {
|
|||||||
await this.localDatabase.openReplication(this.settings, false, showMessage, this.parseReplicationResult);
|
await this.localDatabase.openReplication(this.settings, false, showMessage, this.parseReplicationResult);
|
||||||
}
|
}
|
||||||
|
|
||||||
async initializeDatabase(showingNotice?: boolean) {
|
async initializeDatabase(showingNotice?: boolean, reopenDatabase = true) {
|
||||||
this.isReady = false;
|
this.isReady = false;
|
||||||
if (await this.openDatabase()) {
|
if ((!reopenDatabase) || await this.openDatabase()) {
|
||||||
if (this.localDatabase.isReady) {
|
if (this.localDatabase.isReady) {
|
||||||
await this.syncAllFiles(showingNotice);
|
await this.syncAllFiles(showingNotice);
|
||||||
}
|
}
|
||||||
@@ -1989,18 +1974,22 @@ export default class ObsidianLiveSyncPlugin extends Plugin {
|
|||||||
Logger("Initializing", LOG_LEVEL.NOTICE, "syncAll");
|
Logger("Initializing", LOG_LEVEL.NOTICE, "syncAll");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Logger("Initialize and checking database files");
|
||||||
|
Logger("Checking deleted files");
|
||||||
await this.collectDeletedFiles();
|
await this.collectDeletedFiles();
|
||||||
|
|
||||||
|
Logger("Collecting local files on the storage", LOG_LEVEL.VERBOSE);
|
||||||
const filesStorage = this.app.vault.getFiles().filter(e => this.isTargetFile(e));
|
const filesStorage = this.app.vault.getFiles().filter(e => this.isTargetFile(e));
|
||||||
const filesStorageName = filesStorage.map((e) => e.path);
|
const filesStorageName = filesStorage.map((e) => e.path);
|
||||||
const wf = await this.localDatabase.localDatabase.allDocs();
|
Logger("Collecting local files on the DB", LOG_LEVEL.VERBOSE);
|
||||||
const filesDatabase = wf.rows.filter((e) =>
|
const filesDatabase = [] as string[]
|
||||||
!isChunk(e.id) &&
|
for await (const doc of this.localDatabase.findAllDocs()) {
|
||||||
!isPluginMetadata(e.id) &&
|
const path = id2path(doc._id);
|
||||||
e.id != "obsydian_livesync_version" &&
|
if (isValidPath(doc._id) && this.isTargetFile(path)) {
|
||||||
e.id != "_design/replicate"
|
filesDatabase.push(path);
|
||||||
)
|
}
|
||||||
.filter(e => isValidPath(e.id)).map((e) => id2path(e.id)).filter(e => this.isTargetFile(e));
|
}
|
||||||
|
Logger("Opening the key-value database", LOG_LEVEL.VERBOSE);
|
||||||
const isInitialized = await (this.localDatabase.kvDB.get<boolean>("initialized")) || false;
|
const isInitialized = await (this.localDatabase.kvDB.get<boolean>("initialized")) || false;
|
||||||
// Make chunk bigger if it is the initial scan. There must be non-active docs.
|
// Make chunk bigger if it is the initial scan. There must be non-active docs.
|
||||||
if (filesDatabase.length == 0 && !isInitialized) {
|
if (filesDatabase.length == 0 && !isInitialized) {
|
||||||
@@ -2013,7 +2002,6 @@ export default class ObsidianLiveSyncPlugin extends Plugin {
|
|||||||
const onlyInStorageNames = onlyInStorage.map((e) => e.path);
|
const onlyInStorageNames = onlyInStorage.map((e) => e.path);
|
||||||
|
|
||||||
const syncFiles = filesStorage.filter((e) => onlyInStorageNames.indexOf(e.path) == -1);
|
const syncFiles = filesStorage.filter((e) => onlyInStorageNames.indexOf(e.path) == -1);
|
||||||
Logger("Initialize and checking database files");
|
|
||||||
Logger("Updating database by new files");
|
Logger("Updating database by new files");
|
||||||
this.setStatusBarText(`UPDATE DATABASE`);
|
this.setStatusBarText(`UPDATE DATABASE`);
|
||||||
|
|
||||||
@@ -2827,11 +2815,6 @@ export default class ObsidianLiveSyncPlugin extends Plugin {
|
|||||||
async resetLocalDatabase() {
|
async resetLocalDatabase() {
|
||||||
clearTouched();
|
clearTouched();
|
||||||
await this.localDatabase.resetDatabase();
|
await this.localDatabase.resetDatabase();
|
||||||
await this.localDatabase.resetLocalOldDatabase();
|
|
||||||
}
|
|
||||||
async resetLocalOldDatabase() {
|
|
||||||
clearTouched();
|
|
||||||
await this.localDatabase.resetLocalOldDatabase();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async tryResetRemoteDatabase() {
|
async tryResetRemoteDatabase() {
|
||||||
|
|||||||
@@ -75,5 +75,12 @@
|
|||||||
- The plugin data can be resolved when conflicted.
|
- The plugin data can be resolved when conflicted.
|
||||||
- The semaphore status display has been changed to count only.
|
- The semaphore status display has been changed to count only.
|
||||||
- Applying to the storage will be concurrent with a few files.
|
- Applying to the storage will be concurrent with a few files.
|
||||||
|
- 0.17.28
|
||||||
|
-Fixed:
|
||||||
|
- Some messages have been refined.
|
||||||
|
- Boot sequence has been speeded up.
|
||||||
|
- Opening the local database multiple times in a short duration has been suppressed.
|
||||||
|
- Older migration logic.
|
||||||
|
- Note: If you have used 0.10.0 or lower and have not upgraded, you will need to run 0.17.27 or earlier once or reinstall Obsidian.
|
||||||
|
|
||||||
... To continue on to `updates_old.md`.
|
... To continue on to `updates_old.md`.
|
||||||
Reference in New Issue
Block a user