mirror of
https://github.com/vrtmrz/obsidian-livesync.git
synced 2026-05-29 18:42:56 +00:00
chore(format): no intentional behaviour change - runs pretty
This commit is contained in:
@@ -1,12 +1,9 @@
|
||||
// This file is based on a file that was published by the @remotely-save, under the Apache 2 License.
|
||||
// I would love to express my deepest gratitude to the original authors for their hard work and dedication. Without their contributions, this project would not have been possible.
|
||||
//
|
||||
//
|
||||
// Original Implementation is here: https://github.com/remotely-save/remotely-save/blob/28b99557a864ef59c19d2ad96101196e401718f0/src/remoteForS3.ts
|
||||
|
||||
import {
|
||||
FetchHttpHandler,
|
||||
type FetchHttpHandlerOptions,
|
||||
} from "@smithy/fetch-http-handler";
|
||||
import { FetchHttpHandler, type FetchHttpHandlerOptions } from "@smithy/fetch-http-handler";
|
||||
import { HttpRequest, HttpResponse, type HttpHandlerOptions } from "@smithy/protocol-http";
|
||||
//@ts-ignore
|
||||
import { requestTimeout } from "@smithy/fetch-http-handler/dist-es/request-timeout";
|
||||
@@ -25,20 +22,13 @@ import { requestUrl, type RequestUrlParam } from "../../../deps.ts";
|
||||
export class ObsHttpHandler extends FetchHttpHandler {
|
||||
requestTimeoutInMs: number | undefined;
|
||||
reverseProxyNoSignUrl: string | undefined;
|
||||
constructor(
|
||||
options?: FetchHttpHandlerOptions,
|
||||
reverseProxyNoSignUrl?: string
|
||||
) {
|
||||
constructor(options?: FetchHttpHandlerOptions, reverseProxyNoSignUrl?: string) {
|
||||
super(options);
|
||||
this.requestTimeoutInMs =
|
||||
options === undefined ? undefined : options.requestTimeout;
|
||||
this.requestTimeoutInMs = options === undefined ? undefined : options.requestTimeout;
|
||||
this.reverseProxyNoSignUrl = reverseProxyNoSignUrl;
|
||||
}
|
||||
// eslint-disable-next-line require-await
|
||||
async handle(
|
||||
request: HttpRequest,
|
||||
{ abortSignal }: HttpHandlerOptions = {}
|
||||
): Promise<{ response: HttpResponse }> {
|
||||
async handle(request: HttpRequest, { abortSignal }: HttpHandlerOptions = {}): Promise<{ response: HttpResponse }> {
|
||||
if (abortSignal?.aborted) {
|
||||
const abortError = new Error("Request aborted");
|
||||
abortError.name = "AbortError";
|
||||
@@ -54,18 +44,13 @@ export class ObsHttpHandler extends FetchHttpHandler {
|
||||
}
|
||||
|
||||
const { port, method } = request;
|
||||
let url = `${request.protocol}//${request.hostname}${port ? `:${port}` : ""
|
||||
}${path}`;
|
||||
if (
|
||||
this.reverseProxyNoSignUrl !== undefined &&
|
||||
this.reverseProxyNoSignUrl !== ""
|
||||
) {
|
||||
let url = `${request.protocol}//${request.hostname}${port ? `:${port}` : ""}${path}`;
|
||||
if (this.reverseProxyNoSignUrl !== undefined && this.reverseProxyNoSignUrl !== "") {
|
||||
const urlObj = new URL(url);
|
||||
urlObj.host = this.reverseProxyNoSignUrl;
|
||||
url = urlObj.href;
|
||||
}
|
||||
const body =
|
||||
method === "GET" || method === "HEAD" ? undefined : request.body;
|
||||
const body = method === "GET" || method === "HEAD" ? undefined : request.body;
|
||||
|
||||
const transformedHeaders: Record<string, string> = {};
|
||||
for (const key of Object.keys(request.headers)) {
|
||||
|
||||
@@ -1,17 +1,22 @@
|
||||
import { AbstractObsidianModule, type IObsidianModule } from '../AbstractObsidianModule.ts';
|
||||
import { LOG_LEVEL_DEBUG, LOG_LEVEL_VERBOSE } from 'octagonal-wheels/common/logger';
|
||||
import { Notice, requestUrl, type RequestUrlParam, type RequestUrlResponse } from '../../deps.ts';
|
||||
import { type EntryDoc, type FilePathWithPrefix } from '../../lib/src/common/types.ts';
|
||||
import { getPathFromTFile } from '../../common/utils.ts';
|
||||
import { disableEncryption, enableEncryption, isCloudantURI, isValidRemoteCouchDBURI, replicationFilter } from '../../lib/src/pouchdb/utils_couchdb.ts';
|
||||
import { setNoticeClass } from '../../lib/src/mock_and_interop/wrapper.ts';
|
||||
import { ObsHttpHandler } from './APILib/ObsHttpHandler.ts';
|
||||
import { PouchDB } from '../../lib/src/pouchdb/pouchdb-browser.ts';
|
||||
import { reactive, reactiveSource } from 'octagonal-wheels/dataobject/reactive';
|
||||
import { AbstractObsidianModule, type IObsidianModule } from "../AbstractObsidianModule.ts";
|
||||
import { LOG_LEVEL_DEBUG, LOG_LEVEL_VERBOSE } from "octagonal-wheels/common/logger";
|
||||
import { Notice, requestUrl, type RequestUrlParam, type RequestUrlResponse } from "../../deps.ts";
|
||||
import { type EntryDoc, type FilePathWithPrefix } from "../../lib/src/common/types.ts";
|
||||
import { getPathFromTFile } from "../../common/utils.ts";
|
||||
import {
|
||||
disableEncryption,
|
||||
enableEncryption,
|
||||
isCloudantURI,
|
||||
isValidRemoteCouchDBURI,
|
||||
replicationFilter,
|
||||
} from "../../lib/src/pouchdb/utils_couchdb.ts";
|
||||
import { setNoticeClass } from "../../lib/src/mock_and_interop/wrapper.ts";
|
||||
import { ObsHttpHandler } from "./APILib/ObsHttpHandler.ts";
|
||||
import { PouchDB } from "../../lib/src/pouchdb/pouchdb-browser.ts";
|
||||
import { reactive, reactiveSource } from "octagonal-wheels/dataobject/reactive";
|
||||
|
||||
setNoticeClass(Notice);
|
||||
|
||||
|
||||
async function fetchByAPI(request: RequestUrlParam): Promise<RequestUrlResponse> {
|
||||
const ret = await requestUrl(request);
|
||||
if (ret.status - (ret.status % 100) !== 200) {
|
||||
@@ -27,11 +32,11 @@ async function fetchByAPI(request: RequestUrlParam): Promise<RequestUrlResponse>
|
||||
}
|
||||
|
||||
export class ModuleObsidianAPI extends AbstractObsidianModule implements IObsidianModule {
|
||||
|
||||
_customHandler!: ObsHttpHandler;
|
||||
authHeaderSource = reactiveSource<string>("");
|
||||
authHeader = reactive(() =>
|
||||
this.authHeaderSource.value == "" ? "" : "Basic " + window.btoa(this.authHeaderSource.value));
|
||||
this.authHeaderSource.value == "" ? "" : "Basic " + window.btoa(this.authHeaderSource.value)
|
||||
);
|
||||
|
||||
last_successful_post = false;
|
||||
$$customFetchHandler(): ObsHttpHandler {
|
||||
@@ -42,11 +47,20 @@ export class ModuleObsidianAPI extends AbstractObsidianModule implements IObsidi
|
||||
return !this.last_successful_post;
|
||||
}
|
||||
|
||||
async $$connectRemoteCouchDB(uri: string, auth: { username: string; password: string }, disableRequestURI: boolean, passphrase: string | false, useDynamicIterationCount: boolean, performSetup: boolean, skipInfo: boolean, compression: boolean): Promise<string | { db: PouchDB.Database<EntryDoc>; info: PouchDB.Core.DatabaseInfo }> {
|
||||
async $$connectRemoteCouchDB(
|
||||
uri: string,
|
||||
auth: { username: string; password: string },
|
||||
disableRequestURI: boolean,
|
||||
passphrase: string | false,
|
||||
useDynamicIterationCount: boolean,
|
||||
performSetup: boolean,
|
||||
skipInfo: boolean,
|
||||
compression: boolean
|
||||
): Promise<string | { db: PouchDB.Database<EntryDoc>; info: PouchDB.Core.DatabaseInfo }> {
|
||||
if (!isValidRemoteCouchDBURI(uri)) return "Remote URI is not valid";
|
||||
if (uri.toLowerCase() != uri) return "Remote URI and database name could not contain capital letters.";
|
||||
if (uri.indexOf(" ") !== -1) return "Remote URI and database name could not contain spaces.";
|
||||
const userNameAndPassword = (auth.username && auth.password) ? `${auth.username}:${auth.password}` : "";
|
||||
const userNameAndPassword = auth.username && auth.password ? `${auth.username}:${auth.password}` : "";
|
||||
if (this.authHeaderSource.value != userNameAndPassword) {
|
||||
this.authHeaderSource.value = userNameAndPassword;
|
||||
}
|
||||
@@ -135,7 +149,9 @@ export class ModuleObsidianAPI extends AbstractObsidianModule implements IObsidi
|
||||
if (Math.floor(response.status / 100) !== 2) {
|
||||
if (method != "GET" && localURL.indexOf("/_local/") === -1 && !localURL.endsWith("/")) {
|
||||
const r = response.clone();
|
||||
this._log(`The request may have failed. The reason sent by the server: ${r.status}: ${r.statusText}`);
|
||||
this._log(
|
||||
`The request may have failed. The reason sent by the server: ${r.status}: ${r.statusText}`
|
||||
);
|
||||
|
||||
try {
|
||||
this._log(await (await r.blob()).text(), LOG_LEVEL_VERBOSE);
|
||||
@@ -144,7 +160,10 @@ export class ModuleObsidianAPI extends AbstractObsidianModule implements IObsidi
|
||||
this._log(_, LOG_LEVEL_VERBOSE);
|
||||
}
|
||||
} else {
|
||||
this._log(`Just checkpoint or some server information has been missing. The 404 error shown above is not an error.`, LOG_LEVEL_VERBOSE)
|
||||
this._log(
|
||||
`Just checkpoint or some server information has been missing. The 404 error shown above is not an error.`,
|
||||
LOG_LEVEL_VERBOSE
|
||||
);
|
||||
}
|
||||
}
|
||||
return response;
|
||||
@@ -178,7 +197,8 @@ export class ModuleObsidianAPI extends AbstractObsidianModule implements IObsidi
|
||||
} catch (ex: any) {
|
||||
let msg = `${ex?.name}:${ex?.message}`;
|
||||
if (ex?.name == "TypeError" && ex?.message == "Failed to fetch") {
|
||||
msg += "\n**Note** This error caused by many reasons. The only sure thing is you didn't touch the server.\nTo check details, open inspector.";
|
||||
msg +=
|
||||
"\n**Note** This error caused by many reasons. The only sure thing is you didn't touch the server.\nTo check details, open inspector.";
|
||||
}
|
||||
this._log(ex, LOG_LEVEL_VERBOSE);
|
||||
return msg;
|
||||
@@ -194,7 +214,10 @@ export class ModuleObsidianAPI extends AbstractObsidianModule implements IObsidi
|
||||
return this.app.vault.getName();
|
||||
}
|
||||
$$getVaultName(): string {
|
||||
return this.core.$$vaultName() + (this.settings?.additionalSuffixOfDatabaseName ? ("-" + this.settings.additionalSuffixOfDatabaseName) : "");
|
||||
return (
|
||||
this.core.$$vaultName() +
|
||||
(this.settings?.additionalSuffixOfDatabaseName ? "-" + this.settings.additionalSuffixOfDatabaseName : "")
|
||||
);
|
||||
}
|
||||
$$getActiveFilePath(): FilePathWithPrefix | undefined {
|
||||
const file = this.app.workspace.getActiveFile();
|
||||
@@ -205,7 +228,6 @@ export class ModuleObsidianAPI extends AbstractObsidianModule implements IObsidi
|
||||
}
|
||||
|
||||
$anyGetAppId(): Promise<string | undefined> {
|
||||
return Promise.resolve(`${("appId" in this.app ? this.app.appId : "")}`);
|
||||
return Promise.resolve(`${"appId" in this.app ? this.app.appId : ""}`);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,25 +1,35 @@
|
||||
import { AbstractObsidianModule, type IObsidianModule } from '../AbstractObsidianModule.ts';
|
||||
import { EVENT_FILE_RENAMED, EVENT_LEAF_ACTIVE_CHANGED, eventHub } from '../../common/events.js';
|
||||
import { LOG_LEVEL_NOTICE, LOG_LEVEL_VERBOSE } from 'octagonal-wheels/common/logger';
|
||||
import { scheduleTask } from 'octagonal-wheels/concurrency/task';
|
||||
import { type TFile } from '../../deps.ts';
|
||||
import { fireAndForget } from 'octagonal-wheels/promises';
|
||||
import { type FilePathWithPrefix } from '../../lib/src/common/types.ts';
|
||||
import { reactive, reactiveSource } from 'octagonal-wheels/dataobject/reactive';
|
||||
import { collectingChunks, pluginScanningCount, hiddenFilesEventCount, hiddenFilesProcessingCount } from '../../lib/src/mock_and_interop/stores.ts';
|
||||
import { AbstractObsidianModule, type IObsidianModule } from "../AbstractObsidianModule.ts";
|
||||
import { EVENT_FILE_RENAMED, EVENT_LEAF_ACTIVE_CHANGED, eventHub } from "../../common/events.js";
|
||||
import { LOG_LEVEL_NOTICE, LOG_LEVEL_VERBOSE } from "octagonal-wheels/common/logger";
|
||||
import { scheduleTask } from "octagonal-wheels/concurrency/task";
|
||||
import { type TFile } from "../../deps.ts";
|
||||
import { fireAndForget } from "octagonal-wheels/promises";
|
||||
import { type FilePathWithPrefix } from "../../lib/src/common/types.ts";
|
||||
import { reactive, reactiveSource } from "octagonal-wheels/dataobject/reactive";
|
||||
import {
|
||||
collectingChunks,
|
||||
pluginScanningCount,
|
||||
hiddenFilesEventCount,
|
||||
hiddenFilesProcessingCount,
|
||||
} from "../../lib/src/mock_and_interop/stores.ts";
|
||||
|
||||
export class ModuleObsidianEvents extends AbstractObsidianModule implements IObsidianModule {
|
||||
|
||||
$everyOnloadStart(): Promise<boolean> {
|
||||
// this.registerEvent(this.app.workspace.on("editor-change", ));
|
||||
this.plugin.registerEvent(this.app.vault.on("rename", (file, oldPath) => {
|
||||
eventHub.emitEvent(EVENT_FILE_RENAMED, { newPath: file.path as FilePathWithPrefix, old: oldPath as FilePathWithPrefix });
|
||||
}));
|
||||
this.plugin.registerEvent(this.app.workspace.on("active-leaf-change", () => eventHub.emitEvent(EVENT_LEAF_ACTIVE_CHANGED)));
|
||||
this.plugin.registerEvent(
|
||||
this.app.vault.on("rename", (file, oldPath) => {
|
||||
eventHub.emitEvent(EVENT_FILE_RENAMED, {
|
||||
newPath: file.path as FilePathWithPrefix,
|
||||
old: oldPath as FilePathWithPrefix,
|
||||
});
|
||||
})
|
||||
);
|
||||
this.plugin.registerEvent(
|
||||
this.app.workspace.on("active-leaf-change", () => eventHub.emitEvent(EVENT_LEAF_ACTIVE_CHANGED))
|
||||
);
|
||||
return Promise.resolve(true);
|
||||
}
|
||||
|
||||
|
||||
$$performRestart(): void {
|
||||
this._performAppReload();
|
||||
}
|
||||
@@ -33,9 +43,7 @@ export class ModuleObsidianEvents extends AbstractObsidianModule implements IObs
|
||||
|
||||
swapSaveCommand() {
|
||||
this._log("Modifying callback of the save command", LOG_LEVEL_VERBOSE);
|
||||
const saveCommandDefinition = (this.app as any).commands?.commands?.[
|
||||
"editor:save-file"
|
||||
];
|
||||
const saveCommandDefinition = (this.app as any).commands?.commands?.["editor:save-file"];
|
||||
const save = saveCommandDefinition?.callback;
|
||||
if (typeof save === "function") {
|
||||
this.initialCallback = save;
|
||||
@@ -60,7 +68,7 @@ export class ModuleObsidianEvents extends AbstractObsidianModule implements IObs
|
||||
//@ts-ignore
|
||||
window.CodeMirrorAdapter.commands.save = () => {
|
||||
//@ts-ignore
|
||||
_this.app.commands.executeCommandById('editor:save-file')
|
||||
_this.app.commands.executeCommandById("editor:save-file");
|
||||
// _this.app.performCommand('editor:save-file');
|
||||
};
|
||||
}
|
||||
@@ -158,7 +166,6 @@ export class ModuleObsidianEvents extends AbstractObsidianModule implements IObs
|
||||
return Promise.resolve(true);
|
||||
}
|
||||
|
||||
|
||||
$$askReload(message?: string) {
|
||||
if (this.core.$$isReloadingScheduled()) {
|
||||
this._log(`Reloading is already scheduled`, LOG_LEVEL_VERBOSE);
|
||||
@@ -168,16 +175,17 @@ export class ModuleObsidianEvents extends AbstractObsidianModule implements IObs
|
||||
const RESTART_NOW = "Yes, restart immediately";
|
||||
const RESTART_AFTER_STABLE = "Yes, schedule a restart after stabilisation";
|
||||
const RETRY_LATER = "No, Leave it to me";
|
||||
const ret = await this.core.confirm.askSelectStringDialogue(message || "Do you want to restart and reload Obsidian now?", [
|
||||
RESTART_AFTER_STABLE,
|
||||
RESTART_NOW,
|
||||
RETRY_LATER], { defaultAction: RETRY_LATER });
|
||||
const ret = await this.core.confirm.askSelectStringDialogue(
|
||||
message || "Do you want to restart and reload Obsidian now?",
|
||||
[RESTART_AFTER_STABLE, RESTART_NOW, RETRY_LATER],
|
||||
{ defaultAction: RETRY_LATER }
|
||||
);
|
||||
if (ret == RESTART_NOW) {
|
||||
this._performAppReload();
|
||||
} else if (ret == RESTART_AFTER_STABLE) {
|
||||
this.core.$$scheduleAppReload();
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
$$scheduleAppReload() {
|
||||
if (!this.core._totalProcessingCount) {
|
||||
@@ -194,24 +202,39 @@ export class ModuleObsidianEvents extends AbstractObsidianModule implements IObs
|
||||
const proc = this.core.processingFileEventCount.value;
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
const __ = __tick.value;
|
||||
return dbCount + replicationCount + storageApplyingCount + chunkCount + pluginScanCount + hiddenFilesCount + conflictProcessCount + e + proc;
|
||||
})
|
||||
this.plugin.registerInterval(setInterval(() => {
|
||||
__tick.value++;
|
||||
}, 1000) as unknown as number);
|
||||
return (
|
||||
dbCount +
|
||||
replicationCount +
|
||||
storageApplyingCount +
|
||||
chunkCount +
|
||||
pluginScanCount +
|
||||
hiddenFilesCount +
|
||||
conflictProcessCount +
|
||||
e +
|
||||
proc
|
||||
);
|
||||
});
|
||||
this.plugin.registerInterval(
|
||||
setInterval(() => {
|
||||
__tick.value++;
|
||||
}, 1000) as unknown as number
|
||||
);
|
||||
|
||||
let stableCheck = 3;
|
||||
this.core._totalProcessingCount.onChanged(e => {
|
||||
this.core._totalProcessingCount.onChanged((e) => {
|
||||
if (e.value == 0) {
|
||||
if (stableCheck-- <= 0) {
|
||||
this._performAppReload();
|
||||
}
|
||||
this._log(`Obsidian will be restarted soon! (Within ${stableCheck} seconds)`, LOG_LEVEL_NOTICE, "restart-notice");
|
||||
this._log(
|
||||
`Obsidian will be restarted soon! (Within ${stableCheck} seconds)`,
|
||||
LOG_LEVEL_NOTICE,
|
||||
"restart-notice"
|
||||
);
|
||||
} else {
|
||||
stableCheck = 3;
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,9 +4,7 @@ import { LOG_LEVEL_NOTICE, type FilePathWithPrefix } from "../../lib/src/common/
|
||||
import { AbstractObsidianModule, type IObsidianModule } from "../AbstractObsidianModule.ts";
|
||||
|
||||
export class ModuleObsidianMenu extends AbstractObsidianModule implements IObsidianModule {
|
||||
|
||||
$everyOnloadStart(): Promise<boolean> {
|
||||
|
||||
// UI
|
||||
addIcon(
|
||||
"replicate",
|
||||
@@ -22,7 +20,6 @@ export class ModuleObsidianMenu extends AbstractObsidianModule implements IObsid
|
||||
await this.core.$$replicate(true);
|
||||
}).addClass("livesync-ribbon-replicate");
|
||||
|
||||
|
||||
this.addCommand({
|
||||
id: "livesync-replicate",
|
||||
name: "Replicate now",
|
||||
@@ -84,9 +81,9 @@ export class ModuleObsidianMenu extends AbstractObsidianModule implements IObsid
|
||||
id: "livesync-scan-files",
|
||||
name: "Scan storage and database again",
|
||||
callback: async () => {
|
||||
await this.core.$$performFullScan(true)
|
||||
}
|
||||
})
|
||||
await this.core.$$performFullScan(true);
|
||||
},
|
||||
});
|
||||
|
||||
this.addCommand({
|
||||
id: "livesync-runbatch",
|
||||
@@ -94,7 +91,7 @@ export class ModuleObsidianMenu extends AbstractObsidianModule implements IObsid
|
||||
callback: async () => {
|
||||
await this.core.$everyCommitPendingFileEvent();
|
||||
},
|
||||
})
|
||||
});
|
||||
|
||||
// TODO, Replicator is possibly one of features. It should be moved to features.
|
||||
this.addCommand({
|
||||
@@ -103,9 +100,8 @@ export class ModuleObsidianMenu extends AbstractObsidianModule implements IObsid
|
||||
callback: () => {
|
||||
this.core.replicator.terminateSync();
|
||||
},
|
||||
})
|
||||
});
|
||||
return Promise.resolve(true);
|
||||
|
||||
}
|
||||
$everyOnload(): Promise<boolean> {
|
||||
this.app.workspace.onLayoutReady(this.core.$$onLiveSyncReady.bind(this.core));
|
||||
@@ -124,13 +120,10 @@ export class ModuleObsidianMenu extends AbstractObsidianModule implements IObsid
|
||||
await leaves[0].setViewState({
|
||||
type: viewType,
|
||||
active: true,
|
||||
})
|
||||
});
|
||||
}
|
||||
if (leaves.length > 0) {
|
||||
this.app.workspace.revealLeaf(
|
||||
leaves[0]
|
||||
);
|
||||
this.app.workspace.revealLeaf(leaves[0]);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user