import { EventEmitter } from "@mtgoo/ctool" ; import "reflect-metadata" ; import { IStoreOption } from "./iapp" ; interface IPrivateEvents { attChange : { att : string ; newValue : any ; oldValue : any ; } ; } type IAttEvents < T extends object > = { [ key in keyof T ] : { newValue : any ; oldValue : any ; } ; } ; export type IStoreEvents < T extends object = { } > = IPrivateEvents & IAttEvents < T > & IDataEvents ; description export class AppStore < T = IStoreEvents < any > > extends EventEmitter < T > { private _target : any ; private constructor ( data , opt ) { super ( ) ; this . _target = data ; let { saveItemToStorage = "none" } = opt || { } ; if ( saveItemToStorage != "none" ) { let storage = opt . saveItemToStorage == "localStorage" ? localStorage : sessionStorage ; this . _clearStore = ( ) => storage . clear ( ) ; this . on ( "attChange" as any , ( ev ) => { let { att , newValue } = ev ; storage . setItem ( att , JSON . stringify ( newValue ) ) ; } ) ; } window . addEventListener ( 'beforeunload' , ( ) => { this . saveDataToLocalStorage ( ) ; } , false ) ; if ( opt ?. loadDataOnOpen != false ) { this . loadDataFromLocalStorage ( ) ; } localStorage . removeItem ( storeKey ) ; } static create < P extends object = { } > ( data , opt ? ) { let store = new AppStore < IStoreEvents < P > > ( data , opt ) ; Object . keys ( data ) . forEach ( item => { if ( data [ item ] != null ) { store [ item ] = data [ item ] ; } } ) ; let storedData = new Proxy ( store , { set : function ( obj , prop , value ) { obj [ prop ] = value ; store . emit ( "attChange" , { att : prop . toString ( ) , newValue : value , oldValue : this [ prop ] } ) ; store . emit ( prop . toString ( ) , { newValue : value , oldValue : this [ prop ] } ) ; return true ; } } ) ; return storedData as any ; } /**
     * 将需要持久化的数据存储到LocalStorage中
     */ private saveDataToLocalStorage ( ) { let store = Reflect . getMetadata ( storeKey , this . _target ) ; let needStoreData = { } ; store ?. forEach ( key => { let value = Reflect . get ( this , key ) ; needStoreData [ key ] = value ; } ) ; localStorage . setItem ( storeKey , JSON . stringify ( needStoreData ) ) ; } /**
     * 从localStorage加载被持久化的数据
     */ private loadDataFromLocalStorage ( ) { let store = Reflect . getMetadata ( storeKey , this . _target ) ; let storedInfo = JSON . parse ( localStorage . getItem ( storeKey ) ) ; if ( storedInfo ) { store ?. forEach ( key => { Reflect . set ( this , key , storedInfo [ key ] ) ; } ) ; } } private _clearStore = ( ) => { } ; /**
     * 清空store的数据
     */ clear ( clearStorage = true ) { let store = Reflect . getMetadata ( storeKey , this . _target ) ; store ?. forEach ( key => { Reflect . set ( this , key , null ) ; } ) ; if ( clearStorage ) this . _clearStore ( ) ; } } /**
 * 标记需要持久化的数据
 */ export function Att < K > ( target , name ) { let store = Reflect . getMetadata ( storeKey , target ) ; if ( store == null ) { Reflect . defineMetadata ( storeKey , [ name ] , target ) ; } else { store . push ( name ) ; } } const storeKey = "__private__store" ;