-
Notifications
You must be signed in to change notification settings - Fork 40
/
Copy pathstorage.js
96 lines (83 loc) · 2.42 KB
/
storage.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
// @flow
import { Client } from './ipc'
export const NAMESPACE = 'solid-auth-client'
export interface AsyncStorage {
getItem(key: string): Promise<?string>;
setItem(key: string, val: string): Promise<void>;
removeItem(key: string): Promise<void>;
}
export type Storage = Storage | AsyncStorage
export const defaultStorage = () => {
const hasLocalStorage =
typeof window !== 'undefined' && 'localStorage' in window
return asyncStorage(hasLocalStorage ? window.localStorage : memStorage())
}
/**
* Gets the deserialized stored data
*/
export async function getData(store: Storage): Promise<Object> {
let serialized
let data
try {
serialized = await store.getItem(NAMESPACE)
data = JSON.parse(serialized || '{}')
} catch (e) {
console.warn('Could not deserialize data:', serialized)
console.error(e)
data = {}
}
return data
}
/**
* Updates a Storage object without mutating its intermediate representation.
*/
export async function updateStorage(
store: Storage,
update: (Object) => Object
): Promise<Object> {
const currentData = await getData(store)
const newData = update(currentData)
await store.setItem(NAMESPACE, JSON.stringify(newData))
return newData
}
/**
* Takes a synchronous storage interface and wraps it with an async interface.
*/
export function asyncStorage(storage: Storage): AsyncStorage {
return {
getItem: (key: string): Promise<?string> => {
return Promise.resolve(storage.getItem(key))
},
setItem: (key: string, val: string): Promise<void> => {
return Promise.resolve(storage.setItem(key, val))
},
removeItem: (key: string): Promise<void> => {
return Promise.resolve(storage.removeItem(key))
},
}
}
export const memStorage = (): Storage => {
const store = {}
return {
getItem: (key: string): ?string => {
if (typeof store[key] === 'undefined') return null
return store[key]
},
setItem: (key: string, val: string): void => {
store[key] = val
},
removeItem: (key: string): void => {
delete store[key]
},
}
}
export function ipcStorage(client: Client): AsyncStorage {
return {
getItem: (key: string): Promise<?string> =>
client.request('storage/getItem', key),
setItem: (key: string, val: string): Promise<void> =>
client.request('storage/setItem', key, val),
removeItem: (key: string): Promise<void> =>
client.request('storage/removeItem', key),
}
}