Refactor: Move some functions from modules to services

This commit is contained in:
vorotamoroz
2026-02-12 06:27:29 +00:00
parent b1bba7685e
commit 787627a156
11 changed files with 75 additions and 81 deletions

Submodule src/lib updated: 4ff3cad80b...750ddbb082

View File

@@ -62,4 +62,14 @@ export abstract class AbstractModule {
get services() {
return this.core._services;
}
isMainReady() {
return this.services.appLifecycle.isReady();
}
isMainSuspended() {
return this.services.appLifecycle.isSuspended();
}
isDatabaseReady() {
return this.services.database.isDatabaseReady();
}
}

View File

@@ -10,20 +10,11 @@ export type ModuleKeys = keyof IObsidianModule;
export type ChainableModuleProps = ChainableExecuteFunction<ObsidianLiveSyncPlugin>;
export abstract class AbstractObsidianModule extends AbstractModule {
addCommand = this.plugin.addCommand.bind(this.plugin);
registerView = this.plugin.registerView.bind(this.plugin);
addRibbonIcon = this.plugin.addRibbonIcon.bind(this.plugin);
registerObsidianProtocolHandler = this.plugin.registerObsidianProtocolHandler.bind(this.plugin);
addCommand = this.services.API.addCommand.bind(this.services.API);
registerView = this.services.API.registerWindow.bind(this.services.API);
addRibbonIcon = this.services.API.addRibbonIcon.bind(this.services.API);
registerObsidianProtocolHandler = this.services.API.registerProtocolHandler.bind(this.services.API);
get localDatabase() {
return this.plugin.localDatabase;
}
get settings() {
return this.plugin.settings;
}
set settings(value) {
this.plugin.settings = value;
}
get app() {
return this.plugin.app;
}
@@ -35,18 +26,6 @@ export abstract class AbstractObsidianModule extends AbstractModule {
super(core);
}
saveSettings = this.plugin.saveSettings.bind(this.plugin);
isMainReady() {
return this.services.appLifecycle.isReady();
}
isMainSuspended() {
return this.services.appLifecycle.isSuspended();
}
isDatabaseReady() {
return this.services.database.isDatabaseReady();
}
//should be overridden
isThisModuleEnabled() {
return true;

View File

@@ -53,15 +53,6 @@ export class ModuleTargetFilter extends AbstractModule {
);
}
private _isFileSizeExceeded(size: number) {
if (this.settings.syncMaxSizeInMB > 0 && size > 0) {
if (this.settings.syncMaxSizeInMB * 1024 * 1024 < size) {
return true;
}
}
return false;
}
_markFileListPossiblyChanged(): void {
this.totalFileEventCount++;
}
@@ -110,7 +101,7 @@ export class ModuleTargetFilter extends AbstractModule {
const filepath = getStoragePathFromUXFileInfo(file);
const lc = filepath.toLowerCase();
if (this.services.setting.shouldCheckCaseInsensitively()) {
if (this.services.vault.shouldCheckCaseInsensitively()) {
if (lc in fileCount && fileCount[lc] > 1) {
return false;
}
@@ -178,7 +169,6 @@ export class ModuleTargetFilter extends AbstractModule {
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));
}

View File

@@ -79,15 +79,6 @@ export class ModuleFileAccessObsidian extends AbstractObsidianModule implements
return Promise.resolve(true);
}
_isStorageInsensitive(): boolean {
return this.vaultAccess.isStorageInsensitive();
}
_shouldCheckCaseInsensitive(): boolean {
if (this.services.vault.isStorageInsensitive()) return false;
return !this.settings.handleFilenameCaseSensitive;
}
async writeFileAuto(path: string, data: string | ArrayBuffer, opt?: UXDataWriteOptions): Promise<boolean> {
const file = this.vaultAccess.getAbstractFileByPath(path);
if (file instanceof TFile) {
@@ -386,8 +377,6 @@ export class ModuleFileAccessObsidian extends AbstractObsidianModule implements
super(plugin, core);
}
onBindFunction(core: LiveSyncCore, services: InjectableServiceHub): void {
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));

View File

@@ -1,11 +1,12 @@
import { type App, TFile, type DataWriteOptions, TFolder, TAbstractFile } from "../../../deps.ts";
import { Logger } from "../../../lib/src/common/logger.ts";
import { isPlainText } from "../../../lib/src/string_and_binary/path.ts";
import type { FilePath, HasSettings, UXFileInfoStub } from "../../../lib/src/common/types.ts";
import type { FilePath, UXFileInfoStub } from "../../../lib/src/common/types.ts";
import { createBinaryBlob, isDocContentSame } from "../../../lib/src/common/utils.ts";
import type { InternalFileInfo } from "../../../common/types.ts";
import { markChangesAreSame } from "../../../common/utils.ts";
import type { StorageAccess } from "../../interfaces/StorageAccess.ts";
import type { LiveSyncCore } from "@/main.ts";
function toArrayBuffer(arr: Uint8Array<ArrayBuffer> | ArrayBuffer | DataView<ArrayBuffer>): ArrayBuffer {
if (arr instanceof Uint8Array) {
return arr.buffer;
@@ -18,9 +19,9 @@ function toArrayBuffer(arr: Uint8Array<ArrayBuffer> | ArrayBuffer | DataView<Arr
export class SerializedFileAccess {
app: App;
plugin: HasSettings<{ handleFilenameCaseSensitive: boolean }>;
plugin: LiveSyncCore;
storageAccess: StorageAccess;
constructor(app: App, plugin: SerializedFileAccess["plugin"], storageAccess: StorageAccess) {
constructor(app: App, plugin: LiveSyncCore, storageAccess: StorageAccess) {
this.app = app;
this.plugin = plugin;
this.storageAccess = storageAccess;
@@ -163,8 +164,7 @@ export class SerializedFileAccess {
}
isStorageInsensitive(): boolean {
//@ts-ignore
return this.app.vault.adapter.insensitive ?? true;
return this.plugin.services.vault.isStorageInsensitive();
}
getAbstractFileByPathInsensitive(path: FilePath | string): TAbstractFile | null {

View File

@@ -8,8 +8,7 @@ import {
type LOG_LEVEL,
} from "octagonal-wheels/common/logger";
import { Notice, requestUrl, type RequestUrlParam, type RequestUrlResponse } from "../../deps.ts";
import { type CouchDBCredentials, type EntryDoc, type FilePath } from "../../lib/src/common/types.ts";
import { getPathFromTFile } from "../../common/utils.ts";
import { type CouchDBCredentials, type EntryDoc } from "../../lib/src/common/types.ts";
import { isCloudantURI, isValidRemoteCouchDBURI } from "../../lib/src/pouchdb/utils_couchdb.ts";
import { replicationFilter } from "@/lib/src/pouchdb/compress.ts";
import { disableEncryption } from "@/lib/src/pouchdb/encryption.ts";
@@ -279,23 +278,6 @@ export class ModuleObsidianAPI extends AbstractObsidianModule {
}
}
_vaultName(): string {
return this.app.vault.getName();
}
_getVaultName(): string {
return (
this.services.vault.vaultName() +
(this.settings?.additionalSuffixOfDatabaseName ? "-" + this.settings.additionalSuffixOfDatabaseName : "")
);
}
_getActiveFilePath(): FilePath | undefined {
const file = this.app.workspace.getActiveFile();
if (file) {
return getPathFromTFile(file);
}
return undefined;
}
private _reportUnresolvedMessages(): Promise<(string | Error)[]> {
return Promise.resolve([...this._previousErrors]);
}
@@ -303,9 +285,6 @@ export class ModuleObsidianAPI extends AbstractObsidianModule {
onBindFunction(core: LiveSyncCore, services: typeof core.services) {
services.API.isLastPostFailedDueToPayloadSize.setHandler(this._getLastPostFailedBySize.bind(this));
services.remote.connect.setHandler(this._connectRemoteCouchDB.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.appLifecycle.getUnresolvedMessages.addHandler(this._reportUnresolvedMessages.bind(this));
}
}

View File

@@ -251,7 +251,7 @@ export class ModuleLog extends AbstractObsidianModule {
}
}
// Case Sensitivity
if (this.services.setting.shouldCheckCaseInsensitively()) {
if (this.services.vault.shouldCheckCaseInsensitively()) {
const f = this.core.storageAccess
.getFiles()
.map((e) => e.path)

View File

@@ -13,12 +13,12 @@ import {
ObsidianRemoteService,
ObsidianSettingService,
ObsidianTweakValueService,
ObsidianVaultService,
ObsidianTestService,
ObsidianDatabaseEventService,
ObsidianPathService,
ObsidianConfigService,
} from "./ObsidianServices";
import { ObsidianVaultService } from "./ObsidianVaultService";
import { ObsidianUIService } from "./ObsidianUIService";
// InjectableServiceHub
@@ -37,7 +37,9 @@ export class ObsidianServiceHub extends InjectableServiceHub<ObsidianServiceCont
const remote = new ObsidianRemoteService(context);
const setting = new ObsidianSettingService(context);
const tweakValue = new ObsidianTweakValueService(context);
const vault = new ObsidianVaultService(context);
const vault = new ObsidianVaultService(context, {
settingService: setting,
});
const test = new ObsidianTestService(context);
const databaseEvents = new ObsidianDatabaseEventService(context);
const path = new ObsidianPathService(context);

View File

@@ -11,7 +11,6 @@ import { InjectableReplicatorService } from "@lib/services/implements/injectable
import { InjectableSettingService } from "@lib/services/implements/injectable/InjectableSettingService";
import { InjectableTestService } from "@lib/services/implements/injectable/InjectableTestService";
import { InjectableTweakValueService } from "@lib/services/implements/injectable/InjectableTweakValueService";
import { InjectableVaultService } from "@lib/services/implements/injectable/InjectableVaultService";
import { ConfigServiceBrowserCompat } from "@lib/services/implements/browser/ConfigServiceBrowserCompat";
import type { ObsidianServiceContext } from "@lib/services/implements/obsidian/ObsidianServiceContext.ts";
import { Platform } from "@/deps";
@@ -19,6 +18,7 @@ import type { SimpleStore } from "@/lib/src/common/utils";
import type { IDatabaseService } from "@/lib/src/services/base/IService";
import { handlers } from "@/lib/src/services/lib/HandlerUtils";
import { ObsHttpHandler } from "../essentialObsidian/APILib/ObsHttpHandler";
import type { Command, ViewCreator } from "obsidian";
// All Services will be migrated to be based on Plain Services, not Injectable Services.
// This is a migration step.
@@ -92,6 +92,20 @@ export class ObsidianAPIService extends InjectableAPIService<ObsidianServiceCont
override getPluginVersion(): string {
return this.context.plugin.manifest.version;
}
addCommand<TCommand extends Command>(command: TCommand): TCommand {
return this.context.plugin.addCommand(command) as TCommand;
}
registerWindow(type: string, factory: ViewCreator): void {
return this.context.plugin.registerView(type, factory);
}
addRibbonIcon(icon: string, title: string, callback: (evt: MouseEvent) => any): HTMLElement {
return this.context.plugin.addRibbonIcon(icon, title, callback);
}
registerProtocolHandler(action: string, handler: (params: Record<string, string>) => any): void {
return this.context.plugin.registerObsidianProtocolHandler(action, handler);
}
}
export class ObsidianPathService extends InjectablePathService<ObsidianServiceContext> {}
export class ObsidianDatabaseService extends InjectableDatabaseService<ObsidianServiceContext> {
@@ -117,8 +131,6 @@ export class ObsidianAppLifecycleService extends InjectableAppLifecycleService<O
export class ObsidianSettingService extends InjectableSettingService<ObsidianServiceContext> {}
// InjectableTweakValueService
export class ObsidianTweakValueService extends InjectableTweakValueService<ObsidianServiceContext> {}
// InjectableVaultService
export class ObsidianVaultService extends InjectableVaultService<ObsidianServiceContext> {}
// InjectableTestService
export class ObsidianTestService extends InjectableTestService<ObsidianServiceContext> {}
export class ObsidianConfigService extends ConfigServiceBrowserCompat<ObsidianServiceContext> {}

View File

@@ -0,0 +1,33 @@
import { getPathFromTFile } from "@/common/utils";
import { InjectableVaultService } from "@/lib/src/services/implements/injectable/InjectableVaultService";
import type { ObsidianServiceContext } from "@/lib/src/services/implements/obsidian/ObsidianServiceContext";
import type { FilePath } from "@/lib/src/common/types";
declare module "obsidian" {
interface DataAdapter {
insensitive?: boolean;
}
}
// InjectableVaultService
export class ObsidianVaultService extends InjectableVaultService<ObsidianServiceContext> {
vaultName(): string {
return this.context.app.vault.getName();
}
getActiveFilePath(): FilePath | undefined {
const file = this.context.app.workspace.getActiveFile();
if (file) {
return getPathFromTFile(file);
}
return undefined;
}
isStorageInsensitive(): boolean {
return this.context.app.vault.adapter.insensitive ?? true;
}
override shouldCheckCaseInsensitively(): boolean {
// If the storage is insensitive, always return false, that because no need to check again.
if (this.isStorageInsensitive()) return false;
return super.shouldCheckCaseInsensitively(); // Check the setting
}
}