mirror of
https://github.com/vrtmrz/obsidian-livesync.git
synced 2025-12-13 09:45:56 +00:00
Modified:
- Plugins and settings is now in beta. Implemented: - Show the count of the pending processes into the status.
This commit is contained in:
@@ -75,6 +75,8 @@ Synchronization status is shown in statusbar.
|
|||||||
- ⚠ Error occurred.
|
- ⚠ Error occurred.
|
||||||
- ↑ Uploaded pieces
|
- ↑ Uploaded pieces
|
||||||
- ↓ Downloaded pieces
|
- ↓ Downloaded pieces
|
||||||
|
- ⏳ Count of the pending process
|
||||||
|
If you have deleted or renamed files, please wait until this disappears.
|
||||||
|
|
||||||
# More supplements
|
# More supplements
|
||||||
|
|
||||||
|
|||||||
@@ -78,6 +78,8 @@ Self-hosted LiveSync用にWebClipperも作りました。Chrome Web Storeから
|
|||||||
- ⚠ エラーが発生しています
|
- ⚠ エラーが発生しています
|
||||||
- ↑ 送信したデータ数
|
- ↑ 送信したデータ数
|
||||||
- ↓ 受信したデータ数
|
- ↓ 受信したデータ数
|
||||||
|
- ⏳ 保留している処理の数です
|
||||||
|
ファイルを削除したりリネームした場合、この表示が消えるまでお待ちください。
|
||||||
|
|
||||||
# さらなる補足
|
# さらなる補足
|
||||||
- ファイルは同期された後、タイムスタンプを比較して新しければいったん新しい方で上書きされます。その後、衝突が発生したかによって、マージが行われます。
|
- ファイルは同期された後、タイムスタンプを比較して新しければいったん新しい方で上書きされます。その後、衝突が発生したかによって、マージが行われます。
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"id": "obsidian-livesync",
|
"id": "obsidian-livesync",
|
||||||
"name": "Self-hosted LiveSync",
|
"name": "Self-hosted LiveSync",
|
||||||
"version": "0.4.1",
|
"version": "0.5.0",
|
||||||
"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.4.1",
|
"version": "0.5.0",
|
||||||
"lockfileVersion": 2,
|
"lockfileVersion": 2,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "obsidian-livesync",
|
"name": "obsidian-livesync",
|
||||||
"version": "0.4.1",
|
"version": "0.5.0",
|
||||||
"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.4.1",
|
"version": "0.5.0",
|
||||||
"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",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
@@ -811,7 +811,7 @@ export class ObsidianLiveSyncSettingTab extends PluginSettingTab {
|
|||||||
// With great respect, thank you TfTHacker!
|
// With great respect, thank you TfTHacker!
|
||||||
// refered: https://github.com/TfTHacker/obsidian42-brat/blob/main/src/features/BetaPlugins.ts
|
// refered: https://github.com/TfTHacker/obsidian42-brat/blob/main/src/features/BetaPlugins.ts
|
||||||
const containerPluginSettings = containerEl.createDiv();
|
const containerPluginSettings = containerEl.createDiv();
|
||||||
containerPluginSettings.createEl("h3", { text: "Plugins and settings (bleeding edge)" });
|
containerPluginSettings.createEl("h3", { text: "Plugins and settings (beta)" });
|
||||||
|
|
||||||
const updateDisabledOfDeviceAndVaultName = () => {
|
const updateDisabledOfDeviceAndVaultName = () => {
|
||||||
vaultName.setDisabled(this.plugin.settings.autoSweepPlugins || this.plugin.settings.autoSweepPluginsPeriodic);
|
vaultName.setDisabled(this.plugin.settings.autoSweepPlugins || this.plugin.settings.autoSweepPluginsPeriodic);
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ import {
|
|||||||
diff_result,
|
diff_result,
|
||||||
FLAGMD_REDFLAG,
|
FLAGMD_REDFLAG,
|
||||||
} from "./types";
|
} from "./types";
|
||||||
import { base64ToString, arrayBufferToBase64, base64ToArrayBuffer, isValidPath, versionNumberString2Number, id2path, path2id, runWithLock, shouldBeIgnored } from "./utils";
|
import { base64ToString, arrayBufferToBase64, base64ToArrayBuffer, isValidPath, versionNumberString2Number, id2path, path2id, runWithLock, shouldBeIgnored, getProcessingCounts, setLockNotifier } from "./utils";
|
||||||
import { Logger, setLogger } from "./logger";
|
import { Logger, setLogger } from "./logger";
|
||||||
import { LocalPouchDB } from "./LocalPouchDB";
|
import { LocalPouchDB } from "./LocalPouchDB";
|
||||||
import { LogDisplayModal } from "./LogDisplayModal";
|
import { LogDisplayModal } from "./LogDisplayModal";
|
||||||
@@ -205,6 +205,9 @@ export default class ObsidianLiveSyncPlugin extends Plugin {
|
|||||||
});
|
});
|
||||||
this.triggerRealizeSettingSyncMode = debounce(this.triggerRealizeSettingSyncMode.bind(this), 1000);
|
this.triggerRealizeSettingSyncMode = debounce(this.triggerRealizeSettingSyncMode.bind(this), 1000);
|
||||||
this.triggerCheckPluginUpdate = debounce(this.triggerCheckPluginUpdate.bind(this), 3000);
|
this.triggerCheckPluginUpdate = debounce(this.triggerCheckPluginUpdate.bind(this), 3000);
|
||||||
|
setLockNotifier(() => {
|
||||||
|
this.refreshStatusText();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
onunload() {
|
onunload() {
|
||||||
this.localDatabase.onunload();
|
this.localDatabase.onunload();
|
||||||
@@ -787,7 +790,9 @@ export default class ObsidianLiveSyncPlugin extends Plugin {
|
|||||||
waiting = " " + this.batchFileChange.map((e) => "🛫").join("");
|
waiting = " " + this.batchFileChange.map((e) => "🛫").join("");
|
||||||
waiting = waiting.replace(/(🛫){10}/g, "🚀");
|
waiting = waiting.replace(/(🛫){10}/g, "🚀");
|
||||||
}
|
}
|
||||||
const message = `Sync:${w} ↑${sent} ↓${arrived}${waiting}`;
|
const procs = getProcessingCounts();
|
||||||
|
const procsDisp = procs==0?"":` ⏳${procs}`;
|
||||||
|
const message = `Sync:${w} ↑${sent} ↓${arrived}${waiting}${procsDisp}`;
|
||||||
this.setStatusBarText(message);
|
this.setStatusBarText(message);
|
||||||
}
|
}
|
||||||
setStatusBarText(message: string) {
|
setStatusBarText(message: string) {
|
||||||
|
|||||||
27
src/utils.ts
27
src/utils.ts
@@ -121,7 +121,28 @@ function objectToKey(key: any): string {
|
|||||||
const keys = Object.keys(key).sort((a, b) => a.localeCompare(b));
|
const keys = Object.keys(key).sort((a, b) => a.localeCompare(b));
|
||||||
return keys.map((e) => e + objectToKey(key[e])).join(":");
|
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
|
// Just run async/await as like transacion ISOLATION SERIALIZABLE
|
||||||
export function runWithLock<T>(key: unknown, ignoreWhenRunning: boolean, proc: () => Promise<T>): Promise<T> {
|
export function runWithLock<T>(key: unknown, ignoreWhenRunning: boolean, proc: () => Promise<T>): Promise<T> {
|
||||||
// Logger(`Lock:${key}:enter`, LOG_LEVEL.VERBOSE);
|
// Logger(`Lock:${key}:enter`, LOG_LEVEL.VERBOSE);
|
||||||
@@ -130,11 +151,13 @@ export function runWithLock<T>(key: unknown, ignoreWhenRunning: boolean, proc: (
|
|||||||
if (typeof pendingProcs[lockKey] === "undefined") {
|
if (typeof pendingProcs[lockKey] === "undefined") {
|
||||||
//simply unlock
|
//simply unlock
|
||||||
runningProcs.remove(lockKey);
|
runningProcs.remove(lockKey);
|
||||||
|
notifyLock();
|
||||||
// Logger(`Lock:${lockKey}:released`, LOG_LEVEL.VERBOSE);
|
// Logger(`Lock:${lockKey}:released`, LOG_LEVEL.VERBOSE);
|
||||||
} else {
|
} else {
|
||||||
Logger(`Lock:${lockKey}:left ${pendingProcs[lockKey].length}`, LOG_LEVEL.VERBOSE);
|
Logger(`Lock:${lockKey}:left ${pendingProcs[lockKey].length}`, LOG_LEVEL.VERBOSE);
|
||||||
let nextProc = null;
|
let nextProc = null;
|
||||||
nextProc = pendingProcs[lockKey].shift();
|
nextProc = pendingProcs[lockKey].shift();
|
||||||
|
notifyLock();
|
||||||
if (nextProc) {
|
if (nextProc) {
|
||||||
// left some
|
// left some
|
||||||
nextProc()
|
nextProc()
|
||||||
@@ -145,6 +168,7 @@ export function runWithLock<T>(key: unknown, ignoreWhenRunning: boolean, proc: (
|
|||||||
.finally(() => {
|
.finally(() => {
|
||||||
if (pendingProcs && lockKey in pendingProcs && pendingProcs[lockKey].length == 0) {
|
if (pendingProcs && lockKey in pendingProcs && pendingProcs[lockKey].length == 0) {
|
||||||
delete pendingProcs[lockKey];
|
delete pendingProcs[lockKey];
|
||||||
|
notifyLock();
|
||||||
}
|
}
|
||||||
queueMicrotask(() => {
|
queueMicrotask(() => {
|
||||||
handleNextProcs();
|
handleNextProcs();
|
||||||
@@ -153,6 +177,7 @@ export function runWithLock<T>(key: unknown, ignoreWhenRunning: boolean, proc: (
|
|||||||
} else {
|
} else {
|
||||||
if (pendingProcs && lockKey in pendingProcs && pendingProcs[lockKey].length == 0) {
|
if (pendingProcs && lockKey in pendingProcs && pendingProcs[lockKey].length == 0) {
|
||||||
delete pendingProcs[lockKey];
|
delete pendingProcs[lockKey];
|
||||||
|
notifyLock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -189,10 +214,12 @@ export function runWithLock<T>(key: unknown, ignoreWhenRunning: boolean, proc: (
|
|||||||
});
|
});
|
||||||
|
|
||||||
pendingProcs[lockKey].push(subproc);
|
pendingProcs[lockKey].push(subproc);
|
||||||
|
notifyLock();
|
||||||
// Logger(`Lock:${lockKey}:queud:left${pendingProcs[lockKey].length}`, LOG_LEVEL.VERBOSE);
|
// Logger(`Lock:${lockKey}:queud:left${pendingProcs[lockKey].length}`, LOG_LEVEL.VERBOSE);
|
||||||
return responder;
|
return responder;
|
||||||
} else {
|
} else {
|
||||||
runningProcs.push(lockKey);
|
runningProcs.push(lockKey);
|
||||||
|
notifyLock();
|
||||||
// Logger(`Lock:${lockKey}:aqquired`, LOG_LEVEL.VERBOSE);
|
// Logger(`Lock:${lockKey}:aqquired`, LOG_LEVEL.VERBOSE);
|
||||||
return new Promise((res, rej) => {
|
return new Promise((res, rej) => {
|
||||||
proc()
|
proc()
|
||||||
|
|||||||
Reference in New Issue
Block a user