mirror of
https://github.com/vrtmrz/obsidian-livesync.git
synced 2026-02-28 15:08:47 +00:00
Compare commits
5 Commits
0.25.37
...
refactor_s
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b97756d0cf | ||
|
|
acf4bc3737 | ||
|
|
88838872e7 | ||
|
|
7d3827d335 | ||
|
|
92d3a0cfa2 |
33
.github/workflows/unit-ci.yml
vendored
Normal file
33
.github/workflows/unit-ci.yml
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
# Run Unit test without Harnesses
|
||||
name: unit-ci
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 30
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '24.x'
|
||||
cache: 'npm'
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm ci
|
||||
|
||||
- name: Install test dependencies (Playwright Chromium)
|
||||
run: npm run test:install-dependencies
|
||||
|
||||
- name: Run unit tests suite
|
||||
run: npm run test:unit
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"id": "obsidian-livesync",
|
||||
"name": "Self-hosted LiveSync",
|
||||
"version": "0.25.37",
|
||||
"version": "0.25.38",
|
||||
"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.",
|
||||
"author": "vorotamoroz",
|
||||
|
||||
4
package-lock.json
generated
4
package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "obsidian-livesync",
|
||||
"version": "0.25.37",
|
||||
"version": "0.25.38",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "obsidian-livesync",
|
||||
"version": "0.25.37",
|
||||
"version": "0.25.38",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@aws-sdk/client-s3": "^3.808.0",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "obsidian-livesync",
|
||||
"version": "0.25.37",
|
||||
"version": "0.25.38",
|
||||
"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",
|
||||
"type": "module",
|
||||
@@ -26,6 +26,8 @@
|
||||
"check": "npm run lint && npm run svelte-check",
|
||||
"unittest": "deno test -A --no-check --coverage=cov_profile --v8-flags=--expose-gc --trace-leaks ./src/",
|
||||
"test": "vitest run",
|
||||
"test:unit": "vitest run --config vitest.config.unit.ts",
|
||||
"test:unit:coverage": "vitest run --config vitest.config.unit.ts --coverage",
|
||||
"test:install-playwright": "npx playwright install chromium",
|
||||
"test:install-dependencies": "npm run test:install-playwright",
|
||||
"test:coverage": "vitest run --coverage",
|
||||
|
||||
@@ -3,7 +3,9 @@ import type { KeyValueDatabase } from "../lib/src/interfaces/KeyValueDatabase.ts
|
||||
import { serialized } from "octagonal-wheels/concurrency/lock";
|
||||
import { Logger } from "octagonal-wheels/common/logger";
|
||||
const databaseCache: { [key: string]: IDBPDatabase<any> } = {};
|
||||
export const OpenKeyValueDatabase = async (dbKey: string): Promise<KeyValueDatabase> => {
|
||||
export { OpenKeyValueDatabase } from "./KeyValueDBv2.ts";
|
||||
|
||||
export const _OpenKeyValueDatabase = async (dbKey: string): Promise<KeyValueDatabase> => {
|
||||
if (dbKey in databaseCache) {
|
||||
databaseCache[dbKey].close();
|
||||
delete databaseCache[dbKey];
|
||||
@@ -82,7 +84,7 @@ export const OpenKeyValueDatabase = async (dbKey: string): Promise<KeyValueDatab
|
||||
},
|
||||
close() {
|
||||
delete databaseCache[dbKey];
|
||||
return closeDB();
|
||||
return Promise.resolve(closeDB());
|
||||
},
|
||||
async destroy() {
|
||||
delete databaseCache[dbKey];
|
||||
|
||||
154
src/common/KeyValueDBv2.ts
Normal file
154
src/common/KeyValueDBv2.ts
Normal file
@@ -0,0 +1,154 @@
|
||||
import { LOG_LEVEL_VERBOSE, Logger } from "@/lib/src/common/logger";
|
||||
import type { KeyValueDatabase } from "@/lib/src/interfaces/KeyValueDatabase";
|
||||
import { deleteDB, openDB, type IDBPDatabase } from "idb";
|
||||
import { serialized } from "octagonal-wheels/concurrency/lock";
|
||||
|
||||
const databaseCache = new Map<string, IDBKeyValueDatabase>();
|
||||
|
||||
export async function OpenKeyValueDatabase(dbKey: string): Promise<KeyValueDatabase> {
|
||||
return await serialized(`OpenKeyValueDatabase-${dbKey}`, async () => {
|
||||
const cachedDB = databaseCache.get(dbKey);
|
||||
if (cachedDB) {
|
||||
if (!cachedDB.isDestroyed) {
|
||||
return cachedDB;
|
||||
}
|
||||
await cachedDB.ensuredDestroyed;
|
||||
databaseCache.delete(dbKey);
|
||||
}
|
||||
const newDB = new IDBKeyValueDatabase(dbKey);
|
||||
try {
|
||||
await newDB.getIsReady();
|
||||
databaseCache.set(dbKey, newDB);
|
||||
return newDB;
|
||||
} catch (e) {
|
||||
databaseCache.delete(dbKey);
|
||||
throw e;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export class IDBKeyValueDatabase implements KeyValueDatabase {
|
||||
protected _dbPromise: Promise<IDBPDatabase<any>> | null = null;
|
||||
protected dbKey: string;
|
||||
protected storeKey: string;
|
||||
protected _isDestroyed: boolean = false;
|
||||
protected destroyedPromise: Promise<void> | null = null;
|
||||
|
||||
get isDestroyed() {
|
||||
return this._isDestroyed;
|
||||
}
|
||||
get ensuredDestroyed(): Promise<void> {
|
||||
if (this.destroyedPromise) {
|
||||
return this.destroyedPromise;
|
||||
}
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
async getIsReady(): Promise<boolean> {
|
||||
await this.ensureDB();
|
||||
return this.isDestroyed === false;
|
||||
}
|
||||
|
||||
protected ensureDB() {
|
||||
if (this._isDestroyed) {
|
||||
throw new Error("Database is destroyed");
|
||||
}
|
||||
if (this._dbPromise) {
|
||||
return this._dbPromise;
|
||||
}
|
||||
this._dbPromise = openDB(this.dbKey, undefined, {
|
||||
upgrade: (db, _oldVersion, _newVersion, _transaction, _event) => {
|
||||
if (!db.objectStoreNames.contains(this.storeKey)) {
|
||||
return db.createObjectStore(this.storeKey);
|
||||
}
|
||||
},
|
||||
blocking: (currentVersion, blockedVersion, event) => {
|
||||
Logger(
|
||||
`Blocking database open for ${this.dbKey}: currentVersion=${currentVersion}, blockedVersion=${blockedVersion}`,
|
||||
LOG_LEVEL_VERBOSE
|
||||
);
|
||||
// This `this` is not this openDB instance, previously opened DB. Let it be closed in the terminated handler.
|
||||
void this.closeDB(true);
|
||||
},
|
||||
blocked: (currentVersion, blockedVersion, event) => {
|
||||
Logger(
|
||||
`Database open blocked for ${this.dbKey}: currentVersion=${currentVersion}, blockedVersion=${blockedVersion}`,
|
||||
LOG_LEVEL_VERBOSE
|
||||
);
|
||||
},
|
||||
terminated: () => {
|
||||
Logger(`Database connection terminated for ${this.dbKey}`, LOG_LEVEL_VERBOSE);
|
||||
this._dbPromise = null;
|
||||
},
|
||||
}).catch((e) => {
|
||||
this._dbPromise = null;
|
||||
throw e;
|
||||
});
|
||||
return this._dbPromise;
|
||||
}
|
||||
protected async closeDB(setDestroyed: boolean = false) {
|
||||
if (this._dbPromise) {
|
||||
const tempPromise = this._dbPromise;
|
||||
this._dbPromise = null;
|
||||
try {
|
||||
const dbR = await tempPromise;
|
||||
dbR.close();
|
||||
} catch (e) {
|
||||
Logger(`Error closing database`);
|
||||
Logger(e, LOG_LEVEL_VERBOSE);
|
||||
}
|
||||
}
|
||||
this._dbPromise = null;
|
||||
if (setDestroyed) {
|
||||
this._isDestroyed = true;
|
||||
this.destroyedPromise = Promise.resolve();
|
||||
}
|
||||
}
|
||||
get DB(): Promise<IDBPDatabase<any>> {
|
||||
if (this._isDestroyed) {
|
||||
return Promise.reject(new Error("Database is destroyed"));
|
||||
}
|
||||
return this.ensureDB();
|
||||
}
|
||||
|
||||
constructor(dbKey: string) {
|
||||
this.dbKey = dbKey;
|
||||
this.storeKey = dbKey;
|
||||
}
|
||||
async get<U>(key: IDBValidKey): Promise<U> {
|
||||
const db = await this.DB;
|
||||
return await db.get(this.storeKey, key);
|
||||
}
|
||||
async set<U>(key: IDBValidKey, value: U): Promise<IDBValidKey> {
|
||||
const db = await this.DB;
|
||||
await db.put(this.storeKey, value, key);
|
||||
return key;
|
||||
}
|
||||
async del(key: IDBValidKey): Promise<void> {
|
||||
const db = await this.DB;
|
||||
return await db.delete(this.storeKey, key);
|
||||
}
|
||||
async clear(): Promise<void> {
|
||||
const db = await this.DB;
|
||||
return await db.clear(this.storeKey);
|
||||
}
|
||||
async keys(query?: IDBValidKey | IDBKeyRange, count?: number): Promise<IDBValidKey[]> {
|
||||
const db = await this.DB;
|
||||
return await db.getAllKeys(this.storeKey, query, count);
|
||||
}
|
||||
async close(): Promise<void> {
|
||||
await this.closeDB();
|
||||
}
|
||||
async destroy(): Promise<void> {
|
||||
this._isDestroyed = true;
|
||||
this.destroyedPromise = (async () => {
|
||||
await this.closeDB();
|
||||
await deleteDB(this.dbKey, {
|
||||
blocked: () => {
|
||||
Logger(`Database delete blocked for ${this.dbKey}`);
|
||||
},
|
||||
});
|
||||
})();
|
||||
await this.destroyedPromise;
|
||||
}
|
||||
}
|
||||
@@ -1803,16 +1803,16 @@ export class ConfigSync extends LiveSyncCommands {
|
||||
return files;
|
||||
}
|
||||
onBindFunction(core: LiveSyncCore, services: InjectableServiceHub): void {
|
||||
services.fileProcessing.handleOptionalFileEvent(this._anyProcessOptionalFileEvent.bind(this));
|
||||
services.conflict.handleGetOptionalConflictCheckMethod(this._anyGetOptionalConflictCheckMethod.bind(this));
|
||||
services.replication.handleProcessVirtualDocuments(this._anyModuleParsedReplicationResultItem.bind(this));
|
||||
services.setting.handleOnRealiseSetting(this._everyRealizeSettingSyncMode.bind(this));
|
||||
services.appLifecycle.handleOnResuming(this._everyOnResumeProcess.bind(this));
|
||||
services.appLifecycle.handleOnResumed(this._everyAfterResumeProcess.bind(this));
|
||||
services.replication.handleBeforeReplicate(this._everyBeforeReplicate.bind(this));
|
||||
services.databaseEvents.handleDatabaseInitialised(this._everyOnDatabaseInitialized.bind(this));
|
||||
services.setting.handleSuspendExtraSync(this._allSuspendExtraSync.bind(this));
|
||||
services.setting.handleSuggestOptionalFeatures(this._allAskUsingOptionalSyncFeature.bind(this));
|
||||
services.setting.handleEnableOptionalFeature(this._allConfigureOptionalSyncFeature.bind(this));
|
||||
services.fileProcessing.processOptionalFileEvent.addHandler(this._anyProcessOptionalFileEvent.bind(this));
|
||||
services.conflict.getOptionalConflictCheckMethod.addHandler(this._anyGetOptionalConflictCheckMethod.bind(this));
|
||||
services.replication.processVirtualDocument.addHandler(this._anyModuleParsedReplicationResultItem.bind(this));
|
||||
services.setting.onRealiseSetting.addHandler(this._everyRealizeSettingSyncMode.bind(this));
|
||||
services.appLifecycle.onResuming.addHandler(this._everyOnResumeProcess.bind(this));
|
||||
services.appLifecycle.onResumed.addHandler(this._everyAfterResumeProcess.bind(this));
|
||||
services.replication.onBeforeReplicate.addHandler(this._everyBeforeReplicate.bind(this));
|
||||
services.databaseEvents.onDatabaseInitialised.addHandler(this._everyOnDatabaseInitialized.bind(this));
|
||||
services.setting.suspendExtraSync.addHandler(this._allSuspendExtraSync.bind(this));
|
||||
services.setting.suggestOptionalFeatures.addHandler(this._allAskUsingOptionalSyncFeature.bind(this));
|
||||
services.setting.enableOptionalFeature.addHandler(this._allConfigureOptionalSyncFeature.bind(this));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1914,16 +1914,16 @@ ${messageFetch}${messageOverwrite}${messageMerge}
|
||||
onBindFunction(core: LiveSyncCore, services: typeof core.services) {
|
||||
// No longer needed on initialisation
|
||||
// services.databaseEvents.handleOnDatabaseInitialisation(this._everyOnInitializeDatabase.bind(this));
|
||||
services.appLifecycle.handleOnSettingLoaded(this._everyOnloadAfterLoadSettings.bind(this));
|
||||
services.fileProcessing.handleOptionalFileEvent(this._anyProcessOptionalFileEvent.bind(this));
|
||||
services.conflict.handleGetOptionalConflictCheckMethod(this._anyGetOptionalConflictCheckMethod.bind(this));
|
||||
services.replication.handleProcessOptionalSynchroniseResult(this._anyProcessOptionalSyncFiles.bind(this));
|
||||
services.setting.handleOnRealiseSetting(this._everyRealizeSettingSyncMode.bind(this));
|
||||
services.appLifecycle.handleOnResuming(this._everyOnResumeProcess.bind(this));
|
||||
services.replication.handleBeforeReplicate(this._everyBeforeReplicate.bind(this));
|
||||
services.databaseEvents.handleDatabaseInitialised(this._everyOnDatabaseInitialized.bind(this));
|
||||
services.setting.handleSuspendExtraSync(this._allSuspendExtraSync.bind(this));
|
||||
services.setting.handleSuggestOptionalFeatures(this._allAskUsingOptionalSyncFeature.bind(this));
|
||||
services.setting.handleEnableOptionalFeature(this._allConfigureOptionalSyncFeature.bind(this));
|
||||
services.appLifecycle.onSettingLoaded.addHandler(this._everyOnloadAfterLoadSettings.bind(this));
|
||||
services.fileProcessing.processOptionalFileEvent.addHandler(this._anyProcessOptionalFileEvent.bind(this));
|
||||
services.conflict.getOptionalConflictCheckMethod.addHandler(this._anyGetOptionalConflictCheckMethod.bind(this));
|
||||
services.replication.processOptionalSynchroniseResult.addHandler(this._anyProcessOptionalSyncFiles.bind(this));
|
||||
services.setting.onRealiseSetting.addHandler(this._everyRealizeSettingSyncMode.bind(this));
|
||||
services.appLifecycle.onResuming.addHandler(this._everyOnResumeProcess.bind(this));
|
||||
services.replication.onBeforeReplicate.addHandler(this._everyBeforeReplicate.bind(this));
|
||||
services.databaseEvents.onDatabaseInitialised.addHandler(this._everyOnDatabaseInitialized.bind(this));
|
||||
services.setting.suspendExtraSync.addHandler(this._allSuspendExtraSync.bind(this));
|
||||
services.setting.suggestOptionalFeatures.addHandler(this._allAskUsingOptionalSyncFeature.bind(this));
|
||||
services.setting.enableOptionalFeature.addHandler(this._allConfigureOptionalSyncFeature.bind(this));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -271,11 +271,11 @@ export class P2PReplicator extends LiveSyncCommands implements P2PReplicatorBase
|
||||
}
|
||||
|
||||
override onBindFunction(core: LiveSyncCore, services: typeof core.services): void {
|
||||
services.replicator.handleGetNewReplicator(this._anyNewReplicator.bind(this));
|
||||
services.databaseEvents.handleOnDatabaseInitialisation(this._everyOnInitializeDatabase.bind(this));
|
||||
services.appLifecycle.handleOnInitialise(this._everyOnloadStart.bind(this));
|
||||
services.appLifecycle.handleOnSuspending(this._everyBeforeSuspendProcess.bind(this));
|
||||
services.appLifecycle.handleOnResumed(this._everyAfterResumeProcess.bind(this));
|
||||
services.setting.handleSuspendExtraSync(this._allSuspendExtraSync.bind(this));
|
||||
services.replicator.getNewReplicator.addHandler(this._anyNewReplicator.bind(this));
|
||||
services.databaseEvents.onDatabaseInitialisation.addHandler(this._everyOnInitializeDatabase.bind(this));
|
||||
services.appLifecycle.onInitialise.addHandler(this._everyOnloadStart.bind(this));
|
||||
services.appLifecycle.onSuspending.addHandler(this._everyBeforeSuspendProcess.bind(this));
|
||||
services.appLifecycle.onResumed.addHandler(this._everyAfterResumeProcess.bind(this));
|
||||
services.setting.suspendExtraSync.addHandler(this._allSuspendExtraSync.bind(this));
|
||||
}
|
||||
}
|
||||
|
||||
2
src/lib
2
src/lib
Submodule src/lib updated: bc761fcf57...724d788e2b
@@ -70,6 +70,7 @@ import { P2PReplicator } from "./features/P2PSync/CmdP2PReplicator.ts";
|
||||
import type { LiveSyncManagers } from "./lib/src/managers/LiveSyncManagers.ts";
|
||||
import { ObsidianServiceHub } from "./modules/services/ObsidianServices.ts";
|
||||
import type { InjectableServiceHub } from "./lib/src/services/InjectableServices.ts";
|
||||
import type { ServiceContext } from "./lib/src/services/ServiceHub.ts";
|
||||
|
||||
export default class ObsidianLiveSyncPlugin
|
||||
extends Plugin
|
||||
@@ -83,7 +84,7 @@ export default class ObsidianLiveSyncPlugin
|
||||
/**
|
||||
* The service hub for managing all services.
|
||||
*/
|
||||
_services: InjectableServiceHub = new ObsidianServiceHub(this);
|
||||
_services: InjectableServiceHub<ServiceContext> = new ObsidianServiceHub(this);
|
||||
get services() {
|
||||
return this._services;
|
||||
}
|
||||
|
||||
@@ -346,7 +346,7 @@ export class ModuleDatabaseFileAccess extends AbstractModule implements Database
|
||||
return ret;
|
||||
}
|
||||
onBindFunction(core: LiveSyncCore, services: typeof core.services): void {
|
||||
services.appLifecycle.handleOnLoaded(this._everyOnload.bind(this));
|
||||
services.test.handleTest(this._everyModuleTest.bind(this));
|
||||
services.appLifecycle.onLoaded.addHandler(this._everyOnload.bind(this));
|
||||
services.test.test.addHandler(this._everyModuleTest.bind(this));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -436,8 +436,8 @@ export class ModuleFileHandler extends AbstractModule {
|
||||
);
|
||||
}
|
||||
onBindFunction(core: LiveSyncCore, services: typeof core.services): void {
|
||||
services.appLifecycle.handleOnInitialise(this._everyOnloadStart.bind(this));
|
||||
services.fileProcessing.handleProcessFileEvent(this._anyHandlerProcessesFileEvent.bind(this));
|
||||
services.replication.handleProcessSynchroniseResult(this._anyProcessReplicatedDoc.bind(this));
|
||||
services.appLifecycle.onInitialise.addHandler(this._everyOnloadStart.bind(this));
|
||||
services.fileProcessing.processFileEvent.addHandler(this._anyHandlerProcessesFileEvent.bind(this));
|
||||
services.replication.processSynchroniseResult.addHandler(this._anyProcessReplicatedDoc.bind(this));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,8 +39,8 @@ export class ModuleLocalDatabaseObsidian extends AbstractModule {
|
||||
return this.localDatabase != null && this.localDatabase.isReady;
|
||||
}
|
||||
onBindFunction(core: LiveSyncCore, services: typeof core.services): void {
|
||||
services.database.handleIsDatabaseReady(this._isDatabaseReady.bind(this));
|
||||
services.appLifecycle.handleOnInitialise(this._everyOnloadStart.bind(this));
|
||||
services.database.handleOpenDatabase(this._openDatabase.bind(this));
|
||||
services.database.isDatabaseReady.setHandler(this._isDatabaseReady.bind(this));
|
||||
services.appLifecycle.onInitialise.addHandler(this._everyOnloadStart.bind(this));
|
||||
services.database.openDatabase.setHandler(this._openDatabase.bind(this));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,10 +32,10 @@ export class ModulePeriodicProcess extends AbstractModule {
|
||||
}
|
||||
|
||||
onBindFunction(core: LiveSyncCore, services: typeof core.services): void {
|
||||
services.appLifecycle.handleOnUnload(this._allOnUnload.bind(this));
|
||||
services.setting.handleBeforeRealiseSetting(this._everyBeforeRealizeSetting.bind(this));
|
||||
services.setting.handleSettingRealised(this._everyAfterRealizeSetting.bind(this));
|
||||
services.appLifecycle.handleOnSuspending(this._everyBeforeSuspendProcess.bind(this));
|
||||
services.appLifecycle.handleOnResumed(this._everyAfterResumeProcess.bind(this));
|
||||
services.appLifecycle.onUnload.addHandler(this._allOnUnload.bind(this));
|
||||
services.setting.onBeforeRealiseSetting.addHandler(this._everyBeforeRealizeSetting.bind(this));
|
||||
services.setting.onSettingRealised.addHandler(this._everyAfterRealizeSetting.bind(this));
|
||||
services.appLifecycle.onSuspending.addHandler(this._everyBeforeSuspendProcess.bind(this));
|
||||
services.appLifecycle.onResumed.addHandler(this._everyAfterResumeProcess.bind(this));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,6 @@ export class ModulePouchDB extends AbstractModule {
|
||||
return new PouchDB(name, optionPass);
|
||||
}
|
||||
onBindFunction(core: LiveSyncCore, services: typeof core.services): void {
|
||||
services.database.handleCreatePouchDBInstance(this._createPouchDBInstance.bind(this));
|
||||
services.database.createPouchDBInstance.setHandler(this._createPouchDBInstance.bind(this));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -275,10 +275,10 @@ Please enable them from the settings screen after setup is complete.`,
|
||||
this._log(`Done!`, LOG_LEVEL_NOTICE, "resolveAllConflictedFilesByNewerOnes");
|
||||
}
|
||||
onBindFunction(core: LiveSyncCore, services: typeof core.services): void {
|
||||
services.appLifecycle.handleOnLoaded(this._everyOnload.bind(this));
|
||||
services.database.handleResetDatabase(this._resetLocalDatabase.bind(this));
|
||||
services.remote.handleTryResetDatabase(this._tryResetRemoteDatabase.bind(this));
|
||||
services.remote.handleTryCreateDatabase(this._tryCreateRemoteDatabase.bind(this));
|
||||
services.setting.handleSuspendAllSync(this._allSuspendAllSync.bind(this));
|
||||
services.appLifecycle.onLoaded.addHandler(this._everyOnload.bind(this));
|
||||
services.database.resetDatabase.setHandler(this._resetLocalDatabase.bind(this));
|
||||
services.remote.tryResetDatabase.setHandler(this._tryResetRemoteDatabase.bind(this));
|
||||
services.remote.tryCreateDatabase.setHandler(this._tryCreateRemoteDatabase.bind(this));
|
||||
services.setting.suspendAllSync.addHandler(this._allSuspendAllSync.bind(this));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -329,19 +329,19 @@ Even if you choose to clean up, you will see this option again if you exit Obsid
|
||||
}
|
||||
|
||||
onBindFunction(core: LiveSyncCore, services: typeof core.services): void {
|
||||
services.replicator.handleGetActiveReplicator(this._getReplicator.bind(this));
|
||||
services.databaseEvents.handleOnDatabaseInitialisation(this._everyOnInitializeDatabase.bind(this));
|
||||
services.databaseEvents.handleDatabaseInitialised(this._everyOnDatabaseInitialized.bind(this));
|
||||
services.databaseEvents.handleOnResetDatabase(this._everyOnResetDatabase.bind(this));
|
||||
services.appLifecycle.handleOnSettingLoaded(this._everyOnloadAfterLoadSettings.bind(this));
|
||||
services.replication.handleParseSynchroniseResult(this._parseReplicationResult.bind(this));
|
||||
services.appLifecycle.handleOnSuspending(this._everyBeforeSuspendProcess.bind(this));
|
||||
services.replication.handleBeforeReplicate(this._everyBeforeReplicate.bind(this));
|
||||
services.replication.handleIsReplicationReady(this._canReplicate.bind(this));
|
||||
services.replication.handleReplicate(this._replicate.bind(this));
|
||||
services.replication.handleReplicateByEvent(this._replicateByEvent.bind(this));
|
||||
services.remote.handleReplicateAllToRemote(this._replicateAllToServer.bind(this));
|
||||
services.remote.handleReplicateAllFromRemote(this._replicateAllFromServer.bind(this));
|
||||
services.appLifecycle.reportUnresolvedMessages(this._reportUnresolvedMessages.bind(this));
|
||||
services.replicator.getActiveReplicator.setHandler(this._getReplicator.bind(this));
|
||||
services.databaseEvents.onDatabaseInitialisation.addHandler(this._everyOnInitializeDatabase.bind(this));
|
||||
services.databaseEvents.onDatabaseInitialised.addHandler(this._everyOnDatabaseInitialized.bind(this));
|
||||
services.databaseEvents.onResetDatabase.addHandler(this._everyOnResetDatabase.bind(this));
|
||||
services.appLifecycle.onSettingLoaded.addHandler(this._everyOnloadAfterLoadSettings.bind(this));
|
||||
services.replication.parseSynchroniseResult.setHandler(this._parseReplicationResult.bind(this));
|
||||
services.appLifecycle.onSuspending.addHandler(this._everyBeforeSuspendProcess.bind(this));
|
||||
services.replication.onBeforeReplicate.addHandler(this._everyBeforeReplicate.bind(this));
|
||||
services.replication.isReplicationReady.setHandler(this._canReplicate.bind(this));
|
||||
services.replication.replicate.setHandler(this._replicate.bind(this));
|
||||
services.replication.replicateByEvent.setHandler(this._replicateByEvent.bind(this));
|
||||
services.remote.replicateAllToRemote.setHandler(this._replicateAllToServer.bind(this));
|
||||
services.remote.replicateAllFromRemote.setHandler(this._replicateAllFromServer.bind(this));
|
||||
services.appLifecycle.getUnresolvedMessages.addHandler(this._reportUnresolvedMessages.bind(this));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ export class ModuleReplicatorCouchDB extends AbstractModule {
|
||||
return Promise.resolve(true);
|
||||
}
|
||||
onBindFunction(core: LiveSyncCore, services: typeof core.services): void {
|
||||
services.replicator.handleGetNewReplicator(this._anyNewReplicator.bind(this));
|
||||
services.appLifecycle.handleOnResumed(this._everyAfterResumeProcess.bind(this));
|
||||
services.replicator.getNewReplicator.addHandler(this._anyNewReplicator.bind(this));
|
||||
services.appLifecycle.onResumed.addHandler(this._everyAfterResumeProcess.bind(this));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,6 @@ export class ModuleReplicatorMinIO extends AbstractModule {
|
||||
return Promise.resolve(false);
|
||||
}
|
||||
onBindFunction(core: LiveSyncCore, services: typeof core.services): void {
|
||||
services.replicator.handleGetNewReplicator(this._anyNewReplicator.bind(this));
|
||||
services.replicator.getNewReplicator.addHandler(this._anyNewReplicator.bind(this));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ export class ModuleReplicatorP2P extends AbstractModule {
|
||||
return Promise.resolve(true);
|
||||
}
|
||||
onBindFunction(core: LiveSyncCore, services: typeof core.services): void {
|
||||
services.replicator.handleGetNewReplicator(this._anyNewReplicator.bind(this));
|
||||
services.appLifecycle.handleOnResumed(this._everyAfterResumeProcess.bind(this));
|
||||
services.replicator.getNewReplicator.addHandler(this._anyNewReplicator.bind(this));
|
||||
services.appLifecycle.onResumed.addHandler(this._everyAfterResumeProcess.bind(this));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -174,12 +174,12 @@ export class ModuleTargetFilter extends AbstractModule {
|
||||
}
|
||||
|
||||
onBindFunction(core: LiveSyncCore, services: typeof core.services): void {
|
||||
services.vault.handleMarkFileListPossiblyChanged(this._markFileListPossiblyChanged.bind(this));
|
||||
services.path.handleId2Path(this._id2path.bind(this));
|
||||
services.path.handlePath2Id(this._path2id.bind(this));
|
||||
services.appLifecycle.handleOnLoaded(this._everyOnload.bind(this));
|
||||
services.vault.handleIsFileSizeTooLarge(this._isFileSizeExceeded.bind(this));
|
||||
services.vault.handleIsIgnoredByIgnoreFile(this._isIgnoredByIgnoreFiles.bind(this));
|
||||
services.vault.handleIsTargetFile(this._isTargetFile.bind(this));
|
||||
services.vault.markFileListPossiblyChanged.setHandler(this._markFileListPossiblyChanged.bind(this));
|
||||
services.path.id2path.setHandler(this._id2path.bind(this));
|
||||
services.path.path2id.setHandler(this._path2id.bind(this));
|
||||
services.appLifecycle.onLoaded.addHandler(this._everyOnload.bind(this));
|
||||
services.vault.isFileSizeTooLarge.setHandler(this._isFileSizeExceeded.bind(this));
|
||||
services.vault.isIgnoredByIgnoreFile.setHandler(this._isIgnoredByIgnoreFiles.bind(this));
|
||||
services.vault.isTargetFile.setHandler(this._isTargetFile.bind(this));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -75,8 +75,8 @@ export class ModuleConflictChecker extends AbstractModule {
|
||||
}
|
||||
);
|
||||
onBindFunction(core: LiveSyncCore, services: InjectableServiceHub): void {
|
||||
services.conflict.handleQueueCheckForIfOpen(this._queueConflictCheckIfOpen.bind(this));
|
||||
services.conflict.handleQueueCheckFor(this._queueConflictCheck.bind(this));
|
||||
services.conflict.handleEnsureAllProcessed(this._waitForAllConflictProcessed.bind(this));
|
||||
services.conflict.queueCheckForIfOpen.setHandler(this._queueConflictCheckIfOpen.bind(this));
|
||||
services.conflict.queueCheckFor.setHandler(this._queueConflictCheck.bind(this));
|
||||
services.conflict.ensureAllProcessed.setHandler(this._waitForAllConflictProcessed.bind(this));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -213,8 +213,8 @@ export class ModuleConflictResolver extends AbstractModule {
|
||||
}
|
||||
|
||||
onBindFunction(core: LiveSyncCore, services: InjectableServiceHub): void {
|
||||
services.conflict.handleResolveByDeletingRevision(this._resolveConflictByDeletingRev.bind(this));
|
||||
services.conflict.handleResolve(this._resolveConflict.bind(this));
|
||||
services.conflict.handleResolveByNewest(this._anyResolveConflictByNewest.bind(this));
|
||||
services.conflict.resolveByDeletingRevision.setHandler(this._resolveConflictByDeletingRev.bind(this));
|
||||
services.conflict.resolve.setHandler(this._resolveConflict.bind(this));
|
||||
services.conflict.resolveByNewest.setHandler(this._anyResolveConflictByNewest.bind(this));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -322,6 +322,6 @@ export class ModuleRedFlag extends AbstractModule {
|
||||
}
|
||||
onBindFunction(core: LiveSyncCore, services: typeof core.services): void {
|
||||
super.onBindFunction(core, services);
|
||||
services.appLifecycle.handleLayoutReady(this._everyOnLayoutReady.bind(this));
|
||||
services.appLifecycle.onLayoutReady.addHandler(this._everyOnLayoutReady.bind(this));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,8 +15,8 @@ export class ModuleRemoteGovernor extends AbstractModule {
|
||||
return await this.core.replicator.markRemoteResolved(this.settings);
|
||||
}
|
||||
onBindFunction(core: LiveSyncCore, services: InjectableServiceHub): void {
|
||||
services.remote.handleMarkLocked(this._markRemoteLocked.bind(this));
|
||||
services.remote.handleMarkUnlocked(this._markRemoteUnlocked.bind(this));
|
||||
services.remote.handleMarkResolved(this._markRemoteResolved.bind(this));
|
||||
services.remote.markLocked.setHandler(this._markRemoteLocked.bind(this));
|
||||
services.remote.markUnlocked.setHandler(this._markRemoteUnlocked.bind(this));
|
||||
services.remote.markResolved.setHandler(this._markRemoteResolved.bind(this));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -285,11 +285,15 @@ export class ModuleResolvingMismatchedTweaks extends AbstractModule {
|
||||
}
|
||||
|
||||
onBindFunction(core: LiveSyncCore, services: InjectableServiceHub): void {
|
||||
services.tweakValue.handleFetchRemotePreferred(this._fetchRemotePreferredTweakValues.bind(this));
|
||||
services.tweakValue.handleCheckAndAskResolvingMismatched(this._checkAndAskResolvingMismatchedTweaks.bind(this));
|
||||
services.tweakValue.handleAskResolvingMismatched(this._askResolvingMismatchedTweaks.bind(this));
|
||||
services.tweakValue.handleCheckAndAskUseRemoteConfiguration(this._checkAndAskUseRemoteConfiguration.bind(this));
|
||||
services.tweakValue.handleAskUseRemoteConfiguration(this._askUseRemoteConfiguration.bind(this));
|
||||
services.replication.handleCheckConnectionFailure(this._anyAfterConnectCheckFailed.bind(this));
|
||||
services.tweakValue.fetchRemotePreferred.setHandler(this._fetchRemotePreferredTweakValues.bind(this));
|
||||
services.tweakValue.checkAndAskResolvingMismatched.setHandler(
|
||||
this._checkAndAskResolvingMismatchedTweaks.bind(this)
|
||||
);
|
||||
services.tweakValue.askResolvingMismatched.setHandler(this._askResolvingMismatchedTweaks.bind(this));
|
||||
services.tweakValue.checkAndAskUseRemoteConfiguration.setHandler(
|
||||
this._checkAndAskUseRemoteConfiguration.bind(this)
|
||||
);
|
||||
services.tweakValue.askUseRemoteConfiguration.setHandler(this._askUseRemoteConfiguration.bind(this));
|
||||
services.replication.checkConnectionFailure.addHandler(this._anyAfterConnectCheckFailed.bind(this));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -386,11 +386,11 @@ export class ModuleFileAccessObsidian extends AbstractObsidianModule implements
|
||||
super(plugin, core);
|
||||
}
|
||||
onBindFunction(core: LiveSyncCore, services: InjectableServiceHub): void {
|
||||
services.vault.handleIsStorageInsensitive(this._isStorageInsensitive.bind(this));
|
||||
services.setting.handleShouldCheckCaseInsensitively(this._shouldCheckCaseInsensitive.bind(this));
|
||||
services.appLifecycle.handleFirstInitialise(this._everyOnFirstInitialize.bind(this));
|
||||
services.appLifecycle.handleOnInitialise(this._everyOnloadStart.bind(this));
|
||||
services.appLifecycle.handleOnLoaded(this._everyOnload.bind(this));
|
||||
services.fileProcessing.handleCommitPendingFileEvents(this._everyCommitPendingFileEvent.bind(this));
|
||||
services.vault.isStorageInsensitive.setHandler(this._isStorageInsensitive.bind(this));
|
||||
services.setting.shouldCheckCaseInsensitively.setHandler(this._shouldCheckCaseInsensitive.bind(this));
|
||||
services.appLifecycle.onFirstInitialise.addHandler(this._everyOnFirstInitialize.bind(this));
|
||||
services.appLifecycle.onInitialise.addHandler(this._everyOnloadStart.bind(this));
|
||||
services.appLifecycle.onLoaded.addHandler(this._everyOnload.bind(this));
|
||||
services.fileProcessing.commitPendingFileEvents.addHandler(this._everyCommitPendingFileEvent.bind(this));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -113,6 +113,6 @@ export class ModuleInputUIObsidian extends AbstractObsidianModule implements Con
|
||||
}
|
||||
|
||||
onBindFunction(core: LiveSyncCore, services: typeof core.services): void {
|
||||
services.appLifecycle.handleOnLoaded(this._everyOnload.bind(this));
|
||||
services.appLifecycle.onLoaded.addHandler(this._everyOnload.bind(this));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -397,7 +397,7 @@ export class ModuleInitializerFile extends AbstractModule {
|
||||
}
|
||||
}
|
||||
onBindFunction(core: LiveSyncCore, services: InjectableServiceHub): void {
|
||||
services.databaseEvents.handleInitialiseDatabase(this._initializeDatabase.bind(this));
|
||||
services.vault.handleScanVault(this._performFullScan.bind(this));
|
||||
services.databaseEvents.initialiseDatabase.setHandler(this._initializeDatabase.bind(this));
|
||||
services.vault.scanVault.setHandler(this._performFullScan.bind(this));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,11 +4,12 @@ import type { LiveSyncLocalDB } from "../../lib/src/pouchdb/LiveSyncLocalDB.ts";
|
||||
import { LOG_LEVEL_NOTICE, LOG_LEVEL_VERBOSE } from "octagonal-wheels/common/logger";
|
||||
import { AbstractModule } from "../AbstractModule.ts";
|
||||
import type { LiveSyncCore } from "../../main.ts";
|
||||
import type { SimpleStore } from "octagonal-wheels/databases/SimpleStoreBase";
|
||||
|
||||
export class ModuleKeyValueDB extends AbstractModule {
|
||||
tryCloseKvDB() {
|
||||
async tryCloseKvDB() {
|
||||
try {
|
||||
this.core.kvDB?.close();
|
||||
await this.core.kvDB?.close();
|
||||
return true;
|
||||
} catch (e) {
|
||||
this._log("Failed to close KeyValueDB", LOG_LEVEL_VERBOSE);
|
||||
@@ -19,7 +20,7 @@ export class ModuleKeyValueDB extends AbstractModule {
|
||||
async openKeyValueDB(): Promise<boolean> {
|
||||
await delay(10);
|
||||
try {
|
||||
this.tryCloseKvDB();
|
||||
await this.tryCloseKvDB();
|
||||
await delay(10);
|
||||
await yieldMicrotask();
|
||||
this.core.kvDB = await OpenKeyValueDatabase(this.services.vault.getVaultName() + "-livesync-kv");
|
||||
@@ -33,12 +34,12 @@ export class ModuleKeyValueDB extends AbstractModule {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
_onDBUnload(db: LiveSyncLocalDB) {
|
||||
if (this.core.kvDB) this.core.kvDB.close();
|
||||
async _onDBUnload(db: LiveSyncLocalDB) {
|
||||
if (this.core.kvDB) await this.core.kvDB.close();
|
||||
return Promise.resolve(true);
|
||||
}
|
||||
_onDBClose(db: LiveSyncLocalDB) {
|
||||
if (this.core.kvDB) this.core.kvDB.close();
|
||||
async _onDBClose(db: LiveSyncLocalDB) {
|
||||
if (this.core.kvDB) await this.core.kvDB.close();
|
||||
return Promise.resolve(true);
|
||||
}
|
||||
|
||||
@@ -76,7 +77,7 @@ export class ModuleKeyValueDB extends AbstractModule {
|
||||
.filter((e) => e.startsWith(prefix))
|
||||
.map((e) => e.substring(prefix.length));
|
||||
},
|
||||
};
|
||||
} satisfies SimpleStore<T>;
|
||||
}
|
||||
_everyOnInitializeDatabase(db: LiveSyncLocalDB): Promise<boolean> {
|
||||
return this.openKeyValueDB();
|
||||
@@ -100,11 +101,11 @@ export class ModuleKeyValueDB extends AbstractModule {
|
||||
return true;
|
||||
}
|
||||
onBindFunction(core: LiveSyncCore, services: typeof core.services): void {
|
||||
services.databaseEvents.handleOnUnloadDatabase(this._onDBUnload.bind(this));
|
||||
services.databaseEvents.handleOnCloseDatabase(this._onDBClose.bind(this));
|
||||
services.databaseEvents.handleOnDatabaseInitialisation(this._everyOnInitializeDatabase.bind(this));
|
||||
services.databaseEvents.handleOnResetDatabase(this._everyOnResetDatabase.bind(this));
|
||||
services.database.handleOpenSimpleStore(this._getSimpleStore.bind(this));
|
||||
services.appLifecycle.handleOnSettingLoaded(this._everyOnloadAfterLoadSettings.bind(this));
|
||||
services.databaseEvents.onUnloadDatabase.addHandler(this._onDBUnload.bind(this));
|
||||
services.databaseEvents.onCloseDatabase.addHandler(this._onDBClose.bind(this));
|
||||
services.databaseEvents.onDatabaseInitialisation.addHandler(this._everyOnInitializeDatabase.bind(this));
|
||||
services.databaseEvents.onResetDatabase.addHandler(this._everyOnResetDatabase.bind(this));
|
||||
services.database.openSimpleStore.setHandler(this._getSimpleStore.bind(this));
|
||||
services.appLifecycle.onSettingLoaded.addHandler(this._everyOnloadAfterLoadSettings.bind(this));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -355,7 +355,7 @@ export class ModuleMigration extends AbstractModule {
|
||||
}
|
||||
onBindFunction(core: LiveSyncCore, services: typeof core.services): void {
|
||||
super.onBindFunction(core, services);
|
||||
services.appLifecycle.handleLayoutReady(this._everyOnLayoutReady.bind(this));
|
||||
services.appLifecycle.handleFirstInitialise(this._everyOnFirstInitialize.bind(this));
|
||||
services.appLifecycle.onLayoutReady.addHandler(this._everyOnLayoutReady.bind(this));
|
||||
services.appLifecycle.onFirstInitialise.addHandler(this._everyOnFirstInitialize.bind(this));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -128,7 +128,7 @@ export class ModuleCheckRemoteSize extends AbstractObsidianModule {
|
||||
return Promise.resolve(true);
|
||||
}
|
||||
onBindFunction(core: LiveSyncCore, services: typeof core.services): void {
|
||||
services.appLifecycle.handleOnScanningStartupIssues(this._allScanStat.bind(this));
|
||||
services.appLifecycle.handleOnInitialise(this._everyOnloadStart.bind(this));
|
||||
services.appLifecycle.onScanningStartupIssues.addHandler(this._allScanStat.bind(this));
|
||||
services.appLifecycle.onInitialise.addHandler(this._everyOnloadStart.bind(this));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -312,7 +312,7 @@ export class ModuleObsidianAPI extends AbstractObsidianModule {
|
||||
return `${"appId" in this.app ? this.app.appId : ""}`;
|
||||
}
|
||||
|
||||
private _reportUnresolvedMessages(): Promise<string[]> {
|
||||
private _reportUnresolvedMessages(): Promise<(string | Error)[]> {
|
||||
return Promise.resolve([...this._previousErrors]);
|
||||
}
|
||||
|
||||
@@ -330,16 +330,16 @@ export class ModuleObsidianAPI extends AbstractObsidianModule {
|
||||
}
|
||||
|
||||
onBindFunction(core: LiveSyncCore, services: typeof core.services) {
|
||||
services.API.handleGetCustomFetchHandler(this._customFetchHandler.bind(this));
|
||||
services.API.handleIsLastPostFailedDueToPayloadSize(this._getLastPostFailedBySize.bind(this));
|
||||
services.remote.handleConnect(this._connectRemoteCouchDB.bind(this));
|
||||
services.API.handleIsMobile(this._isMobile.bind(this));
|
||||
services.vault.handleGetVaultName(this._getVaultName.bind(this));
|
||||
services.vault.handleVaultName(this._vaultName.bind(this));
|
||||
services.vault.handleGetActiveFilePath(this._getActiveFilePath.bind(this));
|
||||
services.API.handleGetAppID(this._anyGetAppId.bind(this));
|
||||
services.API.handleGetAppVersion(this._getAppVersion.bind(this));
|
||||
services.API.handleGetPluginVersion(this._getPluginVersion.bind(this));
|
||||
services.appLifecycle.reportUnresolvedMessages(this._reportUnresolvedMessages.bind(this));
|
||||
services.API.getCustomFetchHandler.setHandler(this._customFetchHandler.bind(this));
|
||||
services.API.isLastPostFailedDueToPayloadSize.setHandler(this._getLastPostFailedBySize.bind(this));
|
||||
services.remote.connect.setHandler(this._connectRemoteCouchDB.bind(this));
|
||||
services.API.isMobile.setHandler(this._isMobile.bind(this));
|
||||
services.vault.getVaultName.setHandler(this._getVaultName.bind(this));
|
||||
services.vault.vaultName.setHandler(this._vaultName.bind(this));
|
||||
services.vault.getActiveFilePath.setHandler(this._getActiveFilePath.bind(this));
|
||||
services.API.getAppID.setHandler(this._anyGetAppId.bind(this));
|
||||
services.API.getAppVersion.setHandler(this._getAppVersion.bind(this));
|
||||
services.API.getPluginVersion.setHandler(this._getPluginVersion.bind(this));
|
||||
services.appLifecycle.getUnresolvedMessages.addHandler(this._reportUnresolvedMessages.bind(this));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -244,10 +244,10 @@ export class ModuleObsidianEvents extends AbstractObsidianModule {
|
||||
}
|
||||
}
|
||||
onBindFunction(core: LiveSyncCore, services: typeof core.services): void {
|
||||
services.appLifecycle.handleLayoutReady(this._everyOnLayoutReady.bind(this));
|
||||
services.appLifecycle.handleOnInitialise(this._everyOnloadStart.bind(this));
|
||||
services.appLifecycle.handlePerformRestart(this._performRestart.bind(this));
|
||||
services.appLifecycle.handleAskRestart(this._askReload.bind(this));
|
||||
services.appLifecycle.handleScheduleRestart(this._scheduleAppReload.bind(this));
|
||||
services.appLifecycle.onLayoutReady.addHandler(this._everyOnLayoutReady.bind(this));
|
||||
services.appLifecycle.onInitialise.addHandler(this._everyOnloadStart.bind(this));
|
||||
services.appLifecycle.performRestart.setHandler(this._performRestart.bind(this));
|
||||
services.appLifecycle.askRestart.setHandler(this._askReload.bind(this));
|
||||
services.appLifecycle.scheduleRestart.setHandler(this._scheduleAppReload.bind(this));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -131,8 +131,8 @@ export class ModuleObsidianMenu extends AbstractObsidianModule {
|
||||
}
|
||||
}
|
||||
onBindFunction(core: LiveSyncCore, services: typeof core.services): void {
|
||||
services.appLifecycle.handleOnInitialise(this._everyOnloadStart.bind(this));
|
||||
services.appLifecycle.handleOnLoaded(this._everyOnload.bind(this));
|
||||
services.API.handleShowWindow(this._showView.bind(this));
|
||||
services.appLifecycle.onInitialise.addHandler(this._everyOnloadStart.bind(this));
|
||||
services.appLifecycle.onLoaded.addHandler(this._everyOnload.bind(this));
|
||||
services.API.showWindow.setHandler(this._showView.bind(this));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ export class ModuleExtraSyncObsidian extends AbstractObsidianModule {
|
||||
}
|
||||
|
||||
onBindFunction(core: LiveSyncCore, services: typeof core.services): void {
|
||||
services.setting.handleGetDeviceAndVaultName(this._getDeviceAndVaultName.bind(this));
|
||||
services.setting.handleSetDeviceAndVaultName(this._setDeviceAndVaultName.bind(this));
|
||||
services.setting.getDeviceAndVaultName.setHandler(this._getDeviceAndVaultName.bind(this));
|
||||
services.setting.setDeviceAndVaultName.setHandler(this._setDeviceAndVaultName.bind(this));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -157,10 +157,10 @@ export class ModuleDev extends AbstractObsidianModule {
|
||||
return this.testDone();
|
||||
}
|
||||
onBindFunction(core: LiveSyncCore, services: typeof core.services): void {
|
||||
services.appLifecycle.handleLayoutReady(this._everyOnLayoutReady.bind(this));
|
||||
services.appLifecycle.handleOnInitialise(this._everyOnloadStart.bind(this));
|
||||
services.appLifecycle.handleOnSettingLoaded(this._everyOnloadAfterLoadSettings.bind(this));
|
||||
services.test.handleTest(this._everyModuleTest.bind(this));
|
||||
services.test.handleAddTestResult(this._addTestResult.bind(this));
|
||||
services.appLifecycle.onLayoutReady.addHandler(this._everyOnLayoutReady.bind(this));
|
||||
services.appLifecycle.onInitialise.addHandler(this._everyOnloadStart.bind(this));
|
||||
services.appLifecycle.onSettingLoaded.addHandler(this._everyOnloadAfterLoadSettings.bind(this));
|
||||
services.test.test.addHandler(this._everyModuleTest.bind(this));
|
||||
services.test.addTestResult.setHandler(this._addTestResult.bind(this));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -441,6 +441,6 @@ Line4:D`;
|
||||
return Promise.resolve(true);
|
||||
}
|
||||
onBindFunction(core: typeof this.core, services: typeof core.services): void {
|
||||
services.test.handleTestMultiDevice(this._everyModuleTestMultiDevice.bind(this));
|
||||
services.test.testMultiDevice.addHandler(this._everyModuleTestMultiDevice.bind(this));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -581,8 +581,8 @@ ABCDEFGHIJKLMNOPQRSTUVWXYZ`;
|
||||
return this.testDone();
|
||||
}
|
||||
onBindFunction(core: LiveSyncCore, services: typeof core.services): void {
|
||||
services.appLifecycle.handleOnSettingLoaded(this._everyOnloadAfterLoadSettings.bind(this));
|
||||
services.replication.handleBeforeReplicate(this._everyBeforeReplicate.bind(this));
|
||||
services.test.handleTestMultiDevice(this._everyModuleTestMultiDevice.bind(this));
|
||||
services.appLifecycle.onSettingLoaded.addHandler(this._everyOnloadAfterLoadSettings.bind(this));
|
||||
services.replication.onBeforeReplicate.addHandler(this._everyBeforeReplicate.bind(this));
|
||||
services.test.testMultiDevice.addHandler(this._everyModuleTestMultiDevice.bind(this));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,6 +20,6 @@ export class ModuleObsidianGlobalHistory extends AbstractObsidianModule {
|
||||
void this.services.API.showWindow(VIEW_TYPE_GLOBAL_HISTORY);
|
||||
}
|
||||
onBindFunction(core: typeof this.core, services: typeof core.services): void {
|
||||
services.appLifecycle.handleOnInitialise(this._everyOnloadStart.bind(this));
|
||||
services.appLifecycle.onInitialise.addHandler(this._everyOnloadStart.bind(this));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -165,8 +165,8 @@ export class ModuleInteractiveConflictResolver extends AbstractObsidianModule {
|
||||
return true;
|
||||
}
|
||||
onBindFunction(core: LiveSyncCore, services: typeof core.services): void {
|
||||
services.appLifecycle.handleOnScanningStartupIssues(this._allScanStat.bind(this));
|
||||
services.appLifecycle.handleOnInitialise(this._everyOnloadStart.bind(this));
|
||||
services.conflict.handleResolveByUserInteraction(this._anyResolveConflictByUI.bind(this));
|
||||
services.appLifecycle.onScanningStartupIssues.addHandler(this._allScanStat.bind(this));
|
||||
services.appLifecycle.onInitialise.addHandler(this._everyOnloadStart.bind(this));
|
||||
services.conflict.resolveByUserInteraction.addHandler(this._anyResolveConflictByUI.bind(this));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -495,9 +495,9 @@ export class ModuleLog extends AbstractObsidianModule {
|
||||
}
|
||||
}
|
||||
onBindFunction(core: LiveSyncCore, services: typeof core.services): void {
|
||||
services.appLifecycle.handleOnInitialise(this._everyOnloadStart.bind(this));
|
||||
services.appLifecycle.handleOnSettingLoaded(this._everyOnloadAfterLoadSettings.bind(this));
|
||||
services.appLifecycle.handleOnLoaded(this._everyOnload.bind(this));
|
||||
services.appLifecycle.handleOnBeforeUnload(this._allStartOnUnload.bind(this));
|
||||
services.appLifecycle.onInitialise.addHandler(this._everyOnloadStart.bind(this));
|
||||
services.appLifecycle.onSettingLoaded.addHandler(this._everyOnloadAfterLoadSettings.bind(this));
|
||||
services.appLifecycle.onLoaded.addHandler(this._everyOnload.bind(this));
|
||||
services.appLifecycle.onBeforeUnload.addHandler(this._allStartOnUnload.bind(this));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,6 +52,6 @@ export class ModuleObsidianDocumentHistory extends AbstractObsidianModule {
|
||||
}
|
||||
}
|
||||
onBindFunction(core: typeof this.core, services: typeof core.services): void {
|
||||
services.appLifecycle.handleOnInitialise(this._everyOnloadStart.bind(this));
|
||||
services.appLifecycle.onInitialise.addHandler(this._everyOnloadStart.bind(this));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -323,13 +323,13 @@ export class ModuleObsidianSettings extends AbstractObsidianModule {
|
||||
|
||||
onBindFunction(core: LiveSyncCore, services: typeof core.services): void {
|
||||
super.onBindFunction(core, services);
|
||||
services.appLifecycle.handleLayoutReady(this._everyOnLayoutReady.bind(this));
|
||||
services.setting.handleClearUsedPassphrase(this._clearUsedPassphrase.bind(this));
|
||||
services.setting.handleDecryptSettings(this._decryptSettings.bind(this));
|
||||
services.setting.handleAdjustSettings(this._adjustSettings.bind(this));
|
||||
services.setting.handleLoadSettings(this._loadSettings.bind(this));
|
||||
services.setting.handleCurrentSettings(this._currentSettings.bind(this));
|
||||
services.setting.handleSaveDeviceAndVaultName(this._saveDeviceAndVaultName.bind(this));
|
||||
services.setting.handleSaveSettingData(this._saveSettingData.bind(this));
|
||||
services.appLifecycle.onLayoutReady.addHandler(this._everyOnLayoutReady.bind(this));
|
||||
services.setting.clearUsedPassphrase.setHandler(this._clearUsedPassphrase.bind(this));
|
||||
services.setting.decryptSettings.setHandler(this._decryptSettings.bind(this));
|
||||
services.setting.adjustSettings.setHandler(this._adjustSettings.bind(this));
|
||||
services.setting.loadSettings.setHandler(this._loadSettings.bind(this));
|
||||
services.setting.currentSettings.setHandler(this._currentSettings.bind(this));
|
||||
services.setting.saveDeviceAndVaultName.setHandler(this._saveDeviceAndVaultName.bind(this));
|
||||
services.setting.saveSettingData.setHandler(this._saveSettingData.bind(this));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -243,6 +243,6 @@ We can perform a command in this file.
|
||||
}
|
||||
}
|
||||
onBindFunction(core: typeof this.plugin, services: typeof core.services): void {
|
||||
services.appLifecycle.handleOnInitialise(this._everyOnloadStart.bind(this));
|
||||
services.appLifecycle.onInitialise.addHandler(this._everyOnloadStart.bind(this));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,6 +30,6 @@ export class ModuleObsidianSettingDialogue extends AbstractObsidianModule {
|
||||
return `${"appId" in this.app ? this.app.appId : ""}`;
|
||||
}
|
||||
onBindFunction(core: typeof this.plugin, services: typeof core.services): void {
|
||||
services.appLifecycle.handleOnInitialise(this._everyOnloadStart.bind(this));
|
||||
services.appLifecycle.onInitialise.addHandler(this._everyOnloadStart.bind(this));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -195,6 +195,6 @@ export class ModuleSetupObsidian extends AbstractObsidianModule {
|
||||
// }
|
||||
|
||||
onBindFunction(core: LiveSyncCore, services: typeof core.services): void {
|
||||
services.appLifecycle.handleOnLoaded(this._everyOnload.bind(this));
|
||||
services.appLifecycle.onLoaded.addHandler(this._everyOnload.bind(this));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -93,6 +93,9 @@
|
||||
keys: () => {
|
||||
return Promise.resolve(Array.from(map.keys()));
|
||||
},
|
||||
get db() {
|
||||
return Promise.resolve(this);
|
||||
},
|
||||
} as SimpleStore<any>;
|
||||
|
||||
const dummyPouch = new PouchDB<EntryDoc>("dummy");
|
||||
|
||||
@@ -208,17 +208,17 @@ export class ModuleLiveSyncMain extends AbstractModule {
|
||||
|
||||
onBindFunction(core: LiveSyncCore, services: InjectableServiceHub): void {
|
||||
super.onBindFunction(core, services);
|
||||
services.appLifecycle.handleIsSuspended(this._isSuspended.bind(this));
|
||||
services.appLifecycle.handleSetSuspended(this._setSuspended.bind(this));
|
||||
services.appLifecycle.handleIsReady(this._isReady.bind(this));
|
||||
services.appLifecycle.handleMarkIsReady(this._markIsReady.bind(this));
|
||||
services.appLifecycle.handleResetIsReady(this._resetIsReady.bind(this));
|
||||
services.appLifecycle.handleHasUnloaded(this._isUnloaded.bind(this));
|
||||
services.appLifecycle.handleIsReloadingScheduled(this._isReloadingScheduled.bind(this));
|
||||
services.appLifecycle.handleOnReady(this._onLiveSyncReady.bind(this));
|
||||
services.appLifecycle.handleOnWireUpEvents(this._wireUpEvents.bind(this));
|
||||
services.appLifecycle.handleOnLoad(this._onLiveSyncLoad.bind(this));
|
||||
services.appLifecycle.handleOnAppUnload(this._onLiveSyncUnload.bind(this));
|
||||
services.setting.handleRealiseSetting(this._realizeSettingSyncMode.bind(this));
|
||||
services.appLifecycle.isSuspended.setHandler(this._isSuspended.bind(this));
|
||||
services.appLifecycle.setSuspended.setHandler(this._setSuspended.bind(this));
|
||||
services.appLifecycle.isReady.setHandler(this._isReady.bind(this));
|
||||
services.appLifecycle.markIsReady.setHandler(this._markIsReady.bind(this));
|
||||
services.appLifecycle.resetIsReady.setHandler(this._resetIsReady.bind(this));
|
||||
services.appLifecycle.hasUnloaded.setHandler(this._isUnloaded.bind(this));
|
||||
services.appLifecycle.isReloadingScheduled.setHandler(this._isReloadingScheduled.bind(this));
|
||||
services.appLifecycle.onReady.addHandler(this._onLiveSyncReady.bind(this));
|
||||
services.appLifecycle.onWireUpEvents.addHandler(this._wireUpEvents.bind(this));
|
||||
services.appLifecycle.onLoad.addHandler(this._onLiveSyncLoad.bind(this));
|
||||
services.appLifecycle.onAppUnload.addHandler(this._onLiveSyncUnload.bind(this));
|
||||
services.setting.realiseSetting.setHandler(this._realizeSettingSyncMode.bind(this));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
import { ServiceContext, type ServiceInstances } from "@/lib/src/services/ServiceHub.ts";
|
||||
import {
|
||||
InjectableAPIService,
|
||||
InjectableAppLifecycleService,
|
||||
InjectableConflictService,
|
||||
InjectableDatabaseEventService,
|
||||
InjectableDatabaseService,
|
||||
InjectableFileProcessingService,
|
||||
InjectablePathService,
|
||||
@@ -17,79 +19,96 @@ import { InjectableServiceHub } from "../../lib/src/services/InjectableServices.
|
||||
import { ConfigServiceBrowserCompat } from "../../lib/src/services/Services.ts";
|
||||
import type ObsidianLiveSyncPlugin from "../../main.ts";
|
||||
import { ObsidianUIService } from "./ObsidianUIService.ts";
|
||||
import type { App, Plugin } from "@/deps";
|
||||
|
||||
export class ObsidianServiceContext extends ServiceContext {
|
||||
app: App;
|
||||
plugin: Plugin;
|
||||
liveSyncPlugin: ObsidianLiveSyncPlugin;
|
||||
constructor(app: App, plugin: Plugin, liveSyncPlugin: ObsidianLiveSyncPlugin) {
|
||||
super();
|
||||
this.app = app;
|
||||
this.plugin = plugin;
|
||||
this.liveSyncPlugin = liveSyncPlugin;
|
||||
}
|
||||
}
|
||||
|
||||
// All Services will be migrated to be based on Plain Services, not Injectable Services.
|
||||
// This is a migration step.
|
||||
|
||||
export class ObsidianAPIService extends InjectableAPIService {
|
||||
export class ObsidianAPIService extends InjectableAPIService<ObsidianServiceContext> {
|
||||
getPlatform(): string {
|
||||
return "obsidian";
|
||||
}
|
||||
}
|
||||
export class ObsidianPathService extends InjectablePathService {}
|
||||
export class ObsidianDatabaseService extends InjectableDatabaseService {}
|
||||
export class ObsidianPathService extends InjectablePathService<ObsidianServiceContext> {}
|
||||
export class ObsidianDatabaseService extends InjectableDatabaseService<ObsidianServiceContext> {}
|
||||
export class ObsidianDatabaseEventService extends InjectableDatabaseEventService<ObsidianServiceContext> {}
|
||||
|
||||
// InjectableReplicatorService
|
||||
export class ObsidianReplicatorService extends InjectableReplicatorService {}
|
||||
export class ObsidianReplicatorService extends InjectableReplicatorService<ObsidianServiceContext> {}
|
||||
// InjectableFileProcessingService
|
||||
export class ObsidianFileProcessingService extends InjectableFileProcessingService {}
|
||||
export class ObsidianFileProcessingService extends InjectableFileProcessingService<ObsidianServiceContext> {}
|
||||
// InjectableReplicationService
|
||||
export class ObsidianReplicationService extends InjectableReplicationService {}
|
||||
export class ObsidianReplicationService extends InjectableReplicationService<ObsidianServiceContext> {}
|
||||
// InjectableRemoteService
|
||||
export class ObsidianRemoteService extends InjectableRemoteService {}
|
||||
export class ObsidianRemoteService extends InjectableRemoteService<ObsidianServiceContext> {}
|
||||
// InjectableConflictService
|
||||
export class ObsidianConflictService extends InjectableConflictService {}
|
||||
export class ObsidianConflictService extends InjectableConflictService<ObsidianServiceContext> {}
|
||||
// InjectableAppLifecycleService
|
||||
export class ObsidianAppLifecycleService extends InjectableAppLifecycleService {}
|
||||
export class ObsidianAppLifecycleService extends InjectableAppLifecycleService<ObsidianServiceContext> {}
|
||||
// InjectableSettingService
|
||||
export class ObsidianSettingService extends InjectableSettingService {}
|
||||
export class ObsidianSettingService extends InjectableSettingService<ObsidianServiceContext> {}
|
||||
// InjectableTweakValueService
|
||||
export class ObsidianTweakValueService extends InjectableTweakValueService {}
|
||||
export class ObsidianTweakValueService extends InjectableTweakValueService<ObsidianServiceContext> {}
|
||||
// InjectableVaultService
|
||||
export class ObsidianVaultService extends InjectableVaultService {}
|
||||
export class ObsidianVaultService extends InjectableVaultService<ObsidianServiceContext> {}
|
||||
// InjectableTestService
|
||||
export class ObsidianTestService extends InjectableTestService {}
|
||||
|
||||
export class ObsidianConfigService extends ConfigServiceBrowserCompat {}
|
||||
export class ObsidianTestService extends InjectableTestService<ObsidianServiceContext> {}
|
||||
export class ObsidianConfigService extends ConfigServiceBrowserCompat<ObsidianServiceContext> {}
|
||||
|
||||
// InjectableServiceHub
|
||||
|
||||
export class ObsidianServiceHub extends InjectableServiceHub {
|
||||
protected _api: ObsidianAPIService = new ObsidianAPIService(this._serviceBackend, this._throughHole);
|
||||
protected _path: ObsidianPathService = new ObsidianPathService(this._serviceBackend, this._throughHole);
|
||||
protected _database: ObsidianDatabaseService = new ObsidianDatabaseService(this._serviceBackend, this._throughHole);
|
||||
protected _replicator: ObsidianReplicatorService = new ObsidianReplicatorService(
|
||||
this._serviceBackend,
|
||||
this._throughHole
|
||||
);
|
||||
protected _fileProcessing: ObsidianFileProcessingService = new ObsidianFileProcessingService(
|
||||
this._serviceBackend,
|
||||
this._throughHole
|
||||
);
|
||||
protected _replication: ObsidianReplicationService = new ObsidianReplicationService(
|
||||
this._serviceBackend,
|
||||
this._throughHole
|
||||
);
|
||||
protected _remote: ObsidianRemoteService = new ObsidianRemoteService(this._serviceBackend, this._throughHole);
|
||||
protected _conflict: ObsidianConflictService = new ObsidianConflictService(this._serviceBackend, this._throughHole);
|
||||
protected _appLifecycle: ObsidianAppLifecycleService = new ObsidianAppLifecycleService(
|
||||
this._serviceBackend,
|
||||
this._throughHole
|
||||
);
|
||||
protected _setting: ObsidianSettingService = new ObsidianSettingService(this._serviceBackend, this._throughHole);
|
||||
protected _tweakValue: ObsidianTweakValueService = new ObsidianTweakValueService(
|
||||
this._serviceBackend,
|
||||
this._throughHole
|
||||
);
|
||||
protected _vault: ObsidianVaultService = new ObsidianVaultService(this._serviceBackend, this._throughHole);
|
||||
protected _test: ObsidianTestService = new ObsidianTestService(this._serviceBackend, this._throughHole);
|
||||
|
||||
private _plugin: ObsidianLiveSyncPlugin;
|
||||
export class ObsidianServiceHub extends InjectableServiceHub<ObsidianServiceContext> {
|
||||
constructor(plugin: ObsidianLiveSyncPlugin) {
|
||||
const config = new ObsidianConfigService();
|
||||
super({
|
||||
ui: new ObsidianUIService(plugin),
|
||||
const context = new ObsidianServiceContext(plugin.app, plugin, plugin);
|
||||
|
||||
const API = new ObsidianAPIService(context);
|
||||
const appLifecycle = new ObsidianAppLifecycleService(context);
|
||||
const conflict = new ObsidianConflictService(context);
|
||||
const database = new ObsidianDatabaseService(context);
|
||||
const fileProcessing = new ObsidianFileProcessingService(context);
|
||||
const replication = new ObsidianReplicationService(context);
|
||||
const replicator = new ObsidianReplicatorService(context);
|
||||
const remote = new ObsidianRemoteService(context);
|
||||
const setting = new ObsidianSettingService(context);
|
||||
const tweakValue = new ObsidianTweakValueService(context);
|
||||
const vault = new ObsidianVaultService(context);
|
||||
const test = new ObsidianTestService(context);
|
||||
const databaseEvents = new ObsidianDatabaseEventService(context);
|
||||
const path = new ObsidianPathService(context);
|
||||
const ui = new ObsidianUIService(context);
|
||||
const config = new ObsidianConfigService(context, vault);
|
||||
// Using 'satisfies' to ensure all services are provided
|
||||
const serviceInstancesToInit = {
|
||||
appLifecycle: appLifecycle,
|
||||
conflict: conflict,
|
||||
database: database,
|
||||
databaseEvents: databaseEvents,
|
||||
fileProcessing: fileProcessing,
|
||||
replication: replication,
|
||||
replicator: replicator,
|
||||
remote: remote,
|
||||
setting: setting,
|
||||
tweakValue: tweakValue,
|
||||
vault: vault,
|
||||
test: test,
|
||||
ui: ui,
|
||||
path: path,
|
||||
API: API,
|
||||
config: config,
|
||||
});
|
||||
this._plugin = plugin;
|
||||
} satisfies Required<ServiceInstances<ObsidianServiceContext>>;
|
||||
|
||||
super(context, serviceInstancesToInit);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,19 +1,24 @@
|
||||
import { UIService } from "../../lib/src/services/Services";
|
||||
import type ObsidianLiveSyncPlugin from "../../main";
|
||||
import type { Plugin } from "@/deps";
|
||||
import { SvelteDialogManager } from "../features/SetupWizard/ObsidianSvelteDialog";
|
||||
import DialogueToCopy from "../../lib/src/UI/dialogues/DialogueToCopy.svelte";
|
||||
import type { ObsidianServiceContext } from "./ObsidianServices";
|
||||
import type ObsidianLiveSyncPlugin from "@/main";
|
||||
|
||||
export class ObsidianUIService extends UIService {
|
||||
export class ObsidianUIService extends UIService<ObsidianServiceContext> {
|
||||
private _dialogManager: SvelteDialogManager;
|
||||
private _plugin: ObsidianLiveSyncPlugin;
|
||||
private _plugin: Plugin;
|
||||
private _liveSyncPlugin: ObsidianLiveSyncPlugin;
|
||||
get dialogManager() {
|
||||
return this._dialogManager;
|
||||
}
|
||||
constructor(plugin: ObsidianLiveSyncPlugin) {
|
||||
super();
|
||||
this._dialogManager = new SvelteDialogManager(plugin);
|
||||
this._plugin = plugin;
|
||||
constructor(context: ObsidianServiceContext) {
|
||||
super(context);
|
||||
this._liveSyncPlugin = context.liveSyncPlugin;
|
||||
this._dialogManager = new SvelteDialogManager(this._liveSyncPlugin);
|
||||
this._plugin = context.plugin;
|
||||
}
|
||||
|
||||
async promptCopyToClipboard(title: string, value: string): Promise<boolean> {
|
||||
const param = {
|
||||
title: title,
|
||||
@@ -25,13 +30,15 @@ export class ObsidianUIService extends UIService {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
showMarkdownDialog<T extends string[]>(
|
||||
title: string,
|
||||
contentMD: string,
|
||||
buttons: T,
|
||||
defaultAction?: (typeof buttons)[number]
|
||||
): Promise<(typeof buttons)[number] | false> {
|
||||
return this._plugin.confirm.askSelectStringDialogue(contentMD, buttons, {
|
||||
// TODO: implement `confirm` to this service
|
||||
return this._liveSyncPlugin.confirm.askSelectStringDialogue(contentMD, buttons, {
|
||||
title,
|
||||
defaultAction: defaultAction ?? buttons[0],
|
||||
timeout: 0,
|
||||
|
||||
@@ -992,4 +992,4 @@ export type ListedFiles = {
|
||||
folders: string[];
|
||||
};
|
||||
|
||||
export type ValueComponent = any;
|
||||
export type ValueComponent = any;
|
||||
|
||||
@@ -3,6 +3,14 @@ Since 19th July, 2025 (beta1 in 0.25.0-beta1, 13th July, 2025)
|
||||
|
||||
The head note of 0.25 is now in [updates_old.md](https://github.com/vrtmrz/obsidian-livesync/blob/main/updates_old.md). Because 0.25 got a lot of updates, thankfully, compatibility is kept and we do not need breaking changes! In other words, when get enough stabled. The next version will be v1.0.0. Even though it my hope.
|
||||
|
||||
## 0.25.38
|
||||
|
||||
17th January, 2026
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fixed an issue where indexedDB would not close correctly on some environments, causing unexpected errors during database operations.
|
||||
|
||||
## 0.25.37
|
||||
|
||||
15th January, 2026
|
||||
|
||||
110
vitest.config.common.ts
Normal file
110
vitest.config.common.ts
Normal file
@@ -0,0 +1,110 @@
|
||||
import { defineConfig } from "vitest/config";
|
||||
import { svelte } from "@sveltejs/vite-plugin-svelte";
|
||||
import { sveltePreprocess } from "svelte-preprocess";
|
||||
import inlineWorkerPlugin from "esbuild-plugin-inline-worker";
|
||||
import path from "path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
import fs from "node:fs";
|
||||
import { platform } from "node:process";
|
||||
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||
|
||||
const manifestJson = JSON.parse(fs.readFileSync("./manifest.json") + "");
|
||||
const packageJson = JSON.parse(fs.readFileSync("./package.json") + "");
|
||||
const updateInfo = JSON.stringify(fs.readFileSync("./updates.md") + "");
|
||||
const prod = false;
|
||||
const moduleAliasPlugin = {
|
||||
name: "module-alias",
|
||||
setup(build: any) {
|
||||
build.onResolve({ filter: /.(dev)(.ts|)$/ }, (args: any) => {
|
||||
// console.log(args.path);
|
||||
if (prod) {
|
||||
const prodTs = args.path.replace(".dev", ".prod");
|
||||
const statFile = prodTs.endsWith(".ts") ? prodTs : prodTs + ".ts";
|
||||
const realPath = path.join(args.resolveDir, statFile);
|
||||
console.log(`Checking ${statFile}`);
|
||||
if (fs.existsSync(realPath)) {
|
||||
console.log(`Replaced ${args.path} with ${prodTs}`);
|
||||
return {
|
||||
path: realPath,
|
||||
namespace: "file",
|
||||
};
|
||||
}
|
||||
}
|
||||
return null;
|
||||
});
|
||||
build.onResolve({ filter: /.(platform)(.ts|)$/ }, (args: any) => {
|
||||
// console.log(args.path);
|
||||
if (prod) {
|
||||
const prodTs = args.path.replace(".platform", ".obsidian");
|
||||
const statFile = prodTs.endsWith(".ts") ? prodTs : prodTs + ".ts";
|
||||
const realPath = path.join(args.resolveDir, statFile);
|
||||
console.log(`Checking ${statFile}`);
|
||||
if (fs.existsSync(realPath)) {
|
||||
console.log(`Replaced ${args.path} with ${prodTs}`);
|
||||
return {
|
||||
path: realPath,
|
||||
namespace: "file",
|
||||
};
|
||||
}
|
||||
}
|
||||
return null;
|
||||
});
|
||||
},
|
||||
};
|
||||
const externals = [
|
||||
"obsidian",
|
||||
"electron",
|
||||
"crypto",
|
||||
"@codemirror/autocomplete",
|
||||
"@codemirror/collab",
|
||||
"@codemirror/commands",
|
||||
"@codemirror/language",
|
||||
"@codemirror/lint",
|
||||
"@codemirror/search",
|
||||
"@codemirror/state",
|
||||
"@codemirror/view",
|
||||
"@lezer/common",
|
||||
"@lezer/highlight",
|
||||
"@lezer/lr",
|
||||
];
|
||||
const define = {
|
||||
MANIFEST_VERSION: `"${manifestJson.version}"`,
|
||||
PACKAGE_VERSION: `"${packageJson.version}"`,
|
||||
UPDATE_INFO: `${updateInfo}`,
|
||||
global: "globalThis",
|
||||
hostPlatform: `"${platform}"`,
|
||||
};
|
||||
export default defineConfig({
|
||||
plugins: [
|
||||
moduleAliasPlugin,
|
||||
inlineWorkerPlugin({
|
||||
external: externals,
|
||||
treeShaking: true,
|
||||
}),
|
||||
svelte({
|
||||
preprocess: sveltePreprocess(),
|
||||
compilerOptions: { css: "injected", preserveComments: false },
|
||||
}),
|
||||
],
|
||||
resolve: {
|
||||
alias: {
|
||||
obsidian: path.resolve(__dirname, "./test/harness/obsidian-mock.ts"),
|
||||
"@": path.resolve(__dirname, "./src"),
|
||||
"@lib": path.resolve(__dirname, "./src/lib/src"),
|
||||
src: path.resolve(__dirname, "./src"),
|
||||
},
|
||||
},
|
||||
esbuild: {
|
||||
define: define,
|
||||
target: "es2018",
|
||||
platform: "browser",
|
||||
},
|
||||
// define,
|
||||
server: {
|
||||
headers: {
|
||||
"Service-Worker-Allowed": "/",
|
||||
},
|
||||
port: 5173,
|
||||
},
|
||||
});
|
||||
236
vitest.config.ts
236
vitest.config.ts
@@ -1,180 +1,76 @@
|
||||
import { defineConfig } from "vitest/config";
|
||||
import { defineConfig, mergeConfig } from "vitest/config";
|
||||
import { playwright } from "@vitest/browser-playwright";
|
||||
import { svelte } from "@sveltejs/vite-plugin-svelte";
|
||||
import { sveltePreprocess } from "svelte-preprocess";
|
||||
import inlineWorkerPlugin from "esbuild-plugin-inline-worker";
|
||||
import path from "path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
import fs from "node:fs";
|
||||
import viteConfig from "./vitest.config.common";
|
||||
import dotenv from "dotenv";
|
||||
import { platform } from "node:process";
|
||||
|
||||
import { acceptWebPeer, closeWebPeer, grantClipboardPermissions, openWebPeer } from "./test/lib/commands.ts";
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||
|
||||
import { grantClipboardPermissions, openWebPeer, closeWebPeer, acceptWebPeer } from "./test/lib/commands";
|
||||
const defEnv = dotenv.config({ path: ".env" }).parsed;
|
||||
const testEnv = dotenv.config({ path: ".test.env" }).parsed;
|
||||
const env = Object.assign({}, defEnv, testEnv);
|
||||
const debuggerEnabled = env?.ENABLE_DEBUGGER === "true";
|
||||
const enableUI = env?.ENABLE_UI === "true";
|
||||
// const livesyncLogsEnabled = env?.PRINT_LIVESYNC_LOGS === "true";
|
||||
const headless = !debuggerEnabled && !enableUI;
|
||||
const manifestJson = JSON.parse(fs.readFileSync("./manifest.json") + "");
|
||||
const packageJson = JSON.parse(fs.readFileSync("./package.json") + "");
|
||||
const updateInfo = JSON.stringify(fs.readFileSync("./updates.md") + "");
|
||||
const prod = false;
|
||||
const moduleAliasPlugin = {
|
||||
name: "module-alias",
|
||||
setup(build: any) {
|
||||
build.onResolve({ filter: /.(dev)(.ts|)$/ }, (args: any) => {
|
||||
// console.log(args.path);
|
||||
if (prod) {
|
||||
const prodTs = args.path.replace(".dev", ".prod");
|
||||
const statFile = prodTs.endsWith(".ts") ? prodTs : prodTs + ".ts";
|
||||
const realPath = path.join(args.resolveDir, statFile);
|
||||
console.log(`Checking ${statFile}`);
|
||||
if (fs.existsSync(realPath)) {
|
||||
console.log(`Replaced ${args.path} with ${prodTs}`);
|
||||
return {
|
||||
path: realPath,
|
||||
namespace: "file",
|
||||
};
|
||||
}
|
||||
}
|
||||
return null;
|
||||
});
|
||||
build.onResolve({ filter: /.(platform)(.ts|)$/ }, (args: any) => {
|
||||
// console.log(args.path);
|
||||
if (prod) {
|
||||
const prodTs = args.path.replace(".platform", ".obsidian");
|
||||
const statFile = prodTs.endsWith(".ts") ? prodTs : prodTs + ".ts";
|
||||
const realPath = path.join(args.resolveDir, statFile);
|
||||
console.log(`Checking ${statFile}`);
|
||||
if (fs.existsSync(realPath)) {
|
||||
console.log(`Replaced ${args.path} with ${prodTs}`);
|
||||
return {
|
||||
path: realPath,
|
||||
namespace: "file",
|
||||
};
|
||||
}
|
||||
}
|
||||
return null;
|
||||
});
|
||||
},
|
||||
};
|
||||
const externals = [
|
||||
"obsidian",
|
||||
"electron",
|
||||
"crypto",
|
||||
"@codemirror/autocomplete",
|
||||
"@codemirror/collab",
|
||||
"@codemirror/commands",
|
||||
"@codemirror/language",
|
||||
"@codemirror/lint",
|
||||
"@codemirror/search",
|
||||
"@codemirror/state",
|
||||
"@codemirror/view",
|
||||
"@lezer/common",
|
||||
"@lezer/highlight",
|
||||
"@lezer/lr",
|
||||
];
|
||||
const define = {
|
||||
MANIFEST_VERSION: `"${manifestJson.version}"`,
|
||||
PACKAGE_VERSION: `"${packageJson.version}"`,
|
||||
UPDATE_INFO: `${updateInfo}`,
|
||||
global: "globalThis",
|
||||
hostPlatform: `"${platform}"`,
|
||||
};
|
||||
export default defineConfig({
|
||||
plugins: [
|
||||
moduleAliasPlugin,
|
||||
inlineWorkerPlugin({
|
||||
external: externals,
|
||||
treeShaking: true,
|
||||
}),
|
||||
svelte({
|
||||
preprocess: sveltePreprocess(),
|
||||
compilerOptions: { css: "injected", preserveComments: false },
|
||||
}),
|
||||
],
|
||||
resolve: {
|
||||
alias: {
|
||||
obsidian: path.resolve(__dirname, "./test/harness/obsidian-mock.ts"),
|
||||
"@": path.resolve(__dirname, "./src"),
|
||||
"@lib": path.resolve(__dirname, "./src/lib/src"),
|
||||
src: path.resolve(__dirname, "./src"),
|
||||
},
|
||||
},
|
||||
esbuild: {
|
||||
define: define,
|
||||
target: "es2018",
|
||||
platform: "browser",
|
||||
},
|
||||
// define,
|
||||
server: {
|
||||
headers: {
|
||||
"Service-Worker-Allowed": "/",
|
||||
},
|
||||
port: 5173,
|
||||
},
|
||||
test: {
|
||||
env: env,
|
||||
testTimeout: 40000,
|
||||
hookTimeout: 50000,
|
||||
fileParallelism: false,
|
||||
isolate: true,
|
||||
watch: false,
|
||||
|
||||
// environment: "browser",
|
||||
include: ["test/**/*.test.ts"],
|
||||
coverage: {
|
||||
include: ["src/**/*.ts", "src/lib/src/**/*.ts", "src/**/*.svelte"],
|
||||
exclude: ["**/*.test.ts", "src/lib/**"],
|
||||
provider: "v8",
|
||||
reporter: ["text", "json", "html"],
|
||||
// ignoreEmptyLines: true,
|
||||
},
|
||||
browser: {
|
||||
isolate: true,
|
||||
commands: {
|
||||
grantClipboardPermissions,
|
||||
openWebPeer,
|
||||
closeWebPeer,
|
||||
acceptWebPeer,
|
||||
},
|
||||
provider: playwright({
|
||||
launchOptions: {
|
||||
args: ["--js-flags=--expose-gc"],
|
||||
// chromiumSandbox: true,
|
||||
},
|
||||
}),
|
||||
enabled: true,
|
||||
screenshotFailures: false,
|
||||
instances: [
|
||||
{
|
||||
execArgv: ["--js-flags=--expose-gc"],
|
||||
browser: "chromium",
|
||||
headless,
|
||||
isolate: true,
|
||||
inspector: debuggerEnabled
|
||||
? {
|
||||
waitForDebugger: true,
|
||||
enabled: true,
|
||||
}
|
||||
: undefined,
|
||||
printConsoleTrace: debuggerEnabled,
|
||||
onUnhandledError(error) {
|
||||
// Ignore certain errors
|
||||
const msg = error.message || "";
|
||||
if (msg.includes("Cannot create so many PeerConnections")) {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
},
|
||||
],
|
||||
headless,
|
||||
export default mergeConfig(
|
||||
viteConfig,
|
||||
defineConfig({
|
||||
test: {
|
||||
env: env,
|
||||
testTimeout: 40000,
|
||||
hookTimeout: 50000,
|
||||
fileParallelism: false,
|
||||
ui: debuggerEnabled || enableUI ? true : false,
|
||||
isolate: true,
|
||||
watch: false,
|
||||
|
||||
// environment: "browser",
|
||||
include: ["test/**/*.test.ts"],
|
||||
coverage: {
|
||||
include: ["src/**/*.ts", "src/lib/src/**/*.ts", "src/**/*.svelte"],
|
||||
exclude: ["**/*.test.ts", "src/lib/**"],
|
||||
provider: "v8",
|
||||
reporter: ["text", "json", "html"],
|
||||
// ignoreEmptyLines: true,
|
||||
},
|
||||
browser: {
|
||||
isolate: true,
|
||||
commands: {
|
||||
grantClipboardPermissions,
|
||||
openWebPeer,
|
||||
closeWebPeer,
|
||||
acceptWebPeer,
|
||||
},
|
||||
provider: playwright({
|
||||
launchOptions: {
|
||||
args: ["--js-flags=--expose-gc"],
|
||||
// chromiumSandbox: true,
|
||||
},
|
||||
}),
|
||||
enabled: true,
|
||||
screenshotFailures: false,
|
||||
instances: [
|
||||
{
|
||||
execArgv: ["--js-flags=--expose-gc"],
|
||||
browser: "chromium",
|
||||
headless,
|
||||
isolate: true,
|
||||
inspector: debuggerEnabled
|
||||
? {
|
||||
waitForDebugger: true,
|
||||
enabled: true,
|
||||
}
|
||||
: undefined,
|
||||
printConsoleTrace: debuggerEnabled,
|
||||
onUnhandledError(error) {
|
||||
// Ignore certain errors
|
||||
const msg = error.message || "";
|
||||
if (msg.includes("Cannot create so many PeerConnections")) {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
},
|
||||
],
|
||||
headless,
|
||||
fileParallelism: false,
|
||||
ui: debuggerEnabled || enableUI ? true : false,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
})
|
||||
);
|
||||
|
||||
19
vitest.config.unit.ts
Normal file
19
vitest.config.unit.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
import { defineConfig, mergeConfig } from "vitest/config";
|
||||
import viteConfig from "./vitest.config.common";
|
||||
|
||||
export default mergeConfig(
|
||||
viteConfig,
|
||||
defineConfig({
|
||||
test: {
|
||||
name: "unit-tests",
|
||||
include: ["**/*unit.test.ts"],
|
||||
exclude: ["test/**"],
|
||||
coverage: {
|
||||
include: ["src/**/*.ts"],
|
||||
exclude: ["**/*.test.ts", "src/lib/**/*.test.ts", "**/_*", "src/lib/apps", "src/lib/src/cli"],
|
||||
provider: "v8",
|
||||
reporter: ["text", "json", "html"],
|
||||
},
|
||||
},
|
||||
})
|
||||
);
|
||||
Reference in New Issue
Block a user