11import fs from 'node:fs'
22import { createSharedState } from '@vitejs/devtools-kit/utils/shared-state'
33import { dirname } from 'pathe'
4+ import { debounce } from 'perfect-debounce'
45
56export interface CreateStorageOptions < T extends object > {
67 filepath : string
78 initialValue : T
9+ mergeInitialValue ?: false | ( ( initialValue : T , savedValue : T ) => T )
10+ debounce ?: number
811}
912
1013export function createStorage < T extends object > ( options : CreateStorageOptions < T > ) {
14+ const {
15+ mergeInitialValue = ( initialValue , savedValue ) => ( { ...initialValue , ...savedValue } ) ,
16+ debounce : debounceTime = 100 ,
17+ } = options
18+
1119 let initialValue : T
1220 if ( fs . existsSync ( options . filepath ) ) {
13- initialValue = JSON . parse ( fs . readFileSync ( options . filepath , 'utf-8' ) ) as T
21+ const savedValue = JSON . parse ( fs . readFileSync ( options . filepath , 'utf-8' ) ) as T
22+ initialValue = mergeInitialValue ? mergeInitialValue ( options . initialValue , savedValue ) : savedValue
1423 }
1524 else {
1625 initialValue = options . initialValue
@@ -21,10 +30,14 @@ export function createStorage<T extends object>(options: CreateStorageOptions<T>
2130 enablePatches : false ,
2231 } )
2332
24- state . on ( 'updated' , ( newState ) => {
25- fs . mkdirSync ( dirname ( options . filepath ) , { recursive : true } )
26- fs . writeFileSync ( options . filepath , `${ JSON . stringify ( newState , null , 2 ) } \n` )
27- } )
33+ // throttle the write to the file
34+ state . on (
35+ 'updated' ,
36+ debounce ( ( newState ) => {
37+ fs . mkdirSync ( dirname ( options . filepath ) , { recursive : true } )
38+ fs . writeFileSync ( options . filepath , `${ JSON . stringify ( newState , null , 2 ) } \n` )
39+ } , debounceTime ) ,
40+ )
2841
2942 return state
3043}
0 commit comments