33class PassedState {
44
55 _key = 'passedState' ;
6- state = null ;
6+ _state = null ;
77
88 constructor ( initialState = { } ) {
99 const currentState = localStorage . getItem ( this . _key ) ;
@@ -16,9 +16,9 @@ class PassedState {
1616 const rawState = this . _prepareState ( initialState ) ;
1717
1818 // check new state and old state whether is undefined or not. and merge the new state to the old state.
19- const state = this . _checkAndMerge ( rawState , currentState ) ;
19+ const state = this . _checkAndMerge ( currentState , rawState ) ;
2020 this . _save ( state ) ;
21- this . state = state ;
21+ this . _state = state ;
2222 return
2323 }
2424
@@ -48,7 +48,7 @@ class PassedState {
4848 }
4949
5050 get ( ) {
51- return this . state ;
51+ return this . _state ;
5252 }
5353
5454 _save ( state ) {
@@ -62,15 +62,15 @@ class PassedState {
6262 * @returns void
6363 */
6464 setPassed ( level , challengeName ) {
65- const challenges = this . state [ level ] ;
65+ const challenges = this . _state [ level ] ;
6666 for ( const challenge of challenges ) {
6767 if ( challenge . name === challengeName ) {
6868 challenge . passed = true ;
6969 break ;
7070 }
7171 }
7272
73- this . _save ( this . state ) ;
73+ this . _save ( this . _state ) ;
7474 }
7575
7676 /**
@@ -79,14 +79,41 @@ class PassedState {
7979 * - If the new key in the new state is not in the current state, the new key will be added to the current state.
8080 * @param {object } newState
8181 */
82- _checkAndMerge ( newState , oldState ) {
82+ _checkAndMerge ( oldState , newState ) {
8383 if ( ! newState && ! oldState ) {
8484 throw new Error ( 'one of the new state and the old state is required.' ) ;
8585 }
8686
8787 if ( ! newState ) {
8888 return oldState ;
8989 }
90- // TODO: compare the new state with the old state and merge the new state to the old state.
90+
91+ let mergedState = { } ;
92+ const levels = [ 'basic' , 'intermediate' , 'advanced' , 'expert' ] ;
93+
94+ for ( const level of levels ) {
95+ // Initialize an empty array for merged challenges
96+ let mergedChallenges = [ ] ;
97+
98+ // Create a map for quick lookup of challenges by name
99+ const oldChallengesMap = new Map ( oldState [ level ] . map ( challenge => [ challenge . name , challenge ] ) ) ;
100+ const newChallengesMap = new Map ( newState [ level ] . map ( challenge => [ challenge . name , challenge ] ) ) ;
101+
102+ // Add or update challenges from the newState
103+ for ( const [ name , newChallenge ] of newChallengesMap . entries ( ) ) {
104+ mergedChallenges . push ( { ...newChallenge , passed : oldChallengesMap . get ( name ) ?. passed } ) ;
105+ oldChallengesMap . delete ( name ) ; // Remove the challenge from oldChallengesMap since it's updated
106+ }
107+
108+ // Add remaining challenges from the oldState that are not updated (not present in newState)
109+ for ( const oldChallenge of oldChallengesMap . values ( ) ) {
110+ mergedChallenges . push ( oldChallenge ) ;
111+ }
112+
113+ // Set the merged challenges for the current level in the mergedState
114+ mergedState [ level ] = mergedChallenges ;
115+ }
116+
117+ return mergedState ;
91118 }
92119}
0 commit comments