11// 加载全局缓存
22
3- let loadCachePromise : Promise < any > | undefined = undefined ;
4- let cache : { [ key : string ] : any } | undefined = undefined ;
3+ let loadCachePromise : Promise < Partial < Record < string , any > > > | undefined = undefined ;
4+ let cache : Partial < Record < string , any > > | undefined = undefined ;
55
66// 加载数据到缓存
7- function loadCache ( ) : Promise < any > {
7+ function loadCache ( ) : Promise < Partial < Record < string , any > > > {
88 if ( cache ) {
99 return Promise . resolve ( cache ) ;
1010 }
11- if ( loadCachePromise ) {
12- return loadCachePromise ;
11+ if ( ! loadCachePromise ) {
12+ loadCachePromise = new Promise < Partial < Record < string , any > > > ( ( resolve ) => {
13+ chrome . storage . local . get ( ( result : Partial < Record < string , any > > | undefined ) => {
14+ const lastError = chrome . runtime . lastError ;
15+ if ( lastError ) {
16+ console . error ( "chrome.runtime.lastError in chrome.storage.local.get:" , lastError ) ;
17+ // 无视storage API错误,继续执行
18+ }
19+ cache = result || { } ;
20+ loadCachePromise = undefined ;
21+ resolve ( cache ) ;
22+ } ) ;
23+ } ) ;
1324 }
14- loadCachePromise = new Promise ( ( resolve ) => {
15- chrome . storage . local . get ( ( result : { [ key : string ] : any } | undefined ) => {
25+ return loadCachePromise ;
26+ }
27+
28+ function saveCacheAndStorage < T > ( key : string , value : T ) : Promise < T > {
29+ return Promise . all ( [
30+ loadCache ( ) . then ( ( cache ) => {
31+ cache [ key ] = value ;
32+ } ) ,
33+ new Promise < void > ( ( resolve ) => {
34+ chrome . storage . local . set ( { [ key ] : value } , ( ) => {
35+ const lastError = chrome . runtime . lastError ;
36+ if ( lastError ) {
37+ console . error ( "chrome.runtime.lastError in chrome.storage.local.set:" , lastError ) ;
38+ // 无视storage API错误,继续执行
39+ }
40+ resolve ( ) ;
41+ } ) ;
42+ } ) ,
43+ ] ) . then ( ( ) => value ) ;
44+ }
45+
46+ function saveStorage < T > ( key : string , value : T ) : Promise < T > {
47+ return new Promise ( ( resolve ) => {
48+ chrome . storage . local . set (
49+ {
50+ [ key ] : value ,
51+ } ,
52+ ( ) => {
53+ const lastError = chrome . runtime . lastError ;
54+ if ( lastError ) {
55+ console . error ( "chrome.runtime.lastError in chrome.storage.local.set:" , lastError ) ;
56+ // 无视storage API错误,继续执行
57+ }
58+ resolve ( value ) ;
59+ }
60+ ) ;
61+ } ) ;
62+ }
63+
64+ function saveStorageRecord ( record : Partial < Record < string , any > > ) : Promise < void > {
65+ return new Promise ( ( resolve ) => {
66+ chrome . storage . local . set ( record , ( ) => {
67+ const lastError = chrome . runtime . lastError ;
68+ if ( lastError ) {
69+ console . error ( "chrome.runtime.lastError in chrome.storage.local.set:" , lastError ) ;
70+ // 无视storage API错误,继续执行
71+ }
72+ resolve ( ) ;
73+ } ) ;
74+ } ) ;
75+ }
76+
77+ function getCache ( key : string ) : Promise < any > {
78+ return loadCache ( ) . then ( ( cache ) => {
79+ if ( cache [ key ] ) {
80+ return Object . assign ( { } , cache [ key ] ) ;
81+ }
82+ return cache [ key ] ;
83+ } ) ;
84+ }
85+
86+ function getStorage ( key : string ) : Promise < any > {
87+ return new Promise ( ( resolve ) => {
88+ chrome . storage . local . get ( key , ( result ) => {
1689 const lastError = chrome . runtime . lastError ;
1790 if ( lastError ) {
1891 console . error ( "chrome.runtime.lastError in chrome.storage.local.get:" , lastError ) ;
1992 // 无视storage API错误,继续执行
2093 }
21- cache = result ;
22- resolve ( cache ) ;
94+ resolve ( result [ key ] ) ;
2395 } ) ;
2496 } ) ;
25- return loadCachePromise ;
2697}
2798
28- function saveCache ( key : string , value : any ) {
29- loadCache ( ) . then ( ( ) => {
30- cache ! [ key ] = value ;
99+ function getStorageRecord ( keys : string [ ] ) : Promise < Partial < Record < string , any > > > {
100+ return new Promise ( ( resolve ) => {
101+ chrome . storage . local . get ( keys , ( result ) => {
102+ const lastError = chrome . runtime . lastError ;
103+ if ( lastError ) {
104+ console . error ( "chrome.runtime.lastError in chrome.storage.local.get:" , lastError ) ;
105+ // 无视storage API错误,继续执行
106+ }
107+ resolve ( result ) ;
108+ } ) ;
31109 } ) ;
32- return chrome . storage . local . set ( { [ key ] : value } ) ;
33110}
34111
35112function deleteCache ( key : string ) {
36- loadCache ( ) . then ( ( ) => {
37- delete cache ! [ key ] ;
113+ return loadCache ( ) . then ( ( cache ) => {
114+ delete cache [ key ] ;
115+ } ) ;
116+ }
117+
118+ function deleteStorage ( key : string ) {
119+ return new Promise < void > ( ( resolve ) => {
120+ chrome . storage . local . remove ( key , ( ) => {
121+ const lastError = chrome . runtime . lastError ;
122+ if ( lastError ) {
123+ console . error ( "chrome.runtime.lastError in chrome.storage.local.remove:" , lastError ) ;
124+ // 无视storage API错误,继续执行
125+ }
126+ resolve ( ) ;
127+ } ) ;
128+ } ) ;
129+ }
130+ function deletesStorage ( keys : string [ ] ) {
131+ return new Promise < void > ( ( resolve , reject ) => {
132+ chrome . storage . local . remove ( keys , ( ) => {
133+ const lastError = chrome . runtime . lastError ;
134+ if ( lastError ) {
135+ console . error ( "chrome.runtime.lastError in chrome.storage.local.remove:" , lastError ) ;
136+ // 无视storage API错误,继续执行
137+ reject ( ) ;
138+ }
139+ resolve ( ) ;
140+ } ) ;
141+ } ) . catch ( async ( ) => {
142+ // fallback
143+ for ( const key of keys ) {
144+ await deleteStorage ( key ) ;
145+ }
38146 } ) ;
39- return chrome . storage . local . remove ( key ) ;
40147}
41148
42149export abstract class Repo < T > {
@@ -58,44 +165,41 @@ export abstract class Repo<T> {
58165 }
59166
60167 protected async _save ( key : string , val : T ) : Promise < T > {
61- return new Promise ( ( resolve ) => {
62- const data = {
63- [ this . joinKey ( key ) ] : val ,
64- } ;
65- if ( this . useCache ) {
66- return saveCache ( this . joinKey ( key ) , val ) . then ( ( ) => {
67- return resolve ( val ) ;
68- } ) ;
69- }
70- chrome . storage . local . set ( data , ( ) => {
71- const lastError = chrome . runtime . lastError ;
72- if ( lastError ) {
73- console . error ( "chrome.runtime.lastError in chrome.storage.local.set:" , lastError ) ;
74- // 无视storage API错误,继续执行
75- }
76- resolve ( val ) ;
77- } ) ;
78- } ) ;
168+ key = this . joinKey ( key ) ;
169+ if ( this . useCache ) {
170+ return saveCacheAndStorage ( key , val ) ;
171+ }
172+ return saveStorage ( key , val ) ;
79173 }
80174
81175 public get ( key : string ) : Promise < T | undefined > {
176+ key = this . joinKey ( key ) ;
177+ if ( this . useCache ) {
178+ return getCache ( key ) ;
179+ }
180+ return getStorage ( key ) ;
181+ }
182+
183+ public gets ( keys : string [ ] ) : Promise < ( T | undefined ) [ ] > {
184+ keys = keys . map ( ( key ) => this . joinKey ( key ) ) ;
82185 if ( this . useCache ) {
83186 return loadCache ( ) . then ( ( cache ) => {
84- if ( cache [ this . joinKey ( key ) ] ) {
85- return Object . assign ( { } , cache [ this . joinKey ( key ) ] ) ;
86- }
87- return cache [ this . joinKey ( key ) ] ;
187+ return keys . map ( ( key ) => {
188+ if ( cache [ key ] ) {
189+ return Object . assign ( { } , cache [ key ] ) ;
190+ }
191+ return cache [ key ] ;
192+ } ) ;
88193 } ) ;
89194 }
90195 return new Promise ( ( resolve ) => {
91- key = this . joinKey ( key ) ;
92- chrome . storage . local . get ( key , ( result ) => {
196+ chrome . storage . local . get ( keys , ( result ) => {
93197 const lastError = chrome . runtime . lastError ;
94198 if ( lastError ) {
95199 console . error ( "chrome.runtime.lastError in chrome.storage.local.get:" , lastError ) ;
96200 // 无视storage API错误,继续执行
97201 }
98- resolve ( result [ key ] ) ;
202+ resolve ( keys . map ( ( key ) => result [ key ] ) ) ;
99203 } ) ;
100204 } ) ;
101205 }
@@ -123,69 +227,98 @@ export abstract class Repo<T> {
123227 } ) ;
124228 } ) ;
125229 }
126- const loadData = ( ) => {
127- return new Promise < T [ ] > ( ( resolve ) => {
128- chrome . storage . local . get ( ( result : { [ key : string ] : T } ) => {
129- const lastError = chrome . runtime . lastError ;
130- if ( lastError ) {
131- console . error ( "chrome.runtime.lastError in chrome.storage.local.get:" , lastError ) ;
132- // 无视storage API错误,继续执行
133- }
134- resolve ( this . filter ( result , filters ) ) ;
135- } ) ;
230+ return new Promise < T [ ] > ( ( resolve ) => {
231+ chrome . storage . local . get ( ( result : { [ key : string ] : T } ) => {
232+ const lastError = chrome . runtime . lastError ;
233+ if ( lastError ) {
234+ console . error ( "chrome.runtime.lastError in chrome.storage.local.get:" , lastError ) ;
235+ // 无视storage API错误,继续执行
236+ }
237+ resolve ( this . filter ( result , filters ) ) ;
136238 } ) ;
137- } ;
138- return loadData ( ) ;
239+ } ) ;
139240 }
140241
141242 async findOne ( filters ?: ( key : string , value : T ) => boolean ) : Promise < T | undefined > {
142- const list = await this . find ( filters ) ;
143- if ( list . length > 0 ) {
144- return list [ 0 ] ;
145- }
146- return undefined ;
243+ return this . find ( filters ) . then ( ( list ) => {
244+ if ( list . length > 0 ) {
245+ return list [ 0 ] ;
246+ }
247+ return undefined ;
248+ } ) ;
147249 }
148250
149- public delete ( key : string ) {
251+ public delete ( key : string ) : Promise < void > {
252+ key = this . joinKey ( key ) ;
150253 if ( this . useCache ) {
151- return deleteCache ( this . joinKey ( key ) ) ;
254+ return Promise . all ( [ deleteCache ( key ) , deleteStorage ( key ) ] ) . then ( ( ) => undefined ) ;
152255 }
153- return new Promise < void > ( ( resolve ) => {
154- chrome . storage . local . remove ( this . joinKey ( key ) , ( ) => {
155- const lastError = chrome . runtime . lastError ;
156- if ( lastError ) {
157- console . error ( "chrome.runtime.lastError in chrome.storage.local.remove:" , lastError ) ;
158- // 无视storage API错误,继续执行
256+ return deleteStorage ( key ) ;
257+ }
258+
259+ public deletes ( keys : string [ ] ) : Promise < void > {
260+ keys = keys . map ( ( key ) => this . joinKey ( key ) ) ;
261+ if ( this . useCache ) {
262+ return loadCache ( ) . then ( ( cache ) => {
263+ for ( const key of keys ) {
264+ delete cache [ key ] ;
159265 }
160- resolve ( ) ;
266+ return deletesStorage ( keys ) ;
161267 } ) ;
162- } ) ;
268+ }
269+ return deletesStorage ( keys ) ;
163270 }
164271
272+ // 資料不存在時無法更新, 回傳 false
273+ // 資料存在時進行Object.assign更新,回傳更新後的資料項目
165274 update ( key : string , val : Partial < T > ) : Promise < T | false > {
275+ key = this . joinKey ( key ) ;
166276 if ( this . useCache ) {
167277 return loadCache ( ) . then ( ( cache ) => {
168- const data = cache [ this . joinKey ( key ) ] ;
278+ const data = cache [ key ] as T ;
169279 if ( data ) {
170280 Object . assign ( data , val ) ;
171- return saveCache ( this . joinKey ( key ) , data ) . then ( ( ) => {
172- return data ;
173- } ) ;
281+ return saveCacheAndStorage ( key , data ) as Promise < T | false > ;
174282 }
175283 return false ;
176284 } ) ;
177285 }
178- return new Promise ( ( resolve ) => {
179- this . get ( key ) . then ( ( result ) => {
180- if ( result ) {
181- Object . assign ( result , val ) ;
182- this . _save ( key , result ) . then ( ( ) => {
183- resolve ( result ) ;
184- } ) ;
185- } else {
186- resolve ( false ) ;
286+ return getStorage ( key ) . then ( ( result ) => {
287+ if ( result ) {
288+ Object . assign ( result , val ) ;
289+ return saveStorage ( key , result ) as T ;
290+ } else {
291+ return false ;
292+ }
293+ } ) ;
294+ }
295+
296+ updates ( keys : string [ ] , val : Partial < T > ) : Promise < ( T | false ) [ ] > {
297+ keys = keys . map ( ( key ) => this . joinKey ( key ) ) ;
298+ if ( this . useCache ) {
299+ return loadCache ( ) . then ( ( cache ) =>
300+ Promise . all (
301+ keys . map ( ( key ) => {
302+ const data = cache [ key ] as T ;
303+ if ( data ) {
304+ Object . assign ( data , val ) ;
305+ return saveCacheAndStorage ( key , data ) as Promise < T > ;
306+ }
307+ return false ;
308+ } )
309+ )
310+ ) ;
311+ }
312+ return getStorageRecord ( keys ) . then ( ( record ) => {
313+ const result = keys . map ( ( key ) => {
314+ const o = record [ key ] ;
315+ if ( o ) {
316+ Object . assign ( o , val ) ;
317+ return o as T ;
187318 }
319+ return false ;
188320 } ) ;
321+ return saveStorageRecord ( record ) . then ( ( ) => result ) ;
189322 } ) ;
190323 }
191324
0 commit comments