diff --git a/package-lock.json b/package-lock.json index ff9eecb..5667b13 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,13 +10,13 @@ "license": "MIT", "dependencies": { "diff-match-patch": "^1.0.5", - "esbuild": "0.15.15", - "esbuild-svelte": "^0.7.3", "idb": "^7.1.1", "xxhash-wasm": "^0.4.2" }, "devDependencies": { + "@tsconfig/svelte": "^4.0.1", "@types/diff-match-patch": "^1.0.32", + "@types/node": "^20.2.5", "@types/pouchdb": "^6.4.0", "@types/pouchdb-browser": "^6.1.3", "@typescript-eslint/eslint-plugin": "^5.54.0", @@ -39,11 +39,11 @@ "pouchdb-mapreduce": "^8.0.1", "pouchdb-replication": "^8.0.1", "pouchdb-utils": "^8.0.1", - "svelte": "^3.55.1", - "svelte-preprocess": "^5.0.1", + "svelte": "^3.59.1", + "svelte-preprocess": "^5.0.3", "transform-pouch": "^2.0.0", "tslib": "^2.5.0", - "typescript": "^4.9.5" + "typescript": "^5.0.4" } }, "node_modules/@codemirror/state": { @@ -203,6 +203,12 @@ "node": ">= 8" } }, + "node_modules/@tsconfig/svelte": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@tsconfig/svelte/-/svelte-4.0.1.tgz", + "integrity": "sha512-B+XlGpmuAQzJqDoBATNCvEPqQg0HkO7S8pM14QDI5NsmtymzRexQ1N+nX2H6RTtFbuFgaZD4I8AAi8voGg0GLg==", + "dev": true + }, "node_modules/@types/codemirror": { "version": "0.0.108", "resolved": "https://registry.npmjs.org/@types/codemirror/-/codemirror-0.0.108.tgz", @@ -252,9 +258,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "14.17.21", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.17.21.tgz", - "integrity": "sha512-zv8ukKci1mrILYiQOwGSV4FpkZhyxQtuFWGya2GujWg+zVAeRQ4qbaMmWp9vb9889CFA8JECH7lkwCL6Ygg8kA==", + "version": "20.2.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.2.5.tgz", + "integrity": "sha512-JJulVEQXmiY9Px5axXHeYGLSjhkZEnD+MDPDGbCbIAbMslkKwmygtZFy1X6s/075Yo94sf8GuSlFfPzysQrWZQ==", "dev": true }, "node_modules/@types/pouchdb": { @@ -443,15 +449,6 @@ "integrity": "sha512-SnHmG9wN1UVmagJOnyo/qkk0Z7gejYxOYYmaAwr5u2yFYfsupN3sg10kyzN8Hep/2zbHxCnsumxOoRIRMBwKCg==", "dev": true }, - "node_modules/@types/sass": { - "version": "1.43.1", - "resolved": "https://registry.npmjs.org/@types/sass/-/sass-1.43.1.tgz", - "integrity": "sha512-BPdoIt1lfJ6B7rw35ncdwBZrAssjcwzI5LByIrYs+tpXlj/CAkuVdRsgZDdP4lq5EjyWzwxZCqAoFyHKFwp32g==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, "node_modules/@types/semver": { "version": "7.3.13", "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.13.tgz", @@ -3719,23 +3716,22 @@ } }, "node_modules/svelte": { - "version": "3.55.1", - "resolved": "https://registry.npmjs.org/svelte/-/svelte-3.55.1.tgz", - "integrity": "sha512-S+87/P0Ve67HxKkEV23iCdAh/SX1xiSfjF1HOglno/YTbSTW7RniICMCofWGdJJbdjw3S+0PfFb1JtGfTXE0oQ==", + "version": "3.59.1", + "resolved": "https://registry.npmjs.org/svelte/-/svelte-3.59.1.tgz", + "integrity": "sha512-pKj8fEBmqf6mq3/NfrB9SLtcJcUvjYSWyePlfCqN9gujLB25RitWK8PvFzlwim6hD/We35KbPlRteuA6rnPGcQ==", "dev": true, "engines": { "node": ">= 8" } }, "node_modules/svelte-preprocess": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/svelte-preprocess/-/svelte-preprocess-5.0.1.tgz", - "integrity": "sha512-0HXyhCoc9rsW4zGOgtInylC6qj259E1hpFnJMJWTf+aIfeqh4O/QHT31KT2hvPEqQfdjmqBR/kO2JDkkciBLrQ==", + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/svelte-preprocess/-/svelte-preprocess-5.0.4.tgz", + "integrity": "sha512-ABia2QegosxOGsVlsSBJvoWeXy1wUKSfF7SWJdTjLAbx/Y3SrVevvvbFNQqrSJw89+lNSsM58SipmZJ5SRi5iw==", "dev": true, "hasInstallScript": true, "dependencies": { "@types/pug": "^2.0.6", - "@types/sass": "^1.43.1", "detect-indent": "^6.1.0", "magic-string": "^0.27.0", "sorcery": "^0.11.0", @@ -3754,8 +3750,8 @@ "sass": "^1.26.8", "stylus": "^0.55.0", "sugarss": "^2.0.0 || ^3.0.0 || ^4.0.0", - "svelte": "^3.23.0", - "typescript": "^3.9.5 || ^4.0.0" + "svelte": "^3.23.0 || ^4.0.0-next.0 || ^4.0.0", + "typescript": ">=3.9.5 || ^4.0.0 || ^5.0.0" }, "peerDependenciesMeta": { "@babel/core": { @@ -3916,16 +3912,16 @@ } }, "node_modules/typescript": { - "version": "4.9.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", - "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.0.4.tgz", + "integrity": "sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw==", "dev": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" }, "engines": { - "node": ">=4.2.0" + "node": ">=12.20" } }, "node_modules/unbox-primitive": { @@ -4233,6 +4229,12 @@ "fastq": "^1.6.0" } }, + "@tsconfig/svelte": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@tsconfig/svelte/-/svelte-4.0.1.tgz", + "integrity": "sha512-B+XlGpmuAQzJqDoBATNCvEPqQg0HkO7S8pM14QDI5NsmtymzRexQ1N+nX2H6RTtFbuFgaZD4I8AAi8voGg0GLg==", + "dev": true + }, "@types/codemirror": { "version": "0.0.108", "resolved": "https://registry.npmjs.org/@types/codemirror/-/codemirror-0.0.108.tgz", @@ -4282,9 +4284,9 @@ "dev": true }, "@types/node": { - "version": "14.17.21", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.17.21.tgz", - "integrity": "sha512-zv8ukKci1mrILYiQOwGSV4FpkZhyxQtuFWGya2GujWg+zVAeRQ4qbaMmWp9vb9889CFA8JECH7lkwCL6Ygg8kA==", + "version": "20.2.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.2.5.tgz", + "integrity": "sha512-JJulVEQXmiY9Px5axXHeYGLSjhkZEnD+MDPDGbCbIAbMslkKwmygtZFy1X6s/075Yo94sf8GuSlFfPzysQrWZQ==", "dev": true }, "@types/pouchdb": { @@ -4473,15 +4475,6 @@ "integrity": "sha512-SnHmG9wN1UVmagJOnyo/qkk0Z7gejYxOYYmaAwr5u2yFYfsupN3sg10kyzN8Hep/2zbHxCnsumxOoRIRMBwKCg==", "dev": true }, - "@types/sass": { - "version": "1.43.1", - "resolved": "https://registry.npmjs.org/@types/sass/-/sass-1.43.1.tgz", - "integrity": "sha512-BPdoIt1lfJ6B7rw35ncdwBZrAssjcwzI5LByIrYs+tpXlj/CAkuVdRsgZDdP4lq5EjyWzwxZCqAoFyHKFwp32g==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, "@types/semver": { "version": "7.3.13", "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.13.tgz", @@ -6787,19 +6780,18 @@ "dev": true }, "svelte": { - "version": "3.55.1", - "resolved": "https://registry.npmjs.org/svelte/-/svelte-3.55.1.tgz", - "integrity": "sha512-S+87/P0Ve67HxKkEV23iCdAh/SX1xiSfjF1HOglno/YTbSTW7RniICMCofWGdJJbdjw3S+0PfFb1JtGfTXE0oQ==", + "version": "3.59.1", + "resolved": "https://registry.npmjs.org/svelte/-/svelte-3.59.1.tgz", + "integrity": "sha512-pKj8fEBmqf6mq3/NfrB9SLtcJcUvjYSWyePlfCqN9gujLB25RitWK8PvFzlwim6hD/We35KbPlRteuA6rnPGcQ==", "dev": true }, "svelte-preprocess": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/svelte-preprocess/-/svelte-preprocess-5.0.1.tgz", - "integrity": "sha512-0HXyhCoc9rsW4zGOgtInylC6qj259E1hpFnJMJWTf+aIfeqh4O/QHT31KT2hvPEqQfdjmqBR/kO2JDkkciBLrQ==", + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/svelte-preprocess/-/svelte-preprocess-5.0.4.tgz", + "integrity": "sha512-ABia2QegosxOGsVlsSBJvoWeXy1wUKSfF7SWJdTjLAbx/Y3SrVevvvbFNQqrSJw89+lNSsM58SipmZJ5SRi5iw==", "dev": true, "requires": { "@types/pug": "^2.0.6", - "@types/sass": "^1.43.1", "detect-indent": "^6.1.0", "magic-string": "^0.27.0", "sorcery": "^0.11.0", @@ -6910,9 +6902,9 @@ } }, "typescript": { - "version": "4.9.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", - "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.0.4.tgz", + "integrity": "sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw==", "dev": true }, "unbox-primitive": { diff --git a/package.json b/package.json index 5069bd6..acceba8 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,9 @@ "author": "vorotamoroz", "license": "MIT", "devDependencies": { + "@tsconfig/svelte": "^4.0.1", "@types/diff-match-patch": "^1.0.32", + "@types/node": "^20.2.5", "@types/pouchdb": "^6.4.0", "@types/pouchdb-browser": "^6.1.3", "@typescript-eslint/eslint-plugin": "^5.54.0", @@ -36,17 +38,15 @@ "pouchdb-mapreduce": "^8.0.1", "pouchdb-replication": "^8.0.1", "pouchdb-utils": "^8.0.1", - "svelte": "^3.55.1", - "svelte-preprocess": "^5.0.1", + "svelte": "^3.59.1", + "svelte-preprocess": "^5.0.3", "transform-pouch": "^2.0.0", "tslib": "^2.5.0", - "typescript": "^4.9.5" + "typescript": "^5.0.4" }, "dependencies": { "diff-match-patch": "^1.0.5", - "esbuild": "0.15.15", - "esbuild-svelte": "^0.7.3", "idb": "^7.1.1", "xxhash-wasm": "^0.4.2" } -} \ No newline at end of file +} diff --git a/src/CmdSetupLiveSync.ts b/src/CmdSetupLiveSync.ts index 4bcfdc5..9243eda 100644 --- a/src/CmdSetupLiveSync.ts +++ b/src/CmdSetupLiveSync.ts @@ -1,4 +1,4 @@ -import { EntryDoc, ObsidianLiveSyncSettings, LOG_LEVEL, DEFAULT_SETTINGS } from "./lib/src/types"; +import { type EntryDoc, type ObsidianLiveSyncSettings, LOG_LEVEL, DEFAULT_SETTINGS } from "./lib/src/types"; import { configURIBase } from "./types"; import { Logger } from "./lib/src/logger"; import { PouchDB } from "./lib/src/pouchdb-browser.js"; @@ -284,8 +284,22 @@ Of course, we are able to disable these features.` this.plugin.settings.syncAfterMerge = false; //this.suspendExtraSync(); } + async askUseNewAdapter() { + if (!this.plugin.settings.useIndexedDBAdapter) { + const message = `Now this plugin has been configured to use the old database adapter for keeping compatibility. Do you want to deactivate it?`; + const CHOICE_YES = "Yes, disable and use latest"; + const CHOICE_NO = "No, keep compatibility"; + const choices = [CHOICE_YES, CHOICE_NO]; + + const ret = await confirmWithMessage(this.plugin, "Database adapter", message, choices, CHOICE_YES, 10); + if (ret == CHOICE_YES) { + this.plugin.settings.useIndexedDBAdapter = false; + } + } + } async fetchLocal() { this.suspendExtraSync(); + this.askUseNewAdapter(); await this.plugin.realizeSettingSyncMode(); await this.plugin.resetLocalDatabase(); await delay(1000); @@ -313,6 +327,7 @@ Of course, we are able to disable these features.` } async rebuildEverything() { this.suspendExtraSync(); + this.askUseNewAdapter(); await this.plugin.realizeSettingSyncMode(); await this.plugin.resetLocalDatabase(); await delay(1000); diff --git a/src/StorageEventManager.ts b/src/StorageEventManager.ts index cef04d4..a99f0ac 100644 --- a/src/StorageEventManager.ts +++ b/src/StorageEventManager.ts @@ -112,7 +112,7 @@ export class StorageEventManagerObsidian extends StorageEventManager { } - if (this.plugin.settings.batchSave) { + if (this.plugin.settings.batchSave && !this.plugin.settings.liveSync) { // if the latest event is the same type, omit that // a.md MODIFY <- this should be cancelled when a.md MODIFIED // b.md MODIFY <- this should be cancelled when b.md MODIFIED diff --git a/src/lib b/src/lib index ec4ecac..63fa007 160000 --- a/src/lib +++ b/src/lib @@ -1 +1 @@ -Subproject commit ec4ecacb43d4c12902f4ef9c52f43b1ce122e19e +Subproject commit 63fa0074fe5bf2d45e9132885040ffbebade8e09 diff --git a/src/main.ts b/src/main.ts index bca0275..ef2c895 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,9 +1,9 @@ const isDebug = false; -import { Diff, DIFF_DELETE, DIFF_EQUAL, DIFF_INSERT, diff_match_patch } from "diff-match-patch"; -import { debounce, Notice, Plugin, TFile, addIcon, TFolder, normalizePath, TAbstractFile, Editor, MarkdownView, RequestUrlParam, RequestUrlResponse, requestUrl } from "./deps"; -import { EntryDoc, LoadedEntry, ObsidianLiveSyncSettings, diff_check_result, diff_result_leaf, EntryBody, LOG_LEVEL, VER, DEFAULT_SETTINGS, diff_result, FLAGMD_REDFLAG, SYNCINFO_ID, SALT_OF_PASSPHRASE, ConfigPassphraseStore, CouchDBConnection, FLAGMD_REDFLAG2, FLAGMD_REDFLAG3, PREFIXMD_LOGFILE, DatabaseConnectingStatus, EntryHasPath, DocumentID, FilePathWithPrefix, FilePath, AnyEntry } from "./lib/src/types"; -import { InternalFileInfo, queueItem, CacheData, FileEventItem, FileWatchEventQueueMax } from "./types"; +import { type Diff, DIFF_DELETE, DIFF_EQUAL, DIFF_INSERT, diff_match_patch } from "diff-match-patch"; +import { debounce, Notice, Plugin, TFile, addIcon, TFolder, normalizePath, TAbstractFile, Editor, MarkdownView, type RequestUrlParam, type RequestUrlResponse, requestUrl } from "./deps"; +import { type EntryDoc, type LoadedEntry, type ObsidianLiveSyncSettings, type diff_check_result, type diff_result_leaf, type EntryBody, LOG_LEVEL, VER, DEFAULT_SETTINGS, type diff_result, FLAGMD_REDFLAG, SYNCINFO_ID, SALT_OF_PASSPHRASE, type ConfigPassphraseStore, type CouchDBConnection, FLAGMD_REDFLAG2, FLAGMD_REDFLAG3, PREFIXMD_LOGFILE, type DatabaseConnectingStatus, type EntryHasPath, type DocumentID, type FilePathWithPrefix, type FilePath, type AnyEntry } from "./lib/src/types"; +import { type InternalFileInfo, type queueItem, type CacheData, type FileEventItem, FileWatchEventQueueMax } from "./types"; import { getDocData, isDocContentSame, Parallels } from "./lib/src/utils"; import { Logger } from "./lib/src/logger"; import { PouchDB } from "./lib/src/pouchdb-browser.js"; @@ -22,9 +22,9 @@ import { addPrefix, isPlainText, shouldBeIgnored, stripAllPrefixes } from "./lib import { runWithLock } from "./lib/src/lock"; import { Semaphore } from "./lib/src/semaphore"; import { StorageEventManager, StorageEventManagerObsidian } from "./StorageEventManager"; -import { LiveSyncLocalDB, LiveSyncLocalDBEnv } from "./lib/src/LiveSyncLocalDB"; -import { LiveSyncDBReplicator, LiveSyncReplicatorEnv } from "./lib/src/LiveSyncReplicator"; -import { KeyValueDatabase, OpenKeyValueDatabase } from "./KeyValueDB"; +import { LiveSyncLocalDB, type LiveSyncLocalDBEnv } from "./lib/src/LiveSyncLocalDB"; +import { LiveSyncDBReplicator, type LiveSyncReplicatorEnv } from "./lib/src/LiveSyncReplicator"; +import { type KeyValueDatabase, OpenKeyValueDatabase } from "./KeyValueDB"; import { LiveSyncCommands } from "./LiveSyncCommands"; import { HiddenFileSync } from "./CmdHiddenFileSync"; import { SetupLiveSync } from "./CmdSetupLiveSync"; @@ -194,7 +194,7 @@ export default class ObsidianLiveSyncPlugin extends Plugin enableEncryption(db, passphrase, useDynamicIterationCount); } if (skipInfo) { - return { db: db, info: {} }; + return { db: db, info: { db_name: "", doc_count: 0, update_seq: "" } }; } try { const info = await db.info(); @@ -882,7 +882,7 @@ export default class ObsidianLiveSyncPlugin extends Plugin async procFileEvent(applyBatch?: boolean) { if (!this.isReady) return; - if (this.settings.batchSave) { + if (this.settings.batchSave && !this.settings.liveSync) { if (!applyBatch && this.vaultManager.getQueueLength() < FileWatchEventQueueMax) { // Defer till applying batch save or queue has been grown enough. // or 30 seconds after. @@ -968,7 +968,7 @@ export default class ObsidianLiveSyncPlugin extends Plugin } async applyBatchChange() { - if (this.settings.batchSave) { + if (this.settings.batchSave && !this.settings.liveSync) { return await this.procFileEvent(true); } } @@ -1368,7 +1368,7 @@ export default class ObsidianLiveSyncPlugin extends Plugin // If `Read chunks online` is disabled, chunks should be transferred before here. // However, in some cases, chunks are after that. So, if missing chunks exist, we have to wait for them. if ((!this.settings.readChunksOnline) && "children" in doc) { - const c = await this.localDatabase.collectChunksWithCache(doc.children); + const c = await this.localDatabase.collectChunksWithCache(doc.children as DocumentID[]); const missing = c.filter((e) => e.chunk === false).map((e) => e.id); if (missing.length > 0) Logger(`${path} (${doc._id}, ${doc._rev}) Queued (waiting ${missing.length} items)`, LOG_LEVEL.VERBOSE); newQueue.missingChildren = missing; @@ -1470,9 +1470,11 @@ export default class ObsidianLiveSyncPlugin extends Plugin } this.statusBar.title = e.syncStatus; let waiting = ""; - if (this.settings.batchSave) { - waiting = " " + "🛫".repeat(this.vaultManager.getQueueLength()); - waiting = waiting.replace(/(🛫){10}/g, "🚀"); + if (this.settings.batchSave && !this.settings.liveSync) { + const len = this.vaultManager.getQueueLength(); + if (len != 0) { + waiting = ` 🛫${len}`; + } } let queued = ""; const queue = Object.entries(e.queuedItems).filter((e) => !e[1].warned); @@ -1480,7 +1482,7 @@ export default class ObsidianLiveSyncPlugin extends Plugin if (queuedCount) { const pieces = queue.map((e) => e[1].missingChildren).reduce((prev, cur) => prev + cur.length, 0); - queued = ` 🧩 ${queuedCount} (${pieces})`; + queued = ` 🧩${queuedCount} (${pieces})`; } const processes = e.count; const processesDisp = processes == 0 ? "" : ` ⏳${processes}`; @@ -1643,13 +1645,15 @@ Or if you are sure know what had been happened, we can unlock the database from const filesStorageName = filesStorage.map((e) => e.path); Logger("Collecting local files on the DB", LOG_LEVEL.VERBOSE); const filesDatabase = [] as FilePathWithPrefix[] + let count = 0; for await (const doc of this.localDatabase.findAllNormalDocs()) { + count++; + if (count % 25 == 0) Logger(`Collecting local files on the DB: ${count}`, showingNotice ? LOG_LEVEL.NOTICE : LOG_LEVEL.INFO, "syncAll"); const path = getPath(doc); if (isValidPath(path) && this.isTargetFile(path)) { filesDatabase.push(path); } } - Logger("Opening the key-value database", LOG_LEVEL.VERBOSE); const isInitialized = await (this.kvDB.get("initialized")) || false; // Make chunk bigger if it is the initial scan. There must be non-active docs. diff --git a/tsconfig.json b/tsconfig.json index ec8886b..79bca56 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,4 +1,6 @@ { + "extends": "@tsconfig/svelte/tsconfig.json", + "inlineSourceMap": true, "compilerOptions": { "baseUrl": ".", "module": "ESNext", @@ -6,6 +8,10 @@ "allowJs": true, "noImplicitAny": true, "moduleResolution": "node", + "types": [ + "svelte", + "node" + ], // "importsNotUsedAsValues": "error", "importHelpers": false, "alwaysStrict": true,