diff --git a/packages/engine/src/alwatr-store.ts b/packages/engine/src/alwatr-store.ts index c5c13df6..dea58a90 100644 --- a/packages/engine/src/alwatr-store.ts +++ b/packages/engine/src/alwatr-store.ts @@ -11,6 +11,7 @@ import { } from '@alwatr/store-types'; import {Dictionary} from '@alwatr/type-helper'; import {waitForTimeout} from '@alwatr/wait'; +import exitHook from 'exit-hook' import {WriteFileMode, existsSync, readJsonFile, resolve, unlink, writeJsonFile} from './lib/node-fs.js'; import {logger} from './logger.js'; @@ -89,6 +90,7 @@ export class AlwatrStore { logger.logMethodArgs?.('new', config__); this.config__.defaultChangeDebounce ??= 40; this.rootDb__ = this.loadRootDb__(); + exitHook(this.exitHook__.bind(this)); } /** @@ -357,4 +359,18 @@ export class AlwatrStore { const context = readJsonFile(fullPath, true) as CollectionContext; return CollectionReference.newRefFromContext(context, this.storeChanged__.bind(this), 'root-db'); } + + /** + * Save all store files. + */ + private exitHook__(): void { + logger.logMethod?.('exitHook__'); + for (const ref of Object.values(this.cacheReferences__)) { + if (ref.hasUnprocessedChanges_ === true) { + ref.hasUnprocessedChanges_ = false; + logger.incident?.('exitHook__', 'rescue_unsaved_context', {id: ref.id}); + writeJsonFile(resolve(this.config__.rootPath, ref.path), ref.getFullContext_(), WriteFileMode.Rename, true); + } + } + } } diff --git a/packages/reference/src/collection-reference.ts b/packages/reference/src/collection-reference.ts index 2b8b94c7..137fa100 100644 --- a/packages/reference/src/collection-reference.ts +++ b/packages/reference/src/collection-reference.ts @@ -154,6 +154,11 @@ export class CollectionReference { */ readonly path: string; + /** + * Indicates whether the collection has unsaved changes. + */ + hasUnprocessedChanges_ = false; + /** * Logger instance for this collection. */ @@ -483,6 +488,7 @@ export class CollectionReference { */ private async updated__(id?: string | number): Promise { this.logger__.logMethodArgs?.('updated__', {delayed: this.updateDelayed__}); + this.hasUnprocessedChanges_ = true; this.updateMeta__(id); if (this.updateDelayed__ === true) return; @@ -494,7 +500,10 @@ export class CollectionReference { this.updateDelayed__ = false; } - this.updatedCallback__.call(null, this); + if (this.hasUnprocessedChanges_ === true) { + this.hasUnprocessedChanges_ = false; + this.updatedCallback__.call(null, this); + } } /**