@@ -1057,6 +1057,162 @@ describe('Complex data structures and memoization', () => {
10571057 } ) ;
10581058 } ) ;
10591059
1060+ describe ( 'Map and Set support with enableMapSet' , ( ) => {
1061+ it ( 'should work correctly with Map objects after enableMapSet is called' , async ( ) => {
1062+ const { enableMapSet } = await import ( '../../src/immer-utils' ) ;
1063+ const { setGlobalEqualityCheck } = await import ( '../../src/settings' ) ;
1064+ const isEqual = ( await import ( 'fast-deep-equal' ) ) . default ;
1065+
1066+ let mapValue = new Map ( [ [ 'key1' , 'value1' ] , [ 'key2' , 'value2' ] ] ) ;
1067+ const root = Reaction . create ( ( ) => mapValue ) ;
1068+ const computed = Reaction . create ( ( map ) => ( {
1069+ size : map . size ,
1070+ keys : Array . from ( map . keys ( ) ) . sort ( ) ,
1071+ values : Array . from ( map . values ( ) ) . sort ( )
1072+ } ) , [ root ] ) ;
1073+
1074+ const callback = jest . fn ( ) ;
1075+ computed . watch ( callback ) ;
1076+
1077+ // Initial computation
1078+ const result1 = computed . computeValue ( ) ;
1079+ expect ( result1 . size ) . toBe ( 2 ) ;
1080+ expect ( result1 . keys ) . toEqual ( [ 'key1' , 'key2' ] ) ;
1081+ expect ( result1 . values ) . toEqual ( [ 'value1' , 'value2' ] ) ;
1082+ callback . mockClear ( ) ;
1083+
1084+ // Enable MapSet support
1085+ enableMapSet ( ) ;
1086+
1087+ // Update map with same content - should not trigger change due to equality
1088+ mapValue = new Map ( [ [ 'key1' , 'value1' ] , [ 'key2' , 'value2' ] ] ) ;
1089+ root . markDirty ( ) ;
1090+
1091+ await waitForMicrotasks ( ) ;
1092+ expect ( callback ) . not . toHaveBeenCalled ( ) ; // Should not trigger due to deep equality
1093+
1094+ // Update map with different content - should trigger change
1095+ mapValue = new Map ( [ [ 'key1' , 'value1' ] , [ 'key2' , 'updated' ] ] ) ;
1096+ root . markDirty ( ) ;
1097+
1098+ await waitForMicrotasks ( ) ;
1099+ expect ( callback ) . toHaveBeenCalledWith ( {
1100+ size : 2 ,
1101+ keys : [ 'key1' , 'key2' ] ,
1102+ values : [ 'updated' , 'value1' ]
1103+ } ) ;
1104+
1105+ computed . unwatch ( callback ) ;
1106+
1107+ // Reset to default equality check
1108+ setGlobalEqualityCheck ( isEqual ) ;
1109+ } ) ;
1110+
1111+ it ( 'should work correctly with Set objects after enableMapSet is called' , async ( ) => {
1112+ const { enableMapSet } = await import ( '../../src/immer-utils' ) ;
1113+ const { setGlobalEqualityCheck, getGlobalEqualityCheck } = await import ( '../../src/settings' ) ;
1114+ const isEqual = ( await import ( 'fast-deep-equal' ) ) . default ;
1115+
1116+ let setValue = new Set ( [ 'a' , 'b' , 'c' ] ) ;
1117+ const root = Reaction . create ( ( ) => setValue ) ;
1118+ const computed = Reaction . create ( ( set ) => ( {
1119+ size : set . size ,
1120+ values : Array . from ( set ) . sort ( )
1121+ } ) , [ root ] ) ;
1122+
1123+ const callback = jest . fn ( ) ;
1124+ computed . watch ( callback ) ;
1125+
1126+ // Initial computation
1127+ const result1 = computed . computeValue ( ) ;
1128+ expect ( result1 . size ) . toBe ( 3 ) ;
1129+ expect ( result1 . values ) . toEqual ( [ 'a' , 'b' , 'c' ] ) ;
1130+ callback . mockClear ( ) ;
1131+
1132+ // Enable MapSet support
1133+ enableMapSet ( ) ;
1134+
1135+ // Update set with same content - should not trigger change
1136+ setValue = new Set ( [ 'a' , 'b' , 'c' ] ) ;
1137+ root . markDirty ( ) ;
1138+
1139+ await waitForMicrotasks ( ) ;
1140+ expect ( callback ) . not . toHaveBeenCalled ( ) ; // Should not trigger due to deep equality
1141+
1142+ // Update set with different content - should trigger change
1143+ setValue = new Set ( [ 'a' , 'b' , 'd' ] ) ;
1144+ root . markDirty ( ) ;
1145+
1146+ await waitForMicrotasks ( ) ;
1147+ expect ( callback ) . toHaveBeenCalledWith ( {
1148+ size : 3 ,
1149+ values : [ 'a' , 'b' , 'd' ]
1150+ } ) ;
1151+
1152+ computed . unwatch ( callback ) ;
1153+
1154+ // Reset to default equality check
1155+ setGlobalEqualityCheck ( isEqual ) ;
1156+ } ) ;
1157+
1158+ it ( 'should handle complex nested structures with Maps and Sets' , async ( ) => {
1159+ const { enableMapSet } = await import ( '../../src/immer-utils' ) ;
1160+ const { setGlobalEqualityCheck, getGlobalEqualityCheck } = await import ( '../../src/settings' ) ;
1161+ const isEqual = ( await import ( 'fast-deep-equal' ) ) . default ;
1162+
1163+ let complexValue = {
1164+ map : new Map ( [ [ 'users' , new Set ( [ 'alice' , 'bob' ] ) ] ] ) ,
1165+ config : { enabled : true }
1166+ } ;
1167+
1168+ const root = Reaction . create ( ( ) => complexValue ) ;
1169+ const computed = Reaction . create ( ( obj ) => ( {
1170+ userCount : obj . map . get ( 'users' ) ?. size || 0 ,
1171+ enabled : obj . config . enabled
1172+ } ) , [ root ] ) ;
1173+
1174+ const callback = jest . fn ( ) ;
1175+ computed . watch ( callback ) ;
1176+
1177+ // Initial computation
1178+ const result1 = computed . computeValue ( ) ;
1179+ expect ( result1 . userCount ) . toBe ( 2 ) ;
1180+ expect ( result1 . enabled ) . toBe ( true ) ;
1181+ callback . mockClear ( ) ;
1182+
1183+ // Enable MapSet support
1184+ enableMapSet ( ) ;
1185+
1186+ // Update with structurally identical object - should not trigger change
1187+ complexValue = {
1188+ map : new Map ( [ [ 'users' , new Set ( [ 'alice' , 'bob' ] ) ] ] ) ,
1189+ config : { enabled : true }
1190+ } ;
1191+ root . markDirty ( ) ;
1192+
1193+ await waitForMicrotasks ( ) ;
1194+ expect ( callback ) . not . toHaveBeenCalled ( ) ;
1195+
1196+ // Update with different Map content - should trigger change
1197+ complexValue = {
1198+ map : new Map ( [ [ 'users' , new Set ( [ 'alice' , 'bob' , 'charlie' ] ) ] ] ) ,
1199+ config : { enabled : true }
1200+ } ;
1201+ root . markDirty ( ) ;
1202+
1203+ await waitForMicrotasks ( ) ;
1204+ expect ( callback ) . toHaveBeenCalledWith ( {
1205+ userCount : 3 ,
1206+ enabled : true
1207+ } ) ;
1208+
1209+ computed . unwatch ( callback ) ;
1210+
1211+ // Reset to default equality check
1212+ setGlobalEqualityCheck ( isEqual ) ;
1213+ } ) ;
1214+ } ) ;
1215+
10601216 describe ( 'Custom equality check configuration' , ( ) => {
10611217 // Note: Equality checks are only used for COMPUTED reactions (those with dependencies).
10621218 // Root reactions always mark changed=true and don't use equality checks.
0 commit comments