UNPKG

7.07 kBPlain TextView Raw
1import type { ReactotronCore, Plugin } from "reactotron-core-client"
2import type { AsyncStorageStatic } from "@react-native-async-storage/async-storage"
3export interface AsyncStorageOptions {
4 ignore?: string[]
5}
6
7const PLUGIN_DEFAULTS: AsyncStorageOptions = {
8 ignore: [],
9}
10
11const asyncStorage = (options?: AsyncStorageOptions) => (reactotron: ReactotronCore) => {
12 // setup configuration
13 const config = Object.assign({}, PLUGIN_DEFAULTS, options || {})
14 const ignore = config.ignore || PLUGIN_DEFAULTS.ignore
15
16 let swizzSetItem: AsyncStorageStatic["setItem"]
17 let swizzRemoveItem: AsyncStorageStatic["removeItem"]
18 let swizzMergeItem: AsyncStorageStatic["mergeItem"]
19 let swizzClear: AsyncStorageStatic["clear"]
20 let swizzMultiSet: AsyncStorageStatic["multiSet"]
21 let swizzMultiRemove: AsyncStorageStatic["multiRemove"]
22 let swizzMultiMerge: AsyncStorageStatic["multiMerge"]
23 let isSwizzled = false
24
25 const sendToReactotron = (action: string, data?: any) => {
26 reactotron.send("asyncStorage.mutation", { action, data })
27 }
28
29 const setItem: AsyncStorageStatic["setItem"] = async (key, value, callback) => {
30 try {
31 if (ignore.indexOf(key) < 0) {
32 sendToReactotron("setItem", { key, value })
33 }
34 } catch (e) {}
35 return swizzSetItem(key, value, callback)
36 }
37
38 const removeItem: AsyncStorageStatic["removeItem"] = async (key, callback) => {
39 try {
40 if (ignore.indexOf(key) < 0) {
41 sendToReactotron("removeItem", { key })
42 }
43 } catch (e) {}
44 return swizzRemoveItem(key, callback)
45 }
46
47 const mergeItem: AsyncStorageStatic["mergeItem"] = async (key, value, callback) => {
48 try {
49 if (ignore.indexOf(key) < 0) {
50 sendToReactotron("mergeItem", { key, value })
51 }
52 } catch (e) {}
53 return swizzMergeItem(key, value, callback)
54 }
55
56 const clear: AsyncStorageStatic["clear"] = async (callback) => {
57 try {
58 sendToReactotron("clear")
59 } catch (e) {}
60 return swizzClear(callback)
61 }
62
63 const multiSet: AsyncStorageStatic["multiSet"] = async (pairs, callback) => {
64 try {
65 const shippablePairs = (pairs || []).filter(
66 (pair) => pair && pair[0] && ignore.indexOf(pair[0]) < 0
67 )
68 if (shippablePairs.length > 0) {
69 sendToReactotron("multiSet", { pairs: shippablePairs })
70 }
71 } catch (e) {}
72 return swizzMultiSet(pairs, callback)
73 }
74
75 const multiRemove: AsyncStorageStatic["multiRemove"] = async (keys, callback) => {
76 try {
77 const shippableKeys = (keys || []).filter((key) => ignore.indexOf(key) < 0)
78 if (shippableKeys.length > 0) {
79 sendToReactotron("multiRemove", { keys: shippableKeys })
80 }
81 } catch (e) {}
82 return swizzMultiRemove(keys, callback)
83 }
84
85 const multiMerge: AsyncStorageStatic["multiMerge"] = async (pairs, callback) => {
86 try {
87 const shippablePairs = (pairs || []).filter(
88 (pair) => pair && pair[0] && ignore.indexOf(pair[0]) < 0
89 )
90 if (shippablePairs.length > 0) {
91 sendToReactotron("multiMerge", { pairs: shippablePairs })
92 }
93 } catch (e) {}
94 return swizzMultiMerge(pairs, callback)
95 }
96
97 /**
98 * Hijacks the AsyncStorage API.
99 */
100 const trackAsyncStorage = () => {
101 if (isSwizzled) return
102
103 // eslint-disable-next-line @typescript-eslint/ban-ts-comment
104 // @ts-ignore: reactotron-apis
105 swizzSetItem = reactotron.asyncStorageHandler.setItem
106 // eslint-disable-next-line @typescript-eslint/ban-ts-comment
107 // @ts-ignore: reactotron-apis
108 reactotron.asyncStorageHandler.setItem = setItem
109
110 // eslint-disable-next-line @typescript-eslint/ban-ts-comment
111 // @ts-ignore: reactotron-apis
112 swizzRemoveItem = reactotron.asyncStorageHandler.removeItem
113
114 // eslint-disable-next-line @typescript-eslint/ban-ts-comment
115 // @ts-ignore: reactotron-apis
116 reactotron.asyncStorageHandler.removeItem = removeItem
117
118 // eslint-disable-next-line @typescript-eslint/ban-ts-comment
119 // @ts-ignore: reactotron-apis
120 swizzMergeItem = reactotron.asyncStorageHandler.mergeItem
121 // eslint-disable-next-line @typescript-eslint/ban-ts-comment
122 // @ts-ignore: reactotron-apis
123 reactotron.asyncStorageHandler.mergeItem = mergeItem
124
125 // eslint-disable-next-line @typescript-eslint/ban-ts-comment
126 // @ts-ignore: reactotron-apis
127 swizzClear = reactotron.asyncStorageHandler.clear
128 // eslint-disable-next-line @typescript-eslint/ban-ts-comment
129 // @ts-ignore: reactotron-apis
130 reactotron.asyncStorageHandler.clear = clear
131
132 // eslint-disable-next-line @typescript-eslint/ban-ts-comment
133 // @ts-ignore: reactotron-apis
134 swizzMultiSet = reactotron.asyncStorageHandler.multiSet
135 // eslint-disable-next-line @typescript-eslint/ban-ts-comment
136 // @ts-ignore: reactotron-apis
137 reactotron.asyncStorageHandler.multiSet = multiSet
138
139 // eslint-disable-next-line @typescript-eslint/ban-ts-comment
140 // @ts-ignore: reactotron-apis
141 swizzMultiRemove = reactotron.asyncStorageHandler.multiRemove
142 // eslint-disable-next-line @typescript-eslint/ban-ts-comment
143 // @ts-ignore: reactotron-apis
144 reactotron.asyncStorageHandler.multiRemove = multiRemove
145
146 // eslint-disable-next-line @typescript-eslint/ban-ts-comment
147 // @ts-ignore: reactotron-apis
148 swizzMultiMerge = reactotron.asyncStorageHandler.multiMerge
149 // eslint-disable-next-line @typescript-eslint/ban-ts-comment
150 // @ts-ignore: reactotron-apis
151 reactotron.asyncStorageHandler.multiMerge = multiMerge
152
153 isSwizzled = true
154 }
155
156 const untrackAsyncStorage = () => {
157 if (!isSwizzled) return
158
159 // eslint-disable-next-line @typescript-eslint/ban-ts-comment
160 // @ts-ignore: reactotron-apis
161 reactotron.asyncStorageHandler.setItem = swizzSetItem
162 // eslint-disable-next-line @typescript-eslint/ban-ts-comment
163 // @ts-ignore: reactotron-apis
164 reactotron.asyncStorageHandler.removeItem = swizzRemoveItem
165 // eslint-disable-next-line @typescript-eslint/ban-ts-comment
166 // @ts-ignore: reactotron-apis
167 reactotron.asyncStorageHandler.mergeItem = swizzMergeItem
168 // eslint-disable-next-line @typescript-eslint/ban-ts-comment
169 // @ts-ignore: reactotron-apis
170 reactotron.asyncStorageHandler.clear = swizzClear
171 // eslint-disable-next-line @typescript-eslint/ban-ts-comment
172 // @ts-ignore: reactotron-apis
173 reactotron.asyncStorageHandler.multiSet = swizzMultiSet
174 // eslint-disable-next-line @typescript-eslint/ban-ts-comment
175 // @ts-ignore: reactotron-apis
176 reactotron.asyncStorageHandler.multiRemove = swizzMultiRemove
177 // eslint-disable-next-line @typescript-eslint/ban-ts-comment
178 // @ts-ignore: reactotron-apis
179 reactotron.asyncStorageHandler.multiMerge = swizzMultiMerge
180
181 isSwizzled = false
182 }
183
184 // eslint-disable-next-line @typescript-eslint/ban-ts-comment
185 // @ts-ignore: reactotron-apis
186 if (reactotron.asyncStorageHandler) {
187 trackAsyncStorage()
188 }
189
190 return {
191 features: {
192 trackAsyncStorage,
193 untrackAsyncStorage,
194 },
195 } satisfies Plugin<ReactotronCore>
196}
197
198export default asyncStorage