|
1 | 1 | /* eslint-disable no-empty */
|
2 |
| -import { isRef, ref, Ref, UnwrapRef, watchEffect } from 'vue' |
| 2 | +import { unref, ref, Ref, UnwrapRef, watchEffect } from 'vue' |
3 | 3 |
|
4 | 4 | export interface IFuncUpdater<T> {
|
5 |
| - (previousState?: T): T |
| 5 | + (previousState?: T): T |
6 | 6 | }
|
7 | 7 | export interface IFuncStorage {
|
8 |
| - (): Storage |
| 8 | + (): Storage |
9 | 9 | }
|
10 | 10 |
|
11 | 11 | export interface Options<T> {
|
12 |
| - serializer?: (value: T) => string |
13 |
| - deserializer?: (value: string) => T |
| 12 | + serializer?: (value: T) => string |
| 13 | + deserializer?: (value: string) => T |
14 | 14 | }
|
15 | 15 |
|
16 | 16 | export interface OptionsWithDefaultValue<T> extends Options<T> {
|
17 |
| - defaultValue: T | IFuncUpdater<T> |
| 17 | + defaultValue: T | IFuncUpdater<T> |
18 | 18 | }
|
19 | 19 |
|
20 |
| -export type StorageStateResult<T> = [ |
21 |
| - Ref<T> | Ref<undefined>, |
22 |
| - (value?: T | IFuncUpdater<T>) => void |
23 |
| -] |
| 20 | +export type StorageStateResult<T> = [Ref<T> | Ref<undefined>, (value?: T | IFuncUpdater<T>) => void] |
24 | 21 | export type StorageStateResultHasDefaultValue<T> = [
|
25 |
| - Ref<T> | Ref<undefined>, |
26 |
| - (value?: T | IFuncUpdater<T> | undefined) => void |
| 22 | + Ref<T> | Ref<undefined>, |
| 23 | + (value?: T | IFuncUpdater<T> | undefined) => void, |
27 | 24 | ]
|
28 | 25 |
|
29 | 26 | function isFunction<T>(obj: any): obj is T {
|
30 |
| - return typeof obj === 'function' |
| 27 | + return typeof obj === 'function' |
31 | 28 | }
|
32 | 29 |
|
33 | 30 | export function createUseStorageState(getStorage: () => Storage | undefined) {
|
34 |
| - function useStorageState<T>( |
35 |
| - key: Ref<string> | string, |
36 |
| - options?: OptionsWithDefaultValue<T> |
37 |
| - ): StorageStateResultHasDefaultValue<T> |
| 31 | + function useStorageState<T>( |
| 32 | + key: Ref<string> | string, |
| 33 | + options?: OptionsWithDefaultValue<T>, |
| 34 | + ): StorageStateResultHasDefaultValue<T> |
38 | 35 |
|
39 |
| - function useStorageState<T>( |
40 |
| - key: Ref<string> | string, |
41 |
| - options?: Options<T> & OptionsWithDefaultValue<T> |
42 |
| - ) { |
43 |
| - let storage: Storage | undefined |
44 |
| - try { |
45 |
| - storage = getStorage() |
46 |
| - } catch (err) { |
47 |
| - console.error(err) |
48 |
| - } |
| 36 | + function useStorageState<T>( |
| 37 | + key: Ref<string> | string, |
| 38 | + options?: Options<T> & OptionsWithDefaultValue<T>, |
| 39 | + ) { |
| 40 | + let storage: Storage | undefined |
| 41 | + try { |
| 42 | + storage = getStorage() |
| 43 | + } catch (err) { |
| 44 | + console.error(err) |
| 45 | + } |
49 | 46 |
|
50 |
| - const serializer = (value: T) => { |
51 |
| - if (options?.serializer) { |
52 |
| - return options?.serializer(value) |
53 |
| - } |
54 |
| - return JSON.stringify(value) |
55 |
| - } |
| 47 | + const serializer = (value: T) => { |
| 48 | + if (options?.serializer) { |
| 49 | + return options?.serializer(value) |
| 50 | + } |
| 51 | + return JSON.stringify(value) |
| 52 | + } |
56 | 53 |
|
57 |
| - const deserializer = (value: string) => { |
58 |
| - if (options?.deserializer) { |
59 |
| - return options?.deserializer(value) |
60 |
| - } |
61 |
| - return JSON.parse(value) |
62 |
| - } |
| 54 | + const deserializer = (value: string) => { |
| 55 | + if (options?.deserializer) { |
| 56 | + return options?.deserializer(value) |
| 57 | + } |
| 58 | + return JSON.parse(value) |
| 59 | + } |
63 | 60 |
|
64 |
| - function getStoredValue() { |
65 |
| - try { |
66 |
| - const raw = storage?.getItem(isRef(key) ? key.value : key) |
67 |
| - if (raw) { |
68 |
| - return deserializer(raw) |
69 |
| - } |
70 |
| - } catch (e) { |
71 |
| - console.error(e) |
72 |
| - } |
73 |
| - if (isFunction<IFuncUpdater<T>>(options?.defaultValue)) { |
74 |
| - return options?.defaultValue() |
75 |
| - } |
76 |
| - return options?.defaultValue |
77 |
| - } |
78 |
| - const state = ref<T | undefined>(getStoredValue()) |
79 |
| - watchEffect(() => { |
80 |
| - if (key) state.value = getStoredValue() |
81 |
| - }) |
| 61 | + function getStoredValue() { |
| 62 | + try { |
| 63 | + const raw = storage?.getItem(unref(key)) |
| 64 | + if (raw) { |
| 65 | + return deserializer(raw) |
| 66 | + } |
| 67 | + } catch (e) { |
| 68 | + console.error(e) |
| 69 | + } |
| 70 | + if (isFunction<IFuncUpdater<T>>(options?.defaultValue)) { |
| 71 | + return options?.defaultValue() |
| 72 | + } |
| 73 | + return options?.defaultValue |
| 74 | + } |
| 75 | + const state = ref<T | undefined>(getStoredValue()) |
| 76 | + watchEffect(() => { |
| 77 | + if (key) state.value = getStoredValue() |
| 78 | + }) |
82 | 79 |
|
83 |
| - const updateState = (value?: T | IFuncUpdater<T>) => { |
84 |
| - if (typeof value === 'undefined') { |
85 |
| - state.value = undefined |
86 |
| - storage?.removeItem(isRef(key) ? key.value : key) |
87 |
| - } else if (isFunction<IFuncUpdater<T>>(value)) { |
88 |
| - const currentState = value(state.value as T) |
89 |
| - try { |
90 |
| - state.value = currentState as UnwrapRef<T> |
91 |
| - storage?.setItem( |
92 |
| - isRef(key) ? key.value : key, |
93 |
| - serializer(currentState) |
94 |
| - ) |
95 |
| - } catch (e) { |
96 |
| - console.error(e) |
97 |
| - } |
98 |
| - } else { |
99 |
| - try { |
100 |
| - state.value = value as UnwrapRef<T> |
101 |
| - storage?.setItem(isRef(key) ? key.value : key, serializer(value)) |
102 |
| - } catch (e) { |
103 |
| - console.error(e) |
104 |
| - } |
105 |
| - } |
106 |
| - } |
| 80 | + const updateState = (value?: T | IFuncUpdater<T>) => { |
| 81 | + if (typeof value === 'undefined') { |
| 82 | + state.value = undefined |
| 83 | + storage?.removeItem(unref(key)) |
| 84 | + } else if (isFunction<IFuncUpdater<T>>(value)) { |
| 85 | + const currentState = value(state.value as T) |
| 86 | + try { |
| 87 | + state.value = currentState as UnwrapRef<T> |
| 88 | + storage?.setItem(unref(key), serializer(currentState)) |
| 89 | + } catch (e) { |
| 90 | + console.error(e) |
| 91 | + } |
| 92 | + } else { |
| 93 | + try { |
| 94 | + state.value = value as UnwrapRef<T> |
| 95 | + storage?.setItem(unref(key), serializer(value)) |
| 96 | + } catch (e) { |
| 97 | + console.error(e) |
| 98 | + } |
| 99 | + } |
| 100 | + } |
107 | 101 |
|
108 |
| - return [state, updateState] |
109 |
| - } |
110 |
| - return useStorageState |
| 102 | + return [state, updateState] |
| 103 | + } |
| 104 | + return useStorageState |
111 | 105 | }
|
0 commit comments