1
- type IStorage = {
2
- count : number ;
3
- } ;
4
-
5
- const defaultStorage : IStorage = {
6
- count : 0 ,
7
- } ;
8
-
9
- export const storage = {
10
- get : ( ) : Promise < IStorage > =>
11
- chrome . storage . sync . get ( defaultStorage ) as Promise < IStorage > ,
12
- set : ( value : IStorage ) : Promise < void > => chrome . storage . sync . set ( value ) ,
13
- } ;
1
+ import { writable , type Writable } from 'svelte/store' ;
2
+
3
+ /**
4
+ * Creates a persistent Svelte store backed by Chrome's sync storage.
5
+ * @template T The type of the store's value
6
+ * @param key The key to use in Chrome's storage
7
+ * @param initialValue The initial value of the store
8
+ * @returns A writable Svelte store
9
+ */
10
+ export function persistentStore < T > ( key : string , initialValue : T ) : Writable < T > {
11
+ const store = writable ( initialValue ) ;
12
+ // Ensure each value is updated exactly once in store and in chrome storage
13
+ let storeValueQueue : T [ ] = [ ] ;
14
+ let chromeValueQueue : T [ ] = [ ] ;
15
+
16
+ function watchStore ( ) {
17
+ store . subscribe ( ( value ) => {
18
+ if ( chromeValueQueue . length > 0 && value === chromeValueQueue [ 0 ] ) {
19
+ chromeValueQueue . shift ( ) ;
20
+ return ;
21
+ }
22
+
23
+ storeValueQueue . push ( value ) ;
24
+ chrome . storage . sync . set ( { [ key ] : value } ) ;
25
+ } ) ;
26
+ }
27
+
28
+ function watchChrome ( ) {
29
+ chrome . storage . sync . onChanged . addListener ( ( changes ) => {
30
+ if ( ! ( Object . hasOwn ( changes , key ) ) ) return ;
31
+
32
+ const value = changes [ key ] . newValue as T ;
33
+ if ( storeValueQueue . length > 0 && value === storeValueQueue [ 0 ] ) {
34
+ storeValueQueue . shift ( ) ;
35
+ return ;
36
+ }
37
+
38
+ chromeValueQueue . push ( value ) ;
39
+ store . set ( value ) ;
40
+ } ) ;
41
+ }
42
+
43
+ // Initialize the store with the value from Chrome storage
44
+ chrome . storage . sync . get ( key ) . then ( ( result ) => {
45
+ let value = Object . hasOwn ( result , key ) ? result [ key ] : initialValue ;
46
+ if ( ! Object . hasOwn ( result , key ) ) {
47
+ console . log ( `Persistent store: couldn't find key [${ key } ] in chrome storage. Default to initial value [${ initialValue } ]` )
48
+ }
49
+ chromeValueQueue . push ( value ) ;
50
+ store . set ( value ) ;
51
+ watchStore ( ) ;
52
+ watchChrome ( ) ;
53
+ } ) ;
54
+
55
+ return store ;
56
+ }
57
+
58
+ export const count = persistentStore ( "count" , 10 ) ;
0 commit comments