mirror of
https://github.com/vrtmrz/obsidian-livesync.git
synced 2026-08-31 15:57:06 +00:00
Compose replication lifecycle without a legacy module
This commit is contained in:
@@ -0,0 +1,71 @@
|
||||
import type { ObsidianLiveSyncSettings } from "@vrtmrz/livesync-commonlib/compat/common/types";
|
||||
import { fireAndForget } from "octagonal-wheels/promises";
|
||||
import { scheduleTask } from "octagonal-wheels/concurrency/task";
|
||||
import { EVENT_FILE_SAVED, EVENT_SETTING_SAVED, eventHub } from "@/common/events";
|
||||
|
||||
type ReflectionFilterSettings = Pick<
|
||||
ObsidianLiveSyncSettings,
|
||||
| "handleFilenameCaseSensitive"
|
||||
| "ignoreFiles"
|
||||
| "maxMTimeForReflectEvents"
|
||||
| "syncIgnoreRegEx"
|
||||
| "syncInternalFiles"
|
||||
| "syncMaxSizeInMB"
|
||||
| "syncOnlyRegEx"
|
||||
| "useIgnoreFiles"
|
||||
>;
|
||||
|
||||
interface AutomaticReplicationTriggerContext {
|
||||
readonly currentSettings: () => ObsidianLiveSyncSettings;
|
||||
readonly isSuspended: () => boolean;
|
||||
readonly replicateDatabaseEvent: () => Promise<unknown>;
|
||||
readonly reprocessStoredDocuments: () => Promise<number>;
|
||||
readonly resumeResultApplication: () => void;
|
||||
readonly suspendResultApplication: () => void;
|
||||
}
|
||||
|
||||
function normalFileReflectionFilterSignature(settings: ReflectionFilterSettings): string {
|
||||
return JSON.stringify({
|
||||
handleFilenameCaseSensitive: settings.handleFilenameCaseSensitive ?? false,
|
||||
ignoreFiles: settings.ignoreFiles ?? "",
|
||||
maxMTimeForReflectEvents: settings.maxMTimeForReflectEvents ?? 0,
|
||||
syncIgnoreRegEx: settings.syncIgnoreRegEx ?? "",
|
||||
syncInternalFiles: settings.syncInternalFiles ?? false,
|
||||
syncMaxSizeInMB: settings.syncMaxSizeInMB ?? 0,
|
||||
syncOnlyRegEx: settings.syncOnlyRegEx ?? "",
|
||||
useIgnoreFiles: settings.useIgnoreFiles ?? false,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the settings-loaded handler which installs automatic replication and
|
||||
* result-application reactions. The returned closure owns the previous filter
|
||||
* signature; it is private composition state rather than a shared service.
|
||||
*/
|
||||
export function createAutomaticReplicationTriggers(context: AutomaticReplicationTriggerContext) {
|
||||
let reflectionFilterSignature: string | undefined;
|
||||
|
||||
return function initialiseAutomaticReplicationTriggers(): Promise<boolean> {
|
||||
reflectionFilterSignature = normalFileReflectionFilterSignature(context.currentSettings());
|
||||
eventHub.onEvent(EVENT_FILE_SAVED, () => {
|
||||
if (context.currentSettings().syncOnSave && !context.isSuspended()) {
|
||||
scheduleTask("perform-replicate-after-save", 250, () => context.replicateDatabaseEvent());
|
||||
}
|
||||
});
|
||||
eventHub.onEvent(EVENT_SETTING_SAVED, (settings) => {
|
||||
const previousReflectionFilter = reflectionFilterSignature;
|
||||
const nextReflectionFilter = normalFileReflectionFilterSignature(settings);
|
||||
reflectionFilterSignature = nextReflectionFilter;
|
||||
if (settings.suspendParseReplicationResult) {
|
||||
context.suspendResultApplication();
|
||||
} else {
|
||||
context.resumeResultApplication();
|
||||
}
|
||||
if (previousReflectionFilter !== undefined && previousReflectionFilter !== nextReflectionFilter) {
|
||||
fireAndForget(() => context.reprocessStoredDocuments());
|
||||
}
|
||||
});
|
||||
|
||||
return Promise.resolve(true);
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user