mirror of
https://github.com/vrtmrz/obsidian-livesync.git
synced 2026-05-20 14:21:35 +00:00
Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7046928068 | ||
|
|
333fcbaaeb |
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"id": "obsidian-livesync",
|
"id": "obsidian-livesync",
|
||||||
"name": "Self-hosted LiveSync",
|
"name": "Self-hosted LiveSync",
|
||||||
"version": "0.17.28",
|
"version": "0.17.29",
|
||||||
"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.28",
|
"version": "0.17.29",
|
||||||
"lockfileVersion": 2,
|
"lockfileVersion": 2,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "obsidian-livesync",
|
"name": "obsidian-livesync",
|
||||||
"version": "0.17.28",
|
"version": "0.17.29",
|
||||||
"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.28",
|
"version": "0.17.29",
|
||||||
"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",
|
||||||
|
|||||||
@@ -453,6 +453,9 @@ export class ObsidianLiveSyncSettingTab extends PluginSettingTab {
|
|||||||
this.plugin.settings.syncOnStart = false;
|
this.plugin.settings.syncOnStart = false;
|
||||||
this.plugin.settings.syncOnFileOpen = false;
|
this.plugin.settings.syncOnFileOpen = false;
|
||||||
this.plugin.settings.syncAfterMerge = false;
|
this.plugin.settings.syncAfterMerge = false;
|
||||||
|
this.plugin.settings.syncInternalFiles = false;
|
||||||
|
this.plugin.settings.usePluginSync = false;
|
||||||
|
Logger("Hidden files and plugin synchronization have been temporarily disabled. Please enable them after the fetching, if you need them.", LOG_LEVEL.NOTICE)
|
||||||
await this.plugin.saveSettings();
|
await this.plugin.saveSettings();
|
||||||
|
|
||||||
applyDisplayEnabled();
|
applyDisplayEnabled();
|
||||||
@@ -1324,7 +1327,38 @@ export class ObsidianLiveSyncSettingTab extends PluginSettingTab {
|
|||||||
});
|
});
|
||||||
text.inputEl.setAttribute("type", "number");
|
text.inputEl.setAttribute("type", "number");
|
||||||
});
|
});
|
||||||
|
new Setting(containerSyncSettingEl)
|
||||||
|
.setName("The maximum number of reading chunks online concurrently")
|
||||||
|
.setDesc("")
|
||||||
|
.addText((text) => {
|
||||||
|
text.setPlaceholder("")
|
||||||
|
.setValue(this.plugin.settings.concurrencyOfReadChunksOnline + "")
|
||||||
|
.onChange(async (value) => {
|
||||||
|
let v = Number(value);
|
||||||
|
if (isNaN(v) || v < 10) {
|
||||||
|
v = 10;
|
||||||
|
}
|
||||||
|
this.plugin.settings.concurrencyOfReadChunksOnline = v;
|
||||||
|
await this.plugin.saveSettings();
|
||||||
|
});
|
||||||
|
text.inputEl.setAttribute("type", "number");
|
||||||
|
});
|
||||||
|
new Setting(containerSyncSettingEl)
|
||||||
|
.setName("The minimum interval for reading chunks online")
|
||||||
|
.setDesc("")
|
||||||
|
.addText((text) => {
|
||||||
|
text.setPlaceholder("")
|
||||||
|
.setValue(this.plugin.settings.minimumIntervalOfReadChunksOnline + "")
|
||||||
|
.onChange(async (value) => {
|
||||||
|
let v = Number(value);
|
||||||
|
if (isNaN(v) || v < 10) {
|
||||||
|
v = 10;
|
||||||
|
}
|
||||||
|
this.plugin.settings.minimumIntervalOfReadChunksOnline = v;
|
||||||
|
await this.plugin.saveSettings();
|
||||||
|
});
|
||||||
|
text.inputEl.setAttribute("type", "number");
|
||||||
|
});
|
||||||
addScreenElement("30", containerSyncSettingEl);
|
addScreenElement("30", containerSyncSettingEl);
|
||||||
const containerMiscellaneousEl = containerEl.createDiv();
|
const containerMiscellaneousEl = containerEl.createDiv();
|
||||||
containerMiscellaneousEl.createEl("h3", { text: "Miscellaneous" });
|
containerMiscellaneousEl.createEl("h3", { text: "Miscellaneous" });
|
||||||
|
|||||||
2
src/lib
2
src/lib
Submodule src/lib updated: 45169f72f4...f5ca1c09d9
35
src/main.ts
35
src/main.ts
@@ -1302,7 +1302,7 @@ export default class ObsidianLiveSyncPlugin extends Plugin {
|
|||||||
}
|
}
|
||||||
this.app.vault.adapter.append(normalizePath(logDate), vaultName + ":" + newMessage + "\n");
|
this.app.vault.adapter.append(normalizePath(logDate), vaultName + ":" + newMessage + "\n");
|
||||||
}
|
}
|
||||||
logMessageStore.apply(e => [...e, newMessage].slice(-100));
|
logMessageStore.apply(e => [...e, newMessage].slice(this.settings.showVerboseLog ? -1000 : -100));
|
||||||
this.setStatusBarText(null, messageContent);
|
this.setStatusBarText(null, messageContent);
|
||||||
|
|
||||||
if (level >= LOG_LEVEL.NOTICE) {
|
if (level >= LOG_LEVEL.NOTICE) {
|
||||||
@@ -1571,9 +1571,10 @@ export default class ObsidianLiveSyncPlugin extends Plugin {
|
|||||||
const filename = id2path(id2filenameInternalMetadata(queue.entry._id));
|
const filename = id2path(id2filenameInternalMetadata(queue.entry._id));
|
||||||
// await this.syncInternalFilesAndDatabase("pull", false, false, [filename])
|
// await this.syncInternalFilesAndDatabase("pull", false, false, [filename])
|
||||||
this.procInternalFile(filename);
|
this.procInternalFile(filename);
|
||||||
}
|
} else if (isValidPath(id2path(queue.entry._id))) {
|
||||||
if (isValidPath(id2path(queue.entry._id))) {
|
|
||||||
this.handleDBChanged(queue.entry);
|
this.handleDBChanged(queue.entry);
|
||||||
|
} else {
|
||||||
|
Logger(`Skipped: ${queue.entry._id}`, LOG_LEVEL.VERBOSE);
|
||||||
}
|
}
|
||||||
} else if (now > queue.timeout) {
|
} else if (now > queue.timeout) {
|
||||||
if (!queue.warned) Logger(`Timed out: ${queue.entry._id} could not collect ${queue.missingChildren.length} chunks. plugin keeps watching, but you have to check the file after the replication.`, LOG_LEVEL.NOTICE);
|
if (!queue.warned) Logger(`Timed out: ${queue.entry._id} could not collect ${queue.missingChildren.length} chunks. plugin keeps watching, but you have to check the file after the replication.`, LOG_LEVEL.NOTICE);
|
||||||
@@ -1983,12 +1984,13 @@ export default class ObsidianLiveSyncPlugin extends Plugin {
|
|||||||
const filesStorageName = filesStorage.map((e) => e.path);
|
const filesStorageName = filesStorage.map((e) => e.path);
|
||||||
Logger("Collecting local files on the DB", LOG_LEVEL.VERBOSE);
|
Logger("Collecting local files on the DB", LOG_LEVEL.VERBOSE);
|
||||||
const filesDatabase = [] as string[]
|
const filesDatabase = [] as string[]
|
||||||
for await (const doc of this.localDatabase.findAllDocs()) {
|
for await (const docId of this.localDatabase.findAllDocNames()) {
|
||||||
const path = id2path(doc._id);
|
const path = id2path(docId);
|
||||||
if (isValidPath(doc._id) && this.isTargetFile(path)) {
|
if (isValidPath(docId) && this.isTargetFile(path)) {
|
||||||
filesDatabase.push(path);
|
filesDatabase.push(path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger("Opening the key-value database", LOG_LEVEL.VERBOSE);
|
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.
|
||||||
@@ -2006,28 +2008,14 @@ export default class ObsidianLiveSyncPlugin extends Plugin {
|
|||||||
this.setStatusBarText(`UPDATE DATABASE`);
|
this.setStatusBarText(`UPDATE DATABASE`);
|
||||||
|
|
||||||
const runAll = async<T>(procedureName: string, objects: T[], callback: (arg: T) => Promise<void>) => {
|
const runAll = async<T>(procedureName: string, objects: T[], callback: (arg: T) => Promise<void>) => {
|
||||||
// const count = objects.length;
|
|
||||||
Logger(procedureName);
|
Logger(procedureName);
|
||||||
// let i = 0;
|
|
||||||
const semaphore = Semaphore(25);
|
const semaphore = Semaphore(25);
|
||||||
|
|
||||||
// Logger(`${procedureName} exec.`);
|
|
||||||
if (!this.localDatabase.isReady) throw Error("Database is not ready!");
|
if (!this.localDatabase.isReady) throw Error("Database is not ready!");
|
||||||
const processes = objects.map(e => (async (v) => {
|
const processes = objects.map(e => (async (v) => {
|
||||||
const releaser = await semaphore.acquire(1, procedureName);
|
const releaser = await semaphore.acquire(1, procedureName);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await callback(v);
|
await callback(v);
|
||||||
// i++;
|
|
||||||
// if (i % 50 == 0) {
|
|
||||||
// const notify = `${procedureName} : ${i}/${count}`;
|
|
||||||
// if (showingNotice) {
|
|
||||||
// Logger(notify, LOG_LEVEL.NOTICE, "syncAll");
|
|
||||||
// } else {
|
|
||||||
// Logger(notify);
|
|
||||||
// }
|
|
||||||
// this.setStatusBarText(notify);
|
|
||||||
// }
|
|
||||||
} catch (ex) {
|
} catch (ex) {
|
||||||
Logger(`Error while ${procedureName}`, LOG_LEVEL.NOTICE);
|
Logger(`Error while ${procedureName}`, LOG_LEVEL.NOTICE);
|
||||||
Logger(ex);
|
Logger(ex);
|
||||||
@@ -2067,7 +2055,6 @@ export default class ObsidianLiveSyncPlugin extends Plugin {
|
|||||||
const syncFilesX = syncFiles.splice(0, 100);
|
const syncFilesX = syncFiles.splice(0, 100);
|
||||||
const docs = await this.localDatabase.localDatabase.allDocs({ keys: syncFilesX.map(e => path2id(e.path)), include_docs: true })
|
const docs = await this.localDatabase.localDatabase.allDocs({ keys: syncFilesX.map(e => path2id(e.path)), include_docs: true })
|
||||||
const syncFilesToSync = syncFilesX.map((e) => ({ file: e, doc: docs.rows.find(ee => ee.id == path2id(e.path)).doc as LoadedEntry }));
|
const syncFilesToSync = syncFilesX.map((e) => ({ file: e, doc: docs.rows.find(ee => ee.id == path2id(e.path)).doc as LoadedEntry }));
|
||||||
|
|
||||||
await runAll(`CHECK FILE STATUS:${syncFiles.length}/${docsCount}`, syncFilesToSync, async (e) => {
|
await runAll(`CHECK FILE STATUS:${syncFiles.length}/${docsCount}`, syncFilesToSync, async (e) => {
|
||||||
caches = await this.syncFileBetweenDBandStorage(e.file, e.doc, initialScan, caches);
|
caches = await this.syncFileBetweenDBandStorage(e.file, e.doc, initialScan, caches);
|
||||||
});
|
});
|
||||||
@@ -2674,6 +2661,7 @@ export default class ObsidianLiveSyncPlugin extends Plugin {
|
|||||||
const dK = `${file.path}-diff`;
|
const dK = `${file.path}-diff`;
|
||||||
const isLastDiff = dK in caches ? caches[dK] : { storageMtime: 0, docMtime: 0 };
|
const isLastDiff = dK in caches ? caches[dK] : { storageMtime: 0, docMtime: 0 };
|
||||||
if (isLastDiff.docMtime == docMtime && isLastDiff.storageMtime == storageMtime) {
|
if (isLastDiff.docMtime == docMtime && isLastDiff.storageMtime == storageMtime) {
|
||||||
|
Logger("STORAGE .. DB :" + file.path, LOG_LEVEL.VERBOSE);
|
||||||
caches[dK] = { storageMtime, docMtime };
|
caches[dK] = { storageMtime, docMtime };
|
||||||
return caches;
|
return caches;
|
||||||
}
|
}
|
||||||
@@ -2696,11 +2684,8 @@ export default class ObsidianLiveSyncPlugin extends Plugin {
|
|||||||
}
|
}
|
||||||
caches[dK] = { storageMtime, docMtime };
|
caches[dK] = { storageMtime, docMtime };
|
||||||
return caches;
|
return caches;
|
||||||
} else {
|
|
||||||
// Logger("EVEN :" + file.path, LOG_LEVEL.VERBOSE);
|
|
||||||
// Logger(`${storageMtime} = ${docMtime}`, LOG_LEVEL.VERBOSE);
|
|
||||||
//eq.case
|
|
||||||
}
|
}
|
||||||
|
Logger("STORAGE == DB :" + file.path + "", LOG_LEVEL.VERBOSE);
|
||||||
caches[dK] = { storageMtime, docMtime };
|
caches[dK] = { storageMtime, docMtime };
|
||||||
return caches;
|
return caches;
|
||||||
|
|
||||||
|
|||||||
11
updates.md
11
updates.md
@@ -82,5 +82,14 @@
|
|||||||
- Opening the local database multiple times in a short duration has been suppressed.
|
- Opening the local database multiple times in a short duration has been suppressed.
|
||||||
- Older migration logic.
|
- 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.
|
- 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.
|
||||||
|
- 0.17.29
|
||||||
|
- Fixed:
|
||||||
|
- Requests of reading chunks online are now split into a reasonable(and configurable) size.
|
||||||
|
- No longer error message will be shown on Linux devices with hidden file synchronisation.
|
||||||
|
- Improved:
|
||||||
|
- The interval of reading chunks online is now configurable.
|
||||||
|
- Boot sequence has been speeded up, more.
|
||||||
|
- Misc:
|
||||||
|
- Messages on the boot sequence will now be more detailed. If you want to see them, please enable the verbose log.
|
||||||
|
- Logs became be kept for 1000 lines while the verbose log is enabled.
|
||||||
... To continue on to `updates_old.md`.
|
... To continue on to `updates_old.md`.
|
||||||
Reference in New Issue
Block a user