Revision 53891495
Added by koszko about 2 years ago
background/storage.js | ||
---|---|---|
7 | 7 |
|
8 | 8 |
/* |
9 | 9 |
* IMPORTS_START |
10 |
* IMPORT TYPE_PREFIX
|
|
10 |
* IMPORT raw_storage
|
|
11 | 11 |
* IMPORT TYPE_NAME |
12 | 12 |
* IMPORT list_prefixes |
13 | 13 |
* IMPORT make_lock |
... | ... | |
15 | 15 |
* IMPORT unlock |
16 | 16 |
* IMPORT make_once |
17 | 17 |
* IMPORT browser |
18 |
* IMPORT is_chrome |
|
19 | 18 |
* IMPORT observables |
20 | 19 |
* IMPORTS_END |
21 | 20 |
*/ |
22 | 21 |
|
23 | 22 |
var exports = {}; |
24 | 23 |
|
25 |
/* We're yet to decide how to handle errors... */ |
|
26 |
|
|
27 |
/* Here are some basic wrappers for storage API functions */ |
|
28 |
|
|
29 |
async function get(key) |
|
30 |
{ |
|
31 |
try { |
|
32 |
/* Fix for fact that Chrome does not use promises here */ |
|
33 |
let promise = is_chrome ? |
|
34 |
new Promise((resolve, reject) => |
|
35 |
chrome.storage.local.get(key, |
|
36 |
val => resolve(val))) : |
|
37 |
browser.storage.local.get(key); |
|
38 |
|
|
39 |
return (await promise)[key]; |
|
40 |
} catch (e) { |
|
41 |
console.log(e); |
|
42 |
} |
|
43 |
} |
|
44 |
|
|
45 |
async function set(key, value) |
|
46 |
{ |
|
47 |
try { |
|
48 |
return browser.storage.local.set({[key]: value}); |
|
49 |
} catch (e) { |
|
50 |
console.log(e); |
|
51 |
} |
|
52 |
} |
|
53 |
|
|
54 |
async function setn(keys_and_values) |
|
55 |
{ |
|
56 |
let obj = Object(); |
|
57 |
while (keys_and_values.length > 1) { |
|
58 |
let value = keys_and_values.pop(); |
|
59 |
let key = keys_and_values.pop(); |
|
60 |
obj[key] = value; |
|
61 |
} |
|
62 |
|
|
63 |
try { |
|
64 |
return browser.storage.local.set(obj); |
|
65 |
} catch (e) { |
|
66 |
console.log(e); |
|
67 |
} |
|
68 |
} |
|
69 |
|
|
70 |
async function set_var(name, value) |
|
71 |
{ |
|
72 |
return set(TYPE_PREFIX.VAR + name, value); |
|
73 |
} |
|
74 |
|
|
75 |
async function get_var(name) |
|
76 |
{ |
|
77 |
return get(TYPE_PREFIX.VAR + name); |
|
78 |
} |
|
79 |
|
|
80 |
/* |
|
81 |
* A special case of persisted variable is one that contains list |
|
82 |
* of items. |
|
83 |
*/ |
|
24 |
/* A special case of persisted variable is one that contains list of items. */ |
|
84 | 25 |
|
85 | 26 |
async function get_list_var(name) |
86 | 27 |
{ |
87 |
let list = await get_var(name); |
|
28 |
let list = await raw_storage.get_var(name);
|
|
88 | 29 |
|
89 | 30 |
return list === undefined ? [] : list; |
90 | 31 |
} |
... | ... | |
97 | 38 |
let map = new Map(); |
98 | 39 |
|
99 | 40 |
for (let item of await get_list_var(name)) |
100 |
map.set(item, await get(prefix + item)); |
|
41 |
map.set(item, await raw_storage.get(prefix + item));
|
|
101 | 42 |
|
102 | 43 |
return {map, prefix, name, observable: observables.make(), |
103 | 44 |
lock: make_lock()}; |
... | ... | |
175 | 116 |
} |
176 | 117 |
async function _set_item(item, value, list) |
177 | 118 |
{ |
178 |
let key = list.prefix + item; |
|
179 |
let old_val = list.map.get(item); |
|
119 |
const key = list.prefix + item; |
|
120 |
const old_val = list.map.get(item); |
|
121 |
const set_obj = {[key]: value}; |
|
180 | 122 |
if (old_val === undefined) { |
181 |
let items = list_items(list);
|
|
123 |
const items = list_items(list);
|
|
182 | 124 |
items.push(item); |
183 |
await setn([key, value, "_" + list.name, items]); |
|
184 |
} else { |
|
185 |
await set(key, value); |
|
125 |
set_obj["_" + list.name] = items; |
|
186 | 126 |
} |
187 | 127 |
|
188 |
list.map.set(item, value) |
|
128 |
await raw_storage.set(set_obj); |
|
129 |
list.map.set(item, value); |
|
189 | 130 |
|
190 |
let change = {
|
|
131 |
const change = {
|
|
191 | 132 |
prefix : list.prefix, |
192 | 133 |
item, |
193 | 134 |
old_val, |
... | ... | |
212 | 153 |
} |
213 | 154 |
async function _remove_item(item, list) |
214 | 155 |
{ |
215 |
let old_val = list.map.get(item);
|
|
156 |
const old_val = list.map.get(item);
|
|
216 | 157 |
if (old_val === undefined) |
217 | 158 |
return; |
218 | 159 |
|
219 |
let key = list.prefix + item; |
|
220 |
let items = list_items(list); |
|
221 |
let index = items.indexOf(item); |
|
160 |
const items = list_items(list); |
|
161 |
const index = items.indexOf(item); |
|
222 | 162 |
items.splice(index, 1); |
223 | 163 |
|
224 |
await setn([key, undefined, "_" + list.name, items]); |
|
225 |
|
|
164 |
await raw_storage.set({ |
|
165 |
[list.prefix + item]: undefined, |
|
166 |
["_" + list.name]: items |
|
167 |
}); |
|
226 | 168 |
list.map.delete(item); |
227 | 169 |
|
228 |
let change = {
|
|
170 |
const change = {
|
|
229 | 171 |
prefix : list.prefix, |
230 | 172 |
item, |
231 | 173 |
old_val, |
... | ... | |
247 | 189 |
} |
248 | 190 |
async function _replace_item(old_item, new_item, list, new_val=undefined) |
249 | 191 |
{ |
250 |
let old_val = list.map.get(old_item);
|
|
192 |
const old_val = list.map.get(old_item);
|
|
251 | 193 |
if (new_val === undefined) { |
252 | 194 |
if (old_val === undefined) |
253 | 195 |
return; |
254 |
new_val = old_val |
|
196 |
new_val = old_val;
|
|
255 | 197 |
} else if (new_val === old_val && new_item === old_item) { |
256 | 198 |
return old_val; |
257 | 199 |
} |
... | ... | |
261 | 203 |
return old_val; |
262 | 204 |
} |
263 | 205 |
|
264 |
let new_key = list.prefix + new_item; |
|
265 |
let old_key = list.prefix + old_item; |
|
266 |
let items = list_items(list); |
|
267 |
let index = items.indexOf(old_item); |
|
206 |
const items = list_items(list); |
|
207 |
const index = items.indexOf(old_item); |
|
268 | 208 |
items[index] = new_item; |
269 |
await setn([old_key, undefined, new_key, new_val, |
|
270 |
"_" + list.name, items]); |
|
271 | 209 |
|
210 |
await raw_storage.set({ |
|
211 |
[list.prefix + old_item]: undefined, |
|
212 |
[list.prefix + new_item]: new_val, |
|
213 |
["_" + list.name]: items |
|
214 |
}); |
|
272 | 215 |
list.map.delete(old_item); |
273 | 216 |
|
274 |
let change = {
|
|
217 |
const change = {
|
|
275 | 218 |
prefix : list.prefix, |
276 | 219 |
item : old_item, |
277 | 220 |
old_val, |
Also available in: Unified diff
put simplest, asynchronous local storage operations in a separate file