@@ -5,6 +5,7 @@ import { describe, expect, test } from "vitest";
55import { computed , AutoStore , configurable , ValidateError } from "../../../core/src" ;
66import ".." ;
77import { isFunction } from "../../../core/src/utils/isFunction" ;
8+ import { AutoStoreSyncer } from ".." ;
89
910describe ( "本地Store同步" , ( ) => {
1011 test ( "一对一全同步" , async ( ) => {
@@ -1046,4 +1047,109 @@ describe("本地Store同步", () => {
10461047 } ) ;
10471048 } ) ;
10481049 } ) ;
1050+ test ( "模块配置同步模拟测试" , async ( ) => {
1051+ class SettingManager {
1052+ _dirtyValues : Record < string , any > = { } ;
1053+ store = new AutoStore (
1054+ { } ,
1055+ {
1056+ id : "settings" ,
1057+ resetable : true ,
1058+ } ,
1059+ ) ;
1060+
1061+ constructor ( values : Record < string , any > ) {
1062+ this . load ( values ) ;
1063+ // 侦听配置变化,并且在变化时进行保存
1064+ this . store . watch ( ( { path, value, flags } ) => {
1065+ // 当从模块第一次同步更新到store时,flags<0
1066+ if ( flags && flags < 0 ) return ;
1067+ // 为什么是2? 因为path[0]是模块id,path[1]是配置项路径
1068+ if ( path . length === 2 ) {
1069+ if ( ! this . _dirtyValues [ path [ 0 ] ] ) this . _dirtyValues [ path [ 0 ] ] = { } ;
1070+ this . _dirtyValues [ path [ 0 ] ] [ path [ 1 ] ] = value ;
1071+
1072+ this . save ( ) ;
1073+ }
1074+ } ) ;
1075+ }
1076+ load ( values : Record < string , any > = { } ) {
1077+ this . store = new AutoStore ( values , {
1078+ id : "settings" ,
1079+ resetable : true ,
1080+ } ) ;
1081+ }
1082+ save ( ) { }
1083+ }
1084+ const settingManager = new SettingManager ( {
1085+ shop : {
1086+ "order.price" : 1000 ,
1087+ } ,
1088+ } ) ;
1089+ class ShopModule {
1090+ store = new AutoStore ( {
1091+ order : {
1092+ price : configurable ( 100 ) ,
1093+ } ,
1094+ } ) ;
1095+ syncer ?: AutoStoreSyncer ;
1096+ constructor ( ) {
1097+ this . loadSettings ( ) ;
1098+ this . sync ( ) ;
1099+ }
1100+ sync ( ) {
1101+ // 如果模块不是observable的,则不需要进行同步,同步是基于AutoStore的sync功能的
1102+ if ( this . store . schemas . size === 0 ) {
1103+ return ;
1104+ }
1105+
1106+ // 只有使用schema或configurable声明的配置项才会进行同步
1107+ const filter = ( path : string [ ] ) => {
1108+ return this . store . schemas . has ( path . join ( "." ) as any ) ;
1109+ } ;
1110+ const moduleStore = this . store ;
1111+ const syncSettings = {
1112+ filter,
1113+ remote : "shop" ,
1114+ immediate : true ,
1115+ pathMap : {
1116+ toLocal : ( path : any [ ] , value : any ) => {
1117+ if ( typeof value !== "object" ) {
1118+ return path . reduce < string [ ] > ( ( result : any [ ] , cur : string ) => {
1119+ result . push ( ...cur . split ( "." ) ) ;
1120+ return result ;
1121+ } , [ ] ) ;
1122+ }
1123+ } ,
1124+ toRemote ( path : any [ ] , value : any ) {
1125+ // this.store.schemas.has(path)的作用
1126+ // 当同步configurable时,如果是数组或对象,也需要同步
1127+ if ( typeof value !== "object" || moduleStore . schemas . has ( path ) ) {
1128+ return [ path . join ( "." ) ] ;
1129+ }
1130+ } ,
1131+ } ,
1132+ } ;
1133+ // 将本模块的配置项同步到全局SettingManager中,这样在应用中就可以使用SettingManager管理应用的所有配置了
1134+ this . syncer = this . store . sync ( settingManager . store , syncSettings ) ;
1135+ }
1136+ loadSettings ( ) {
1137+ // @ts -expect-error
1138+ this . store . state . order . price = settingManager . store . state [ "shop" ] [ "order.price" ] ;
1139+ }
1140+ }
1141+
1142+ const order = new ShopModule ( ) ;
1143+ expect ( order . store . state . order . price ) . toBe ( 1000 ) ;
1144+ // @ts -expect-error
1145+ expect ( settingManager . store . state [ "shop" ] [ "order.price" ] ) . toBe ( 1000 ) ;
1146+ order . store . state . order . price = 2000 ;
1147+ expect ( order . store . state . order . price ) . toBe ( 2000 ) ;
1148+ // @ts -expect-error
1149+ expect ( settingManager . store . state [ "shop" ] [ "order.price" ] ) . toBe ( 2000 ) ;
1150+
1151+ // @ts -expect-error
1152+ settingManager . store . state [ "shop" ] [ "order.price" ] = 3000 ;
1153+ expect ( order . store . state . order . price ) . toBe ( 3000 ) ;
1154+ } ) ;
10491155} ) ;
0 commit comments