summaryrefslogtreecommitdiff
path: root/apps/web/src/core/managers/save-manager.ts
diff options
context:
space:
mode:
authorMaze Winther <mazewinther@gmail.com>2026-03-27 00:55:15 +0100
committerMaze Winther <mazewinther@gmail.com>2026-03-29 15:56:48 +0200
commit4d127a038bf768eded68aae3cfa5c1b12241bdac (patch)
tree16bbb801caf6770546cff4fdb37b6408ec9ead98 /apps/web/src/core/managers/save-manager.ts
parent82817cb50cb0487350573d6129130aec705f924b (diff)
downloadopencut-4d127a038bf768eded68aae3cfa5c1b12241bdac.tar.gz
chore: normalize line endings
Diffstat (limited to 'apps/web/src/core/managers/save-manager.ts')
-rw-r--r--apps/web/src/core/managers/save-manager.ts214
1 files changed, 107 insertions, 107 deletions
diff --git a/apps/web/src/core/managers/save-manager.ts b/apps/web/src/core/managers/save-manager.ts
index d5881b6b..b3c894d4 100644
--- a/apps/web/src/core/managers/save-manager.ts
+++ b/apps/web/src/core/managers/save-manager.ts
@@ -1,107 +1,107 @@
-import type { EditorCore } from "@/core";
-
-type SaveManagerOptions = {
- debounceMs?: number;
-};
-
-export class SaveManager {
- private debounceMs: number;
- private isPaused = false;
- private isSaving = false;
- private hasPendingSave = false;
- private saveTimer: ReturnType<typeof setTimeout> | null = null;
- private unsubscribeHandlers: Array<() => void> = [];
-
- constructor(
- private editor: EditorCore,
- { debounceMs = 800 }: SaveManagerOptions = {},
- ) {
- this.debounceMs = debounceMs;
- }
-
- start(): void {
- if (this.unsubscribeHandlers.length > 0) return;
-
- this.unsubscribeHandlers = [
- this.editor.scenes.subscribe(() => {
- this.markDirty();
- }),
- this.editor.timeline.subscribe(() => {
- this.markDirty();
- }),
- ];
- }
-
- stop(): void {
- for (const unsubscribe of this.unsubscribeHandlers) {
- unsubscribe();
- }
- this.unsubscribeHandlers = [];
- this.clearTimer();
- }
-
- pause(): void {
- this.isPaused = true;
- }
-
- resume(): void {
- this.isPaused = false;
- if (this.hasPendingSave) {
- this.queueSave();
- }
- }
-
- markDirty({ force = false }: { force?: boolean } = {}): void {
- if (this.isPaused && !force) return;
- this.hasPendingSave = true;
- this.queueSave();
- }
-
- async flush(): Promise<void> {
- this.hasPendingSave = true;
- await this.saveNow();
- }
-
- getIsDirty(): boolean {
- return this.hasPendingSave || this.isSaving;
- }
-
- private queueSave(): void {
- if (this.isSaving) return;
- if (this.saveTimer) {
- clearTimeout(this.saveTimer);
- }
- this.saveTimer = setTimeout(() => {
- void this.saveNow();
- }, this.debounceMs);
- }
-
- private async saveNow(): Promise<void> {
- if (this.isSaving) return;
- if (!this.hasPendingSave) return;
-
- const activeProject = this.editor.project.getActive();
- if (!activeProject) return;
- if (this.editor.project.getIsLoading()) return;
- if (this.editor.project.getMigrationState().isMigrating) return;
-
- this.isSaving = true;
- this.hasPendingSave = false;
- this.clearTimer();
-
- try {
- await this.editor.project.saveCurrentProject();
- } finally {
- this.isSaving = false;
- if (this.hasPendingSave) {
- this.queueSave();
- }
- }
- }
-
- private clearTimer(): void {
- if (!this.saveTimer) return;
- clearTimeout(this.saveTimer);
- this.saveTimer = null;
- }
-}
+import type { EditorCore } from "@/core";
+
+type SaveManagerOptions = {
+ debounceMs?: number;
+};
+
+export class SaveManager {
+ private debounceMs: number;
+ private isPaused = false;
+ private isSaving = false;
+ private hasPendingSave = false;
+ private saveTimer: ReturnType<typeof setTimeout> | null = null;
+ private unsubscribeHandlers: Array<() => void> = [];
+
+ constructor(
+ private editor: EditorCore,
+ { debounceMs = 800 }: SaveManagerOptions = {},
+ ) {
+ this.debounceMs = debounceMs;
+ }
+
+ start(): void {
+ if (this.unsubscribeHandlers.length > 0) return;
+
+ this.unsubscribeHandlers = [
+ this.editor.scenes.subscribe(() => {
+ this.markDirty();
+ }),
+ this.editor.timeline.subscribe(() => {
+ this.markDirty();
+ }),
+ ];
+ }
+
+ stop(): void {
+ for (const unsubscribe of this.unsubscribeHandlers) {
+ unsubscribe();
+ }
+ this.unsubscribeHandlers = [];
+ this.clearTimer();
+ }
+
+ pause(): void {
+ this.isPaused = true;
+ }
+
+ resume(): void {
+ this.isPaused = false;
+ if (this.hasPendingSave) {
+ this.queueSave();
+ }
+ }
+
+ markDirty({ force = false }: { force?: boolean } = {}): void {
+ if (this.isPaused && !force) return;
+ this.hasPendingSave = true;
+ this.queueSave();
+ }
+
+ async flush(): Promise<void> {
+ this.hasPendingSave = true;
+ await this.saveNow();
+ }
+
+ getIsDirty(): boolean {
+ return this.hasPendingSave || this.isSaving;
+ }
+
+ private queueSave(): void {
+ if (this.isSaving) return;
+ if (this.saveTimer) {
+ clearTimeout(this.saveTimer);
+ }
+ this.saveTimer = setTimeout(() => {
+ void this.saveNow();
+ }, this.debounceMs);
+ }
+
+ private async saveNow(): Promise<void> {
+ if (this.isSaving) return;
+ if (!this.hasPendingSave) return;
+
+ const activeProject = this.editor.project.getActive();
+ if (!activeProject) return;
+ if (this.editor.project.getIsLoading()) return;
+ if (this.editor.project.getMigrationState().isMigrating) return;
+
+ this.isSaving = true;
+ this.hasPendingSave = false;
+ this.clearTimer();
+
+ try {
+ await this.editor.project.saveCurrentProject();
+ } finally {
+ this.isSaving = false;
+ if (this.hasPendingSave) {
+ this.queueSave();
+ }
+ }
+ }
+
+ private clearTimer(): void {
+ if (!this.saveTimer) return;
+ clearTimeout(this.saveTimer);
+ this.saveTimer = null;
+ }
+}