Add database for representing the data.json instead of just settings
This commit is contained in:
parent
a67bac63b6
commit
a38c15db95
3 changed files with 178 additions and 78 deletions
153
plugin/src/database/database.ts
Normal file
153
plugin/src/database/database.ts
Normal file
|
|
@ -0,0 +1,153 @@
|
||||||
|
import { Logger } from "src/logger";
|
||||||
|
|
||||||
|
export type DocumentId = string;
|
||||||
|
export type DocumentVersionId = number;
|
||||||
|
export type RelativePath = string;
|
||||||
|
|
||||||
|
export interface SyncSettings {
|
||||||
|
remoteUri: string;
|
||||||
|
token: string;
|
||||||
|
fullScanIntervalInSeconds: number;
|
||||||
|
fullScanEnabled: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const DEFAULT_SETTINGS: SyncSettings = {
|
||||||
|
remoteUri: "",
|
||||||
|
token: "",
|
||||||
|
fullScanIntervalInSeconds: 60,
|
||||||
|
fullScanEnabled: true,
|
||||||
|
};
|
||||||
|
|
||||||
|
export interface DocumentMetadata {
|
||||||
|
documentId: DocumentId;
|
||||||
|
parentVersionId: DocumentVersionId;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface StoredDatabase {
|
||||||
|
documents: Map<RelativePath, DocumentMetadata>;
|
||||||
|
settings: SyncSettings;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class Database {
|
||||||
|
private _documents: Map<RelativePath, DocumentMetadata> = new Map();
|
||||||
|
private _settings: SyncSettings;
|
||||||
|
private onSettingsChangeHandlers: Array<(settings: SyncSettings) => void> =
|
||||||
|
[];
|
||||||
|
|
||||||
|
public constructor(
|
||||||
|
initialState: Partial<StoredDatabase> | undefined,
|
||||||
|
private saveData: (data: any) => Promise<void>
|
||||||
|
) {
|
||||||
|
initialState = initialState || {};
|
||||||
|
if (
|
||||||
|
Object.prototype.hasOwnProperty.call(initialState, "documents") &&
|
||||||
|
initialState.documents
|
||||||
|
) {
|
||||||
|
for (const [relativePath, metadata] of Object.entries(
|
||||||
|
initialState.documents
|
||||||
|
)) {
|
||||||
|
this._documents.set(relativePath, metadata as DocumentMetadata);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Logger.getInstance().debug(
|
||||||
|
`Loaded documents ${JSON.stringify(
|
||||||
|
Object.fromEntries(this._documents.entries()),
|
||||||
|
null,
|
||||||
|
2
|
||||||
|
)}`
|
||||||
|
);
|
||||||
|
|
||||||
|
this._settings = Object.assign(
|
||||||
|
{},
|
||||||
|
DEFAULT_SETTINGS,
|
||||||
|
initialState.settings || {}
|
||||||
|
);
|
||||||
|
|
||||||
|
Logger.getInstance().debug(
|
||||||
|
`Loaded settings ${JSON.stringify(this._settings, null, 2)}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public getSettings(): SyncSettings {
|
||||||
|
return this._settings;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async setSettings(value: SyncSettings): Promise<void> {
|
||||||
|
this._settings = value;
|
||||||
|
this.onSettingsChangeHandlers.forEach((handler) => handler(value));
|
||||||
|
await this.save();
|
||||||
|
}
|
||||||
|
|
||||||
|
public addOnSettingsChangeHandlers(
|
||||||
|
handler: (settings: SyncSettings) => void
|
||||||
|
) {
|
||||||
|
this.onSettingsChangeHandlers.push(handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async setSetting<T extends keyof SyncSettings>(
|
||||||
|
key: T,
|
||||||
|
value: SyncSettings[T]
|
||||||
|
): Promise<void> {
|
||||||
|
this._settings[key] = value;
|
||||||
|
Logger.getInstance().debug(
|
||||||
|
`Setting ${key} to ${value}, new settings: ${JSON.stringify(
|
||||||
|
this._settings
|
||||||
|
)}`
|
||||||
|
);
|
||||||
|
await this.setSettings(this._settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async setDocument({
|
||||||
|
relativePath,
|
||||||
|
documentId,
|
||||||
|
parentVersionId,
|
||||||
|
}: {
|
||||||
|
relativePath: RelativePath;
|
||||||
|
documentId: DocumentId;
|
||||||
|
parentVersionId: DocumentVersionId;
|
||||||
|
}): Promise<void> {
|
||||||
|
this._documents.set(relativePath, {
|
||||||
|
documentId,
|
||||||
|
parentVersionId,
|
||||||
|
});
|
||||||
|
await this.save();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async moveDocument({
|
||||||
|
oldRelativePath,
|
||||||
|
relativePath,
|
||||||
|
documentId,
|
||||||
|
parentVersionId,
|
||||||
|
}: {
|
||||||
|
oldRelativePath: RelativePath;
|
||||||
|
relativePath: RelativePath;
|
||||||
|
documentId: DocumentId;
|
||||||
|
parentVersionId: DocumentVersionId;
|
||||||
|
}): Promise<void> {
|
||||||
|
this._documents.delete(oldRelativePath);
|
||||||
|
this._documents.set(relativePath, {
|
||||||
|
documentId,
|
||||||
|
parentVersionId,
|
||||||
|
});
|
||||||
|
await this.save();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async removeDocument(relativePath: RelativePath): Promise<void> {
|
||||||
|
this._documents.delete(relativePath);
|
||||||
|
await this.save();
|
||||||
|
}
|
||||||
|
|
||||||
|
public getDocument(
|
||||||
|
relativePath: RelativePath
|
||||||
|
): DocumentMetadata | undefined {
|
||||||
|
return this._documents.get(relativePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async save(): Promise<void> {
|
||||||
|
await this.saveData({
|
||||||
|
documents: Object.fromEntries(this._documents.entries()),
|
||||||
|
settings: this._settings,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,57 +0,0 @@
|
||||||
import { Logger } from "src/logger";
|
|
||||||
import SyncPlugin from "src/plugin";
|
|
||||||
|
|
||||||
export interface SyncSettings {
|
|
||||||
remoteUri: string;
|
|
||||||
token: string;
|
|
||||||
fullScanIntervalInSeconds: number;
|
|
||||||
fullScanEnabled: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const DEFAULT_SETTINGS: SyncSettings = {
|
|
||||||
remoteUri: "",
|
|
||||||
token: "",
|
|
||||||
fullScanIntervalInSeconds: 60,
|
|
||||||
fullScanEnabled: true,
|
|
||||||
};
|
|
||||||
|
|
||||||
export class SettingsContainer {
|
|
||||||
private _settings: SyncSettings;
|
|
||||||
|
|
||||||
private onChangeHandlers: Array<(settings: SyncSettings) => void> = [];
|
|
||||||
|
|
||||||
public constructor(private plugin: SyncPlugin, loadedSettings: any) {
|
|
||||||
Logger.getInstance().debug(
|
|
||||||
"Loaded settings " + JSON.stringify(loadedSettings, null, 2)
|
|
||||||
);
|
|
||||||
this._settings = Object.assign({}, DEFAULT_SETTINGS, loadedSettings);
|
|
||||||
}
|
|
||||||
|
|
||||||
public onChange(handler: (settings: SyncSettings) => void) {
|
|
||||||
this.onChangeHandlers.push(handler);
|
|
||||||
}
|
|
||||||
|
|
||||||
public getSettings(): SyncSettings {
|
|
||||||
return this._settings;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async setSettings(value: SyncSettings): Promise<void> {
|
|
||||||
this._settings = value;
|
|
||||||
await this.plugin.saveData(value);
|
|
||||||
this.onChangeHandlers.forEach((handler) => handler(value));
|
|
||||||
}
|
|
||||||
|
|
||||||
public async setSetting<T extends keyof SyncSettings>(
|
|
||||||
key: T,
|
|
||||||
value: SyncSettings[T]
|
|
||||||
): Promise<void> {
|
|
||||||
this._settings[key] = value;
|
|
||||||
Logger.getInstance().debug(
|
|
||||||
`Setting ${key} to ${value}, new settings: ${JSON.stringify(
|
|
||||||
this._settings
|
|
||||||
)}`
|
|
||||||
);
|
|
||||||
await this.plugin.saveData(this._settings);
|
|
||||||
this.onChangeHandlers.forEach((handler) => handler(this._settings));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -10,18 +10,17 @@ import {
|
||||||
} from "obsidian";
|
} from "obsidian";
|
||||||
|
|
||||||
import SyncPlugin from "src/plugin.js";
|
import SyncPlugin from "src/plugin.js";
|
||||||
import { SettingsContainer } from "./settings";
|
import { Database } from "src/database/database";
|
||||||
|
import { SyncServer } from "src/services/sync_service";
|
||||||
|
|
||||||
export class SyncSettingsTab extends PluginSettingTab {
|
export class SyncSettingsTab extends PluginSettingTab {
|
||||||
plugin: SyncPlugin;
|
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
app: App,
|
app: App,
|
||||||
plugin: SyncPlugin,
|
plugin: SyncPlugin,
|
||||||
private settingsContainer: SettingsContainer
|
private database: Database,
|
||||||
|
private syncServer: SyncServer
|
||||||
) {
|
) {
|
||||||
super(app, plugin);
|
super(app, plugin);
|
||||||
this.plugin = plugin;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
display(): void {
|
display(): void {
|
||||||
|
|
@ -38,25 +37,36 @@ export class SyncSettingsTab extends PluginSettingTab {
|
||||||
.addText((text) =>
|
.addText((text) =>
|
||||||
text
|
text
|
||||||
.setPlaceholder("https://example.com:8080/obsidian")
|
.setPlaceholder("https://example.com:8080/obsidian")
|
||||||
.setValue(this.settingsContainer.getSettings().remoteUri)
|
.setValue(this.database.getSettings().remoteUri)
|
||||||
.onChange((value) =>
|
.onChange((value) =>
|
||||||
this.settingsContainer.setSetting("remoteUri", value)
|
this.database.setSetting("remoteUri", value)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
.addButton((button) => button.setButtonText("Test Connection"));
|
.addButton((button) =>
|
||||||
|
button.setButtonText("Test Connection").onClick(async () => {
|
||||||
|
try {
|
||||||
|
const result = await this.syncServer.ping();
|
||||||
|
new Notice(
|
||||||
|
`Successfully connected to server! (server version: ${result.serverVersion})`
|
||||||
|
);
|
||||||
|
} catch (e) {
|
||||||
|
new Notice("Failed to connect to server: " + e);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
new Setting(containerEl)
|
new Setting(containerEl)
|
||||||
.setName("Access token")
|
.setName("Access token")
|
||||||
.setDesc(
|
.setDesc(
|
||||||
"Set the access token for the server that you can get from the server"
|
"Set the access token for the server that you can get from the server"
|
||||||
)
|
)
|
||||||
.setTooltip("todo, links to docs")
|
.setTooltip("todo, links to dcocs")
|
||||||
.addTextArea((text) =>
|
.addTextArea((text) =>
|
||||||
text
|
text
|
||||||
.setPlaceholder("ey...")
|
.setPlaceholder("ey...")
|
||||||
.setValue(this.settingsContainer.getSettings().token)
|
.setValue(this.database.getSettings().token)
|
||||||
.onChange((value) =>
|
.onChange((value) =>
|
||||||
this.settingsContainer.setSetting("token", value)
|
this.database.setSetting("token", value)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -68,14 +78,9 @@ export class SyncSettingsTab extends PluginSettingTab {
|
||||||
.setTooltip("todo, links to docs")
|
.setTooltip("todo, links to docs")
|
||||||
.addToggle((toggle) =>
|
.addToggle((toggle) =>
|
||||||
toggle
|
toggle
|
||||||
.setValue(
|
.setValue(this.database.getSettings().fullScanEnabled)
|
||||||
this.settingsContainer.getSettings().fullScanEnabled
|
|
||||||
)
|
|
||||||
.onChange((value) =>
|
.onChange((value) =>
|
||||||
this.settingsContainer.setSetting(
|
this.database.setSetting("fullScanEnabled", value)
|
||||||
"fullScanEnabled",
|
|
||||||
value
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
.addSlider((text) =>
|
.addSlider((text) =>
|
||||||
|
|
@ -83,11 +88,10 @@ export class SyncSettingsTab extends PluginSettingTab {
|
||||||
.setLimits(1, 3600, 1)
|
.setLimits(1, 3600, 1)
|
||||||
.setDynamicTooltip()
|
.setDynamicTooltip()
|
||||||
.setValue(
|
.setValue(
|
||||||
this.settingsContainer.getSettings()
|
this.database.getSettings().fullScanIntervalInSeconds
|
||||||
.fullScanIntervalInSeconds
|
|
||||||
)
|
)
|
||||||
.onChange((value) =>
|
.onChange((value) =>
|
||||||
this.settingsContainer.setSetting(
|
this.database.setSetting(
|
||||||
"fullScanIntervalInSeconds",
|
"fullScanIntervalInSeconds",
|
||||||
value
|
value
|
||||||
)
|
)
|
||||||
Loading…
Add table
Add a link
Reference in a new issue