1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 | export default class LocalStorage {
|
7 | static async safePromise(resolver) {
|
8 | try {
|
9 | return await new Promise(resolver);
|
10 | } catch (e) {
|
11 | if (e && e.name === 'NS_ERROR_FILE_CORRUPTED') {
|
12 |
|
13 | window.alert('Sorry, it looks like your browser storage is corrupted. ' +
|
14 | 'Please clear your storage by going to Tools -> Clear Recent History -> Cookies' +
|
15 | ' and setting time range to "Everything". This will remove the corrupted browser storage across all sites.');
|
16 |
|
17 | }
|
18 | throw e;
|
19 | }
|
20 | }
|
21 |
|
22 | constructor(config = {}) {
|
23 | this.storageType = config.type === 'session' ? 'sessionStorage' : 'localStorage';
|
24 | }
|
25 |
|
26 | |
27 |
|
28 |
|
29 |
|
30 | get(name) {
|
31 | return this.constructor.safePromise(resolve => {
|
32 | const value = window[this.storageType].getItem(name);
|
33 | try {
|
34 | resolve(JSON.parse(value));
|
35 | } catch (e) {
|
36 | resolve(value);
|
37 | }
|
38 | });
|
39 | }
|
40 |
|
41 | |
42 |
|
43 |
|
44 |
|
45 |
|
46 | set(name, value) {
|
47 | return this.constructor.safePromise(resolve => {
|
48 | window[this.storageType].setItem(name, JSON.stringify(value));
|
49 | resolve(value);
|
50 | });
|
51 | }
|
52 |
|
53 | |
54 |
|
55 |
|
56 |
|
57 | remove(name) {
|
58 | const storageType = this.storageType;
|
59 |
|
60 | return this.constructor.safePromise(resolve => {
|
61 | if (window[storageType].hasOwnProperty(name)) {
|
62 | window[storageType].removeItem(name);
|
63 | }
|
64 | resolve();
|
65 | });
|
66 | }
|
67 |
|
68 | |
69 |
|
70 |
|
71 |
|
72 | each(callback) {
|
73 | const storageType = this.storageType;
|
74 |
|
75 | return this.constructor.safePromise(resolve => {
|
76 | const promises = [];
|
77 |
|
78 | for (const item in window[storageType]) {
|
79 | if (window[storageType].hasOwnProperty(item)) {
|
80 | let value = window[storageType].getItem(item);
|
81 | try {
|
82 | value = JSON.parse(value);
|
83 | } catch (e) {
|
84 |
|
85 | }
|
86 |
|
87 | promises.push(Promise.resolve(callback(item, value)));
|
88 | }
|
89 | }
|
90 |
|
91 | resolve(Promise.all(promises));
|
92 | });
|
93 | }
|
94 |
|
95 | |
96 |
|
97 |
|
98 |
|
99 |
|
100 | on(name, callback) {
|
101 | function handleStorage(e) {
|
102 | if (e.key === name) {
|
103 | try {
|
104 | callback(JSON.parse(e.newValue));
|
105 | } catch (err) {
|
106 | callback(e.newValue);
|
107 | }
|
108 | }
|
109 | }
|
110 |
|
111 | window.addEventListener('storage', handleStorage, false);
|
112 |
|
113 | return () => window.removeEventListener('storage', handleStorage, false);
|
114 | }
|
115 | }
|