11import { toast } from 'react-toastify' ;
22
3+ const encodeBase64 = ( value ) => {
4+ const bytes = new TextEncoder ( ) . encode ( value ) ;
5+ let binary = '' ;
6+ bytes . forEach ( ( byte ) => {
7+ binary += String . fromCharCode ( byte ) ;
8+ } ) ;
9+ return window . btoa ( binary ) ;
10+ } ;
11+
12+ const decodeBase64 = ( value ) => {
13+ const binary = window . atob ( value ) ;
14+ const bytes = Uint8Array . from ( binary , ( char ) => char . charCodeAt ( 0 ) ) ;
15+ return new TextDecoder ( ) . decode ( bytes ) ;
16+ } ;
17+
18+ const parseStoredJson = ( raw ) => {
19+ try {
20+ return JSON . parse ( decodeBase64 ( raw ) ) ;
21+ } catch ( e ) {
22+ return null ;
23+ }
24+ } ;
25+
326const localStorageGet = ( key ) => {
427 try {
528 return window . localStorage . getItem ( key ) ;
@@ -27,11 +50,16 @@ const localStorageRemove = (key) => {
2750
2851const getSet = ( ALL_GRAPHS ) => {
2952 if ( ! localStorageGet ( ALL_GRAPHS ) ) {
30- localStorageSet ( ALL_GRAPHS , window . btoa ( JSON . stringify ( [ ] ) ) ) ;
53+ localStorageSet ( ALL_GRAPHS , encodeBase64 ( JSON . stringify ( [ ] ) ) ) ;
3154 }
3255 const raw = localStorageGet ( ALL_GRAPHS ) ;
3356 if ( ! raw ) return new Set ( ) ;
34- return new Set ( JSON . parse ( window . atob ( raw ) ) ) ;
57+ const parsed = parseStoredJson ( raw ) ;
58+ if ( ! Array . isArray ( parsed ) ) {
59+ localStorageSet ( ALL_GRAPHS , encodeBase64 ( JSON . stringify ( [ ] ) ) ) ;
60+ return new Set ( ) ;
61+ }
62+ return new Set ( parsed ) ;
3563} ;
3664
3765const localStorageManager = {
@@ -41,24 +69,29 @@ const localStorageManager = {
4169 allgs : getSet ( window . btoa ( 'ALL_GRAPHS' ) ) ,
4270
4371 saveAllgs ( ) {
44- localStorageSet ( this . ALL_GRAPHS , window . btoa ( JSON . stringify ( Array . from ( this . allgs ) ) ) ) ;
72+ localStorageSet ( this . ALL_GRAPHS , encodeBase64 ( JSON . stringify ( Array . from ( this . allgs ) ) ) ) ;
4573 } ,
4674
4775 addEmptyIfNot ( ) {
4876 if ( ! localStorageGet ( this . ALL_GRAPHS ) ) {
49- localStorageSet ( this . ALL_GRAPHS , window . btoa ( JSON . stringify ( [ ] ) ) ) ;
77+ localStorageSet ( this . ALL_GRAPHS , encodeBase64 ( JSON . stringify ( [ ] ) ) ) ;
5078 }
5179 } ,
5280
5381 get ( id ) {
5482 const raw = localStorageGet ( id ) ;
5583 if ( raw === null ) return null ;
56- return JSON . parse ( window . atob ( raw ) ) ;
84+ const parsed = parseStoredJson ( raw ) ;
85+ if ( parsed === null ) {
86+ localStorageRemove ( id ) ;
87+ return null ;
88+ }
89+ return parsed ;
5790 } ,
5891 save ( id , graphContent ) {
5992 this . addGraph ( id ) ;
6093 const serializedJson = JSON . stringify ( graphContent ) ;
61- localStorageSet ( id , window . btoa ( serializedJson ) ) ;
94+ localStorageSet ( id , encodeBase64 ( serializedJson ) ) ;
6295 } ,
6396 remove ( id ) {
6497 if ( this . allgs . delete ( id ) ) this . saveAllgs ( ) ;
@@ -72,16 +105,25 @@ const localStorageManager = {
72105 getAllGraphs ( ) {
73106 const raw = localStorageGet ( this . ALL_GRAPHS ) ;
74107 if ( ! raw ) return [ ] ;
75- return JSON . parse ( window . atob ( raw ) ) ;
108+ const parsed = parseStoredJson ( raw ) ;
109+ if ( ! Array . isArray ( parsed ) ) {
110+ localStorageSet ( this . ALL_GRAPHS , encodeBase64 ( JSON . stringify ( [ ] ) ) ) ;
111+ return [ ] ;
112+ }
113+ return parsed ;
76114 } ,
77115 addToFront ( id ) {
78116 if ( this . allgs . has ( id ) ) return ;
79117 this . allgs . add ( id ) ;
80118 const raw = localStorageGet ( this . ALL_GRAPHS ) ;
81119 if ( ! raw ) return ;
82- const Garr = JSON . parse ( window . atob ( raw ) ) ;
120+ const Garr = parseStoredJson ( raw ) ;
121+ if ( ! Array . isArray ( Garr ) ) {
122+ this . saveAllgs ( ) ;
123+ return ;
124+ }
83125 Garr . unshift ( id ) ;
84- localStorageSet ( this . ALL_GRAPHS , window . btoa ( JSON . stringify ( Garr ) ) ) ;
126+ localStorageSet ( this . ALL_GRAPHS , encodeBase64 ( JSON . stringify ( Garr ) ) ) ;
85127 } ,
86128 getAuthorName ( ) {
87129 return localStorageGet ( this . AUTHOR_NAME ) || '' ;
0 commit comments