@xiao-ying/miniapp-hooks 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/LICENSE +35 -0
  2. package/README.md +47 -0
  3. package/dist/index.d.ts +11 -0
  4. package/dist/index.d.ts.map +1 -0
  5. package/dist/index.js +12 -0
  6. package/dist/index.js.map +1 -0
  7. package/dist/use-auth-state.d.ts +18 -0
  8. package/dist/use-auth-state.d.ts.map +1 -0
  9. package/dist/use-auth-state.js +44 -0
  10. package/dist/use-auth-state.js.map +1 -0
  11. package/dist/use-brightness.d.ts +13 -0
  12. package/dist/use-brightness.d.ts.map +1 -0
  13. package/dist/use-brightness.js +38 -0
  14. package/dist/use-brightness.js.map +1 -0
  15. package/dist/use-foreground.d.ts +12 -0
  16. package/dist/use-foreground.d.ts.map +1 -0
  17. package/dist/use-foreground.js +24 -0
  18. package/dist/use-foreground.js.map +1 -0
  19. package/dist/use-haptic-feedback.d.ts +20 -0
  20. package/dist/use-haptic-feedback.d.ts.map +1 -0
  21. package/dist/use-haptic-feedback.js +21 -0
  22. package/dist/use-haptic-feedback.js.map +1 -0
  23. package/dist/use-media-query.d.ts +20 -0
  24. package/dist/use-media-query.d.ts.map +1 -0
  25. package/dist/use-media-query.js +36 -0
  26. package/dist/use-media-query.js.map +1 -0
  27. package/dist/use-sdk-error.d.ts +47 -0
  28. package/dist/use-sdk-error.d.ts.map +1 -0
  29. package/dist/use-sdk-error.js +60 -0
  30. package/dist/use-sdk-error.js.map +1 -0
  31. package/dist/use-share.d.ts +23 -0
  32. package/dist/use-share.d.ts.map +1 -0
  33. package/dist/use-share.js +72 -0
  34. package/dist/use-share.js.map +1 -0
  35. package/dist/use-storage.d.ts +37 -0
  36. package/dist/use-storage.d.ts.map +1 -0
  37. package/dist/use-storage.js +132 -0
  38. package/dist/use-storage.js.map +1 -0
  39. package/package.json +43 -0
  40. package/src/index.ts +36 -0
  41. package/src/use-auth-state.ts +51 -0
  42. package/src/use-brightness.ts +44 -0
  43. package/src/use-foreground.ts +28 -0
  44. package/src/use-haptic-feedback.ts +32 -0
  45. package/src/use-media-query.ts +48 -0
  46. package/src/use-sdk-error.ts +110 -0
  47. package/src/use-share.ts +84 -0
  48. package/src/use-storage.ts +170 -0
@@ -0,0 +1,170 @@
1
+ import { useCallback, useEffect, useRef, useState } from 'react'
2
+
3
+ /**
4
+ * useStorage 的配置项。
5
+ *
6
+ * @param defaultValue - 初始值(当 storage 为空时使用)。
7
+ * @param disabled - 禁用读写与订阅。
8
+ */
9
+ export interface UseStorageOptions<T> {
10
+ defaultValue?: T
11
+ disabled?: boolean
12
+ }
13
+
14
+ /**
15
+ * useStorage 的返回结果。
16
+ *
17
+ * - `value`: 当前值
18
+ * - `loading`: 是否在加载
19
+ * - `error`: 最近一次错误
20
+ * - `setValue/remove/refresh`: 操作方法
21
+ */
22
+ export interface UseStorageResult<T> {
23
+ value: T | null
24
+ loading: boolean
25
+ error?: unknown
26
+ setValue: (next: T) => Promise<void>
27
+ remove: () => Promise<void>
28
+ refresh: () => Promise<void>
29
+ }
30
+
31
+ /**
32
+ * 读取并订阅小应小程序存储的指定 key。
33
+ *
34
+ * @param key - storage key。
35
+ * @param options - 读取配置。
36
+ *
37
+ * @example
38
+ * const storage = useStorage<string>('nickname', { defaultValue: '游客' })
39
+ */
40
+ export const useStorage = <T = any>(
41
+ key: string,
42
+ options: UseStorageOptions<T> = {}
43
+ ): UseStorageResult<T> => {
44
+ const { defaultValue, disabled = false } = options
45
+ const initialDefault = (defaultValue as T | null | undefined) ?? null
46
+ const isMounted = useRef(true)
47
+
48
+ const [value, setValueState] = useState<T | null>(initialDefault)
49
+ const [loading, setLoading] = useState<boolean>(!disabled)
50
+ const [error, setError] = useState<unknown>()
51
+
52
+ useEffect(() => {
53
+ isMounted.current = true
54
+ return () => {
55
+ isMounted.current = false
56
+ }
57
+ }, [])
58
+
59
+ const setValueSafe = useCallback((next: T | null) => {
60
+ if (!isMounted.current) return
61
+ setValueState(next)
62
+ }, [])
63
+
64
+ const setLoadingSafe = useCallback((next: boolean) => {
65
+ if (!isMounted.current) return
66
+ setLoading(next)
67
+ }, [])
68
+
69
+ const setErrorSafe = useCallback((next?: unknown) => {
70
+ if (!isMounted.current) return
71
+ setError(next)
72
+ }, [])
73
+
74
+ const refresh = useCallback(async (): Promise<void> => {
75
+ if (disabled) {
76
+ setValueSafe(initialDefault)
77
+ setLoadingSafe(false)
78
+ setErrorSafe(undefined)
79
+ return
80
+ }
81
+
82
+ setLoadingSafe(true)
83
+ try {
84
+ const res = await xy.getStorage<T>({ key })
85
+ const resolved =
86
+ res?.data === null || typeof res?.data === 'undefined' ? initialDefault : res.data
87
+ setValueSafe(resolved as T | null)
88
+ setErrorSafe(undefined)
89
+ } catch (err) {
90
+ setErrorSafe(err)
91
+ throw err
92
+ } finally {
93
+ setLoadingSafe(false)
94
+ }
95
+ }, [disabled, initialDefault, key, setErrorSafe, setLoadingSafe, setValueSafe, xy])
96
+
97
+ useEffect(() => {
98
+ void refresh()
99
+ }, [refresh])
100
+
101
+ useEffect(() => {
102
+ if (disabled || typeof xy.onStorageChange !== 'function') {
103
+ return
104
+ }
105
+
106
+ const unsubscribe = xy.onStorageChange((event) => {
107
+ if (!event) return
108
+ if (event.key === '*' || event.key === key) {
109
+ const nextValue =
110
+ event.key === '*' ? initialDefault : ((event.newValue ?? initialDefault) as T | null)
111
+ setValueSafe(nextValue)
112
+ setErrorSafe(undefined)
113
+ }
114
+ })
115
+
116
+ return () => {
117
+ if (typeof unsubscribe === 'function') {
118
+ unsubscribe()
119
+ }
120
+ }
121
+ }, [disabled, initialDefault, key, setErrorSafe, setValueSafe, xy])
122
+
123
+ const setValue = useCallback(
124
+ async (next: T): Promise<void> => {
125
+ if (disabled) return
126
+ setLoadingSafe(true)
127
+ try {
128
+ const res = await xy.setStorage({ key, data: next })
129
+ if (res?.success === false) {
130
+ throw new Error('SET_STORAGE_FAILED')
131
+ }
132
+ setValueSafe(next)
133
+ setErrorSafe(undefined)
134
+ } catch (err) {
135
+ setErrorSafe(err)
136
+ throw err
137
+ } finally {
138
+ setLoadingSafe(false)
139
+ }
140
+ },
141
+ [disabled, key, setErrorSafe, setLoadingSafe, setValueSafe, xy]
142
+ )
143
+
144
+ const remove = useCallback(async (): Promise<void> => {
145
+ if (disabled) return
146
+ setLoadingSafe(true)
147
+ try {
148
+ const res = await xy.removeStorage({ key })
149
+ if (res?.success === false) {
150
+ throw new Error('REMOVE_STORAGE_FAILED')
151
+ }
152
+ setValueSafe(initialDefault)
153
+ setErrorSafe(undefined)
154
+ } catch (err) {
155
+ setErrorSafe(err)
156
+ throw err
157
+ } finally {
158
+ setLoadingSafe(false)
159
+ }
160
+ }, [disabled, initialDefault, key, setErrorSafe, setLoadingSafe, setValueSafe, xy])
161
+
162
+ return {
163
+ value,
164
+ loading,
165
+ error,
166
+ setValue,
167
+ remove,
168
+ refresh
169
+ }
170
+ }