@@ -189,7 +189,7 @@ export class Loki extends LokiEventEmitter {
189
189
}
190
190
}
191
191
192
- this . autosaveDisable ( ) ;
192
+ this . _autosaveDisable ( ) ;
193
193
194
194
// if they want to load database on loki instantiation, now is a good time to load... after adapter set and before
195
195
// possible autosave initiation
@@ -202,7 +202,7 @@ export class Loki extends LokiEventEmitter {
202
202
203
203
return loaded . then ( ( ) => {
204
204
if ( this . _autosave ) {
205
- this . autosaveEnable ( ) ;
205
+ this . _autosaveEnable ( ) ;
206
206
}
207
207
} ) ;
208
208
}
@@ -734,13 +734,9 @@ export class Loki extends LokiEventEmitter {
734
734
// for autosave scenarios, we will let close perform final save (if dirty)
735
735
// For web use, you might call from window.onbeforeunload to shutdown database, saving pending changes
736
736
if ( this . _autosave ) {
737
- this . autosaveDisable ( ) ;
738
- // Check if collections are dirty.
739
- for ( let idx = 0 ; idx < this . _collections . length ; idx ++ ) {
740
- if ( this . _collections [ idx ] . dirty ) {
741
- saved = this . saveDatabase ( ) ;
742
- break ;
743
- }
737
+ this . _autosaveDisable ( ) ;
738
+ if ( this . _autosaveDirty ( ) ) {
739
+ saved = this . saveDatabase ( ) ;
744
740
}
745
741
}
746
742
@@ -929,25 +925,24 @@ export class Loki extends LokiEventEmitter {
929
925
return Promise . reject ( new Error ( "persistenceAdapter not configured" ) ) ;
930
926
}
931
927
932
- let saved ;
933
-
934
928
// check if the adapter is requesting (and supports) a 'reference' mode export
935
929
if ( this . _persistenceAdapter . mode === "reference" && typeof this . _persistenceAdapter . exportDatabase === "function" ) {
936
930
// filename may seem redundant but loadDatabase will need to expect this same filename
937
- saved = this . _persistenceAdapter . exportDatabase ( this . filename , this . copy ( { removeNonSerializable : true } ) ) ;
938
- }
939
- // otherwise just pass the serialized database to adapter
940
- else {
941
- saved = this . _persistenceAdapter . saveDatabase ( this . filename , this . serialize ( ) as string ) ;
931
+ return Promise . resolve ( this . _persistenceAdapter . exportDatabase ( this . filename , this . copy ( { removeNonSerializable : true } ) ) )
932
+ . then ( ( ) => {
933
+ this . _autosaveClearFlags ( ) ;
934
+ this . emit ( "save" ) ;
935
+ } ) ;
942
936
}
943
937
944
- return Promise . resolve ( saved ) . then ( ( ) => {
945
- // Set all collection not dirty.
946
- for ( let idx = 0 ; idx < this . _collections . length ; idx ++ ) {
947
- this . _collections [ idx ] . dirty = false ;
948
- }
949
- this . emit ( "save" ) ;
950
- } ) ;
938
+ // otherwise just pass the serialized database to adapter
939
+ // persistenceAdapter might be asynchronous, so we must clear `dirty` immediately
940
+ // or autosave won't work if an update occurs between here and the callback
941
+ this . _autosaveClearFlags ( ) ;
942
+ return Promise . resolve ( this . _persistenceAdapter . saveDatabase ( this . filename , this . serialize ( ) as string ) )
943
+ . then ( ( ) => {
944
+ this . emit ( "save" ) ;
945
+ } ) ;
951
946
}
952
947
953
948
/**
@@ -959,7 +954,7 @@ export class Loki extends LokiEventEmitter {
959
954
*
960
955
* @returns {Promise } a Promise that resolves after the database is persisted
961
956
*/
962
- saveDatabase ( ) {
957
+ public saveDatabase ( ) {
963
958
if ( ! this . _throttledSaves ) {
964
959
return this . _saveDatabase ( ) ;
965
960
}
@@ -989,7 +984,7 @@ export class Loki extends LokiEventEmitter {
989
984
*
990
985
* @returns {Promise } a Promise that resolves after the database is deleted
991
986
*/
992
- deleteDatabase ( ) {
987
+ public deleteDatabase ( ) {
993
988
// the persistenceAdapter should be present if all is ok, but check to be sure.
994
989
if ( this . _persistenceAdapter === null ) {
995
990
return Promise . reject ( new Error ( "persistenceAdapter not configured" ) ) ;
@@ -998,10 +993,32 @@ export class Loki extends LokiEventEmitter {
998
993
return Promise . resolve ( this . _persistenceAdapter . deleteDatabase ( this . filename ) ) ;
999
994
}
1000
995
996
+ /**
997
+ * Check whether any collections are "dirty" meaning we need to save the (entire) database
998
+ * @returns {boolean } - true if database has changed since last autosave, otherwise false
999
+ */
1000
+ private _autosaveDirty ( ) : boolean {
1001
+ for ( let idx = 0 ; idx < this . _collections . length ; idx ++ ) {
1002
+ if ( this . _collections [ idx ] . dirty ) {
1003
+ return true ;
1004
+ }
1005
+ }
1006
+ return false ;
1007
+ }
1008
+
1009
+ /**
1010
+ * Resets dirty flags on all collections.
1011
+ */
1012
+ private _autosaveClearFlags ( ) {
1013
+ for ( let idx = 0 ; idx < this . _collections . length ; idx ++ ) {
1014
+ this . _collections [ idx ] . dirty = false ;
1015
+ }
1016
+ }
1017
+
1001
1018
/**
1002
1019
* Starts periodically saves to the underlying storage adapter.
1003
1020
*/
1004
- autosaveEnable ( ) {
1021
+ private _autosaveEnable ( ) : void {
1005
1022
if ( this . _autosaveHandle ) {
1006
1023
return ;
1007
1024
}
@@ -1024,7 +1041,7 @@ export class Loki extends LokiEventEmitter {
1024
1041
/**
1025
1042
* Stops the autosave interval timer.
1026
1043
*/
1027
- autosaveDisable ( ) {
1044
+ private _autosaveDisable ( ) : void {
1028
1045
this . _autosave = false ;
1029
1046
1030
1047
if ( this . _autosaveHandle ) {
0 commit comments