-
-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathuseStorageDb.ts
More file actions
84 lines (70 loc) · 2.85 KB
/
Copy pathuseStorageDb.ts
File metadata and controls
84 lines (70 loc) · 2.85 KB
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
import type { SetStateAction } from 'react'
import { useMemo } from 'react'
import { useEvent } from '../useEvent'
import { useGlobalObject } from '../useGlobalObject'
import { useStorageState } from './useStorageState'
type UseStorageDb = Record<string, Array<UseStorageDbRecord>>
type UseStorageDbPrimaryKey = string | number
type UseStorageDbRecord = {
id: UseStorageDbPrimaryKey
[property: string]: unknown
}
type Params = {
id: UseStorageDbPrimaryKey
payload: UseStorageDbRecord
}
const useStorageDb = (key: string, storage: Storage) => {
const [value, setValue] = useStorageState(key, storage)
const db: Record<string, Array<UseStorageDbRecord>> = useMemo(() => {
return value ? JSON.parse(value) : {}
}, [value])
const setDb = useEvent((valueOrSetter: SetStateAction<UseStorageDb>) => {
const newValue = typeof valueOrSetter === 'function' ? valueOrSetter(db) : valueOrSetter
setValue(JSON.stringify(newValue))
})
return useMemo(
() => ({
createOne: (resource: string, params: Params) => {
setDb(current => ({
...current,
[resource]: [
...(current[resource] || []),
{
...params.payload
}
]
}))
},
getList: (resource: string, params: Params) => db[resource] || [],
getOne: (resource: string, params: Params) =>
db[resource]?.find((item: UseStorageDbRecord) => item.id === params.id),
updateOne: (resource: string, params: Params) => {
setDb(current => ({
...current,
[resource]: (current[resource] || []).map((itemToUpdate: UseStorageDbRecord) => {
if (itemToUpdate.id === params.id) {
return {
...itemToUpdate,
...params.payload,
id: itemToUpdate.id
}
}
return itemToUpdate
})
}))
},
deleteOne: (resource: string, params: Params) => {
setDb(current => ({
...current,
[resource]: (current[resource] || []).filter((itemToUpdate: UseStorageDbRecord) => {
return itemToUpdate.id !== params.id
})
}))
}
}),
[db, setDb]
)
}
const useLocalStorageDb = (key: string) => useStorageDb(key, useGlobalObject().localStorage)
const useSessionStorageDb = (key: string) => useStorageDb(key, useGlobalObject().sessionStorage)
export { useLocalStorageDb, useSessionStorageDb, useStorageDb }