@buoy-gg/storage 7.0.7 → 7.0.8

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 (42) hide show
  1. package/lib/typescript/storage/sync/storageSyncAdapter.d.ts +1 -1
  2. package/package.json +5 -5
  3. package/lib/commonjs/storage/components/GameUIStorageStats.js +0 -746
  4. package/lib/commonjs/storage/components/StorageActions.js +0 -178
  5. package/lib/commonjs/storage/components/StorageEventListener.js +0 -357
  6. package/lib/commonjs/storage/components/StorageFilterViewV2.js +0 -42
  7. package/lib/commonjs/storage/hooks/useMeasuredWidth.js +0 -74
  8. package/lib/commonjs/storage/hooks/useTickEverySecond.js +0 -21
  9. package/lib/commonjs/storage/index.js +0 -258
  10. package/lib/commonjs/storage/utils/index.js +0 -230
  11. package/lib/commonjs/storage/utils/objectDiff.js +0 -157
  12. package/lib/commonjs/storage/utils/safeAsyncStorage.js +0 -140
  13. package/lib/module/storage/components/GameUIStorageStats.js +0 -743
  14. package/lib/module/storage/components/StorageActions.js +0 -174
  15. package/lib/module/storage/components/StorageEventListener.js +0 -354
  16. package/lib/module/storage/components/StorageFilterViewV2.js +0 -38
  17. package/lib/module/storage/hooks/useMeasuredWidth.js +0 -71
  18. package/lib/module/storage/hooks/useTickEverySecond.js +0 -18
  19. package/lib/module/storage/index.js +0 -34
  20. package/lib/module/storage/utils/index.js +0 -28
  21. package/lib/module/storage/utils/objectDiff.js +0 -153
  22. package/lib/module/storage/utils/safeAsyncStorage.js +0 -134
  23. package/lib/typescript/storage/components/GameUIStorageStats.d.ts +0 -7
  24. package/lib/typescript/storage/components/GameUIStorageStats.d.ts.map +0 -1
  25. package/lib/typescript/storage/components/StorageActions.d.ts +0 -10
  26. package/lib/typescript/storage/components/StorageActions.d.ts.map +0 -1
  27. package/lib/typescript/storage/components/StorageEventListener.d.ts +0 -6
  28. package/lib/typescript/storage/components/StorageEventListener.d.ts.map +0 -1
  29. package/lib/typescript/storage/components/StorageFilterViewV2.d.ts +0 -9
  30. package/lib/typescript/storage/components/StorageFilterViewV2.d.ts.map +0 -1
  31. package/lib/typescript/storage/hooks/useMeasuredWidth.d.ts +0 -37
  32. package/lib/typescript/storage/hooks/useMeasuredWidth.d.ts.map +0 -1
  33. package/lib/typescript/storage/hooks/useTickEverySecond.d.ts +0 -6
  34. package/lib/typescript/storage/hooks/useTickEverySecond.d.ts.map +0 -1
  35. package/lib/typescript/storage/index.d.ts +0 -21
  36. package/lib/typescript/storage/index.d.ts.map +0 -1
  37. package/lib/typescript/storage/utils/index.d.ts +0 -10
  38. package/lib/typescript/storage/utils/index.d.ts.map +0 -1
  39. package/lib/typescript/storage/utils/objectDiff.d.ts +0 -35
  40. package/lib/typescript/storage/utils/objectDiff.d.ts.map +0 -1
  41. package/lib/typescript/storage/utils/safeAsyncStorage.d.ts +0 -56
  42. package/lib/typescript/storage/utils/safeAsyncStorage.d.ts.map +0 -1
@@ -1,178 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.StorageActions = StorageActions;
7
- var _reactNative = require("react-native");
8
- var _react = require("react");
9
- var _clearAllStorage = require("../utils/clearAllStorage");
10
- var _sharedUi = require("@buoy-gg/shared-ui");
11
- var _license = require("@buoy-gg/license");
12
- var _jsxRuntime = require("react/jsx-runtime");
13
- function StorageActions({
14
- storageKeys,
15
- onClearAll,
16
- onRefresh,
17
- totalCount
18
- }) {
19
- const [isRefreshing, setIsRefreshing] = (0, _react.useState)(false);
20
- const [showUpgradeModal, setShowUpgradeModal] = (0, _react.useState)(false);
21
- const isPro = (0, _license.useIsPro)();
22
-
23
- // Auto-close upgrade modal when user becomes Pro
24
- (0, _react.useEffect)(() => {
25
- if (showUpgradeModal && isPro) {
26
- setShowUpgradeModal(false);
27
- }
28
- }, [showUpgradeModal, isPro]);
29
- const handleRefresh = (0, _react.useCallback)(async () => {
30
- setIsRefreshing(true);
31
- try {
32
- await onRefresh();
33
- } finally {
34
- setTimeout(() => setIsRefreshing(false), 500);
35
- }
36
- }, [onRefresh]);
37
- const handleClear = () => {
38
- // Gate clear behind Pro
39
- if (!isPro) {
40
- setShowUpgradeModal(true);
41
- return;
42
- }
43
- _reactNative.Alert.alert("Clear Storage", "Choose what to clear:", [{
44
- text: "Cancel",
45
- style: "cancel"
46
- }, {
47
- text: "Clear App Data",
48
- onPress: handleClearAppData
49
- }, {
50
- text: "Clear Everything",
51
- style: "destructive",
52
- onPress: handleClearEverything
53
- }]);
54
- };
55
- const handleClearAppData = async () => {
56
- try {
57
- await onClearAll();
58
- await onRefresh(); // Auto-refresh after clearing
59
- } catch (error) {
60
- _reactNative.Alert.alert("Error", `Failed to clear storage: ${error}`);
61
- }
62
- };
63
- const handleClearEverything = async () => {
64
- // Clear everything directly without extra confirmation
65
- try {
66
- await (0, _clearAllStorage.clearAllStorageIncludingDevTools)();
67
- await onRefresh(); // Auto-refresh after clearing
68
-
69
- // Show success message briefly
70
- _reactNative.Alert.alert("Success", "All storage cleared including dev tools settings.", [{
71
- text: "OK"
72
- }], {
73
- cancelable: true
74
- });
75
- } catch (error) {
76
- _reactNative.Alert.alert("Error", `Failed to clear all storage: ${error}`);
77
- }
78
- };
79
- return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
80
- style: styles.headerContainer,
81
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
82
- style: styles.leftSection,
83
- children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Text, {
84
- style: styles.keyCount,
85
- children: [totalCount, " ", totalCount === 1 ? "key" : "keys", " found"]
86
- })
87
- }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
88
- style: styles.headerActions,
89
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
90
- "sentry-label": "ignore storage refresh button",
91
- onPress: handleRefresh,
92
- style: [styles.iconButton, isRefreshing && styles.activeButton],
93
- accessibilityLabel: "Refresh storage",
94
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.RefreshCw, {
95
- size: 16,
96
- color: isRefreshing ? "#10B981" : _sharedUi.buoyColors.textSecondary
97
- })
98
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.CopyButton, {
99
- value: storageKeys,
100
- size: 16,
101
- buttonStyle: styles.iconButton,
102
- colors: {
103
- idle: "#3B82F6",
104
- success: "#10B981",
105
- error: "#F87171"
106
- }
107
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
108
- "sentry-label": "ignore storage clear button",
109
- onPress: handleClear,
110
- style: styles.iconButton,
111
- accessibilityLabel: "Clear storage",
112
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.Trash2, {
113
- size: 16,
114
- color: "#F87171"
115
- })
116
- })]
117
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.ProUpgradeModal, {
118
- visible: showUpgradeModal,
119
- onClose: () => setShowUpgradeModal(false),
120
- featureName: "Storage Editing"
121
- })]
122
- });
123
- }
124
- const styles = _reactNative.StyleSheet.create({
125
- // Header styles matching Sentry pattern
126
- headerContainer: {
127
- flexDirection: "row",
128
- alignItems: "center",
129
- justifyContent: "space-between",
130
- paddingHorizontal: 12,
131
- paddingVertical: 8,
132
- backgroundColor: "rgba(128, 128, 128, 0.06)",
133
- borderRadius: 8,
134
- marginBottom: 12,
135
- borderWidth: 1,
136
- borderColor: "rgba(128, 128, 128, 0.16)"
137
- },
138
- leftSection: {
139
- flexDirection: "row",
140
- alignItems: "center",
141
- gap: 8
142
- },
143
- keyCount: {
144
- color: _sharedUi.buoyColors.textSecondary,
145
- fontSize: 12,
146
- fontWeight: "500"
147
- },
148
- copiedBadge: {
149
- backgroundColor: "#10B981",
150
- paddingHorizontal: 8,
151
- paddingVertical: 3,
152
- borderRadius: 10
153
- },
154
- copiedText: {
155
- color: "#FFFFFF",
156
- fontSize: 10,
157
- fontWeight: "600"
158
- },
159
- headerActions: {
160
- flexDirection: "row",
161
- alignItems: "center",
162
- gap: 8
163
- },
164
- iconButton: {
165
- width: 32,
166
- height: 32,
167
- borderRadius: 6,
168
- backgroundColor: "rgba(128, 128, 128, 0.06)",
169
- borderWidth: 1,
170
- borderColor: "rgba(128, 128, 128, 0.16)",
171
- alignItems: "center",
172
- justifyContent: "center"
173
- },
174
- activeButton: {
175
- backgroundColor: "rgba(16, 185, 129, 0.1)",
176
- borderColor: "rgba(16, 185, 129, 0.2)"
177
- }
178
- });
@@ -1,357 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.StorageEventListener = StorageEventListener;
7
- var _react = require("react");
8
- var _reactNative = require("react-native");
9
- var _sharedUi = require("@buoy-gg/shared-ui");
10
- var _AsyncStorageListener = require("../utils/AsyncStorageListener");
11
- var _storageActionHelpers = require("../utils/storageActionHelpers");
12
- var _mmkvAvailability = require("../utils/mmkvAvailability");
13
- var _jsxRuntime = require("react/jsx-runtime");
14
- // Conditionally import MMKV listener
15
- let addMMKVListener;
16
-
17
- // Define type for MMKV events (imported conditionally at runtime)
18
-
19
- if ((0, _mmkvAvailability.isMMKVAvailable)()) {
20
- const mmkvListener = require("../utils/MMKVListener");
21
- addMMKVListener = mmkvListener.addMMKVListener;
22
- }
23
-
24
- // Unified event type that covers both AsyncStorage and MMKV
25
-
26
- /**
27
- * Storage event listener component for monitoring AsyncStorage and MMKV operations
28
- * Follows the Sentry component pattern for consistency
29
- */
30
- function StorageEventListener() {
31
- const [events, setEvents] = (0, _react.useState)([]);
32
- const [isListening, setIsListening] = (0, _react.useState)(false);
33
- const [isAsyncStorageAvailable, setIsAsyncStorageAvailable] = (0, _react.useState)(false);
34
- (0, _react.useEffect)(() => {
35
- // Component mounted, AsyncStorage is available
36
- setIsAsyncStorageAvailable(true);
37
-
38
- // Add listener for AsyncStorage events
39
- const unsubscribeAsync = (0, _AsyncStorageListener.addListener)(event => {
40
- setEvents(prev => {
41
- const newEvents = [{
42
- ...event,
43
- storageType: 'async'
44
- }, ...prev.slice(0, 99)];
45
- return newEvents;
46
- });
47
- });
48
-
49
- // Add listener for MMKV events (only if available)
50
- let unsubscribeMMKV = () => {};
51
- if ((0, _mmkvAvailability.isMMKVAvailable)() && addMMKVListener) {
52
- unsubscribeMMKV = addMMKVListener(event => {
53
- setEvents(prev => {
54
- const newEvents = [{
55
- ...event,
56
- storageType: 'mmkv'
57
- }, ...prev.slice(0, 99)];
58
- return newEvents;
59
- });
60
- });
61
- }
62
-
63
- // Check initial listening state
64
- const initialState = (0, _AsyncStorageListener.isListening)();
65
- setIsListening(initialState);
66
- return () => {
67
- if ((0, _AsyncStorageListener.isListening)()) {
68
- (0, _AsyncStorageListener.stopListening)();
69
- }
70
- unsubscribeAsync();
71
- unsubscribeMMKV();
72
- };
73
- }, []);
74
- const handleToggleListening = (0, _react.useCallback)(async () => {
75
- if (!isAsyncStorageAvailable) {
76
- return;
77
- }
78
- if (isListening) {
79
- // Stopping listener
80
- (0, _AsyncStorageListener.stopListening)();
81
- setIsListening(false);
82
- } else {
83
- // Starting listener
84
- await (0, _AsyncStorageListener.startListening)();
85
- setIsListening(true);
86
- }
87
- }, [isListening, isAsyncStorageAvailable]);
88
- const handleClearEvents = (0, _react.useCallback)(() => {
89
- // Clearing all events
90
- setEvents([]);
91
- }, []);
92
- const formatEventData = event => {
93
- if (!event.data) return "";
94
-
95
- // MMKV events
96
- if (event.storageType === 'mmkv') {
97
- const mmkvEvent = event;
98
-
99
- // Show instance ID for MMKV events
100
- const instancePrefix = `[${mmkvEvent.instanceId}] `;
101
- if (mmkvEvent.action.startsWith('set.') || mmkvEvent.action.startsWith('get.') || mmkvEvent.action === 'delete') {
102
- const keyInfo = mmkvEvent.data?.key ? `${mmkvEvent.data.key}` : "";
103
- const typeInfo = mmkvEvent.data?.valueType ? ` (${mmkvEvent.data.valueType})` : "";
104
- return instancePrefix + keyInfo + typeInfo;
105
- }
106
- if (mmkvEvent.action === 'clearAll') {
107
- return instancePrefix + "All keys";
108
- }
109
- return instancePrefix;
110
- }
111
-
112
- // AsyncStorage events
113
- if (event.action === "setItem" || event.action === "removeItem" || event.action === "mergeItem") {
114
- return event.data.key || "";
115
- }
116
- if (event.action === "multiSet" || event.action === "multiMerge") {
117
- return `${event.data.pairs?.length || 0} pairs`;
118
- }
119
- if (event.action === "multiRemove") {
120
- return `${event.data.keys?.length || 0} keys`;
121
- }
122
- if (event.action === "clear") {
123
- return "All storage";
124
- }
125
- return "";
126
- };
127
- const getActionColor = action => {
128
- // MMKV actions
129
- if (action.startsWith('set.')) {
130
- return "#10B981"; // Green for writes
131
- }
132
- if (action.startsWith('get.')) {
133
- return "#F59E0B"; // Orange for reads
134
- }
135
- if (action === 'delete' || action === 'clearAll') {
136
- return "#EF4444"; // Red for deletes
137
- }
138
-
139
- // AsyncStorage actions
140
- switch (action) {
141
- case "setItem":
142
- case "multiSet":
143
- return "#10B981";
144
- // Green for write
145
- case "removeItem":
146
- case "multiRemove":
147
- case "clear":
148
- return "#EF4444";
149
- // Red for delete
150
- case "mergeItem":
151
- case "multiMerge":
152
- return "#3B82F6";
153
- // Blue for merge
154
- default:
155
- return _sharedUi.macOSColors.text.icon;
156
- }
157
- };
158
- if (!isAsyncStorageAvailable) {
159
- return null; // Don't show component if AsyncStorage isn't available
160
- }
161
- return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
162
- style: styles.container,
163
- children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
164
- style: styles.header,
165
- children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
166
- style: styles.headerLeft,
167
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
168
- style: styles.title,
169
- children: "Storage Events"
170
- }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
171
- style: styles.statsContainer,
172
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
173
- style: styles.statsText,
174
- children: events.length
175
- }), isListening && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
176
- style: styles.listeningIndicator
177
- })]
178
- })]
179
- }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
180
- style: styles.headerActions,
181
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
182
- "sentry-label": "ignore toggle listening",
183
- onPress: handleToggleListening,
184
- style: [styles.actionButton, isListening ? styles.stopButton : styles.startButton],
185
- accessibilityLabel: isListening ? "Stop listening" : "Start listening",
186
- children: isListening ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.Pause, {
187
- size: 14,
188
- color: "#EF4444"
189
- }) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.Play, {
190
- size: 14,
191
- color: "#10B981"
192
- })
193
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
194
- "sentry-label": "ignore clear events",
195
- onPress: handleClearEvents,
196
- style: styles.actionButton,
197
- accessibilityLabel: "Clear events",
198
- disabled: events.length === 0,
199
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.Trash2, {
200
- size: 14,
201
- color: events.length > 0 ? _sharedUi.macOSColors.text.icon : _sharedUi.macOSColors.border.toggle
202
- })
203
- })]
204
- })]
205
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.ScrollView, {
206
- style: styles.eventsList,
207
- nestedScrollEnabled: true,
208
- showsVerticalScrollIndicator: false,
209
- "sentry-label": "ignore event list scroll",
210
- children: events.length === 0 ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
211
- style: styles.emptyState,
212
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
213
- style: styles.emptyText,
214
- children: isListening ? "Waiting for storage operations..." : "Start listening to capture events"
215
- })
216
- }) : events.map((event, index) => /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
217
- style: styles.eventItem,
218
- children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
219
- style: styles.eventLeft,
220
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
221
- style: [styles.eventAction, {
222
- color: getActionColor(event.action)
223
- }],
224
- children: (0, _storageActionHelpers.translateStorageAction)(event.action)
225
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
226
- style: styles.eventData,
227
- numberOfLines: 1,
228
- children: formatEventData(event)
229
- })]
230
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
231
- style: styles.eventTime,
232
- children: event.timestamp.toLocaleTimeString([], {
233
- hour: "2-digit",
234
- minute: "2-digit",
235
- second: "2-digit"
236
- })
237
- })]
238
- }, `${event.timestamp.getTime()}-${index}`))
239
- })]
240
- });
241
- }
242
- const styles = _reactNative.StyleSheet.create({
243
- container: {
244
- backgroundColor: "rgba(128, 128, 128, 0.06)",
245
- borderRadius: 8,
246
- borderWidth: 1,
247
- borderColor: "rgba(128, 128, 128, 0.16)",
248
- marginBottom: 12,
249
- maxHeight: 200
250
- },
251
- header: {
252
- flexDirection: "row",
253
- alignItems: "center",
254
- justifyContent: "space-between",
255
- paddingHorizontal: 12,
256
- paddingVertical: 8,
257
- borderBottomWidth: 1,
258
- borderBottomColor: "rgba(128, 128, 128, 0.12)"
259
- },
260
- headerLeft: {
261
- flexDirection: "row",
262
- alignItems: "center",
263
- gap: 8
264
- },
265
- title: {
266
- fontSize: 12,
267
- fontWeight: "500",
268
- color: _sharedUi.buoyColors.textSecondary,
269
- textTransform: "uppercase",
270
- letterSpacing: 0.5
271
- },
272
- statsContainer: {
273
- flexDirection: "row",
274
- alignItems: "center",
275
- gap: 6,
276
- backgroundColor: "rgba(0, 0, 0, 0.2)",
277
- paddingHorizontal: 8,
278
- paddingVertical: 2,
279
- borderRadius: 10
280
- },
281
- statsText: {
282
- fontSize: 11,
283
- color: _sharedUi.macOSColors.text.icon,
284
- fontWeight: "500"
285
- },
286
- listeningIndicator: {
287
- width: 6,
288
- height: 6,
289
- borderRadius: 3,
290
- backgroundColor: "#10B981"
291
- },
292
- headerActions: {
293
- flexDirection: "row",
294
- alignItems: "center",
295
- gap: 6
296
- },
297
- actionButton: {
298
- width: 28,
299
- height: 28,
300
- borderRadius: 6,
301
- backgroundColor: "rgba(128, 128, 128, 0.06)",
302
- borderWidth: 1,
303
- borderColor: "rgba(128, 128, 128, 0.16)",
304
- alignItems: "center",
305
- justifyContent: "center"
306
- },
307
- startButton: {
308
- backgroundColor: "rgba(16, 185, 129, 0.1)",
309
- borderColor: "rgba(16, 185, 129, 0.2)"
310
- },
311
- stopButton: {
312
- backgroundColor: "rgba(239, 68, 68, 0.1)",
313
- borderColor: "rgba(239, 68, 68, 0.2)"
314
- },
315
- eventsList: {
316
- maxHeight: 150
317
- },
318
- emptyState: {
319
- padding: 20,
320
- alignItems: "center"
321
- },
322
- emptyText: {
323
- fontSize: 11,
324
- color: _sharedUi.macOSColors.text.icon,
325
- fontStyle: "italic"
326
- },
327
- eventItem: {
328
- flexDirection: "row",
329
- alignItems: "center",
330
- justifyContent: "space-between",
331
- paddingHorizontal: 12,
332
- paddingVertical: 6,
333
- borderBottomWidth: 1,
334
- borderBottomColor: "rgba(128, 128, 128, 0.06)"
335
- },
336
- eventLeft: {
337
- flex: 1,
338
- flexDirection: "row",
339
- alignItems: "center",
340
- gap: 8,
341
- marginRight: 8
342
- },
343
- eventAction: {
344
- fontSize: 11,
345
- fontWeight: "600",
346
- minWidth: 60
347
- },
348
- eventData: {
349
- fontSize: 11,
350
- color: _sharedUi.buoyColors.textSecondary,
351
- flex: 1
352
- },
353
- eventTime: {
354
- fontSize: 10,
355
- color: _sharedUi.macOSColors.text.icon
356
- }
357
- });
@@ -1,42 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.StorageFilterViewV2 = StorageFilterViewV2;
7
- var _sharedUi = require("@buoy-gg/shared-ui");
8
- var _jsxRuntime = require("react/jsx-runtime");
9
- function StorageFilterViewV2({
10
- ignoredPatterns,
11
- onTogglePattern,
12
- onAddPattern,
13
- availableKeys = []
14
- }) {
15
- const filterConfig = {
16
- addFilterSection: {
17
- enabled: true,
18
- placeholder: "Enter key pattern to hide...",
19
- title: "ACTIVE FILTERS",
20
- icon: _sharedUi.Filter
21
- },
22
- availableItemsSection: {
23
- enabled: true,
24
- title: "AVAILABLE STORAGE KEYS",
25
- emptyMessage: "No storage keys available. Keys will appear here once loaded.",
26
- items: availableKeys
27
- },
28
- howItWorksSection: {
29
- enabled: true,
30
- title: "HOW STORAGE FILTERS WORK",
31
- description: "Patterns hide matching storage keys from the list. Filters match if the storage key contains the provided text.",
32
- examples: ["• react_buoy → hides keys containing react_buoy", "• @temp → hides @temp_user, @temp_data", "• redux → hides redux-persist:root", "• : → hides all keys with colons"],
33
- icon: _sharedUi.Filter
34
- },
35
- onPatternToggle: onTogglePattern,
36
- onPatternAdd: onAddPattern,
37
- activePatterns: ignoredPatterns
38
- };
39
- return /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.DynamicFilterView, {
40
- ...filterConfig
41
- });
42
- }
@@ -1,74 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.useMeasuredWidth = useMeasuredWidth;
7
- var _react = require("react");
8
- /**
9
- * Measure a container's width, for the layouts that switch between a card list
10
- * and a wide table.
11
- *
12
- * Three things went wrong before this landed on a callback ref; all three are
13
- * worth knowing, because the same trap is waiting in any other tool that wants
14
- * a width-driven layout.
15
- *
16
- * 1. `onLayout` ALONE IS NOT ENOUGH. On react-native-web it never delivered its
17
- * first callback for these subtrees. The node carries RNW's
18
- * `__reactLayoutHandler`, and a ResizeObserver attached by hand fires on that
19
- * very same node — so the handler is wired and the observer works; RNW's
20
- * shared observer just never calls it. `width` stayed 0 and the table never
21
- * appeared, silently. `onLayout` is still wired here because it works on
22
- * native.
23
- *
24
- * 2. RE-MEASURING EVERY RENDER DEADLOCKS THE RENDERER. Filtering a list changes
25
- * whether its scrollbar is present, which changes the container width, which
26
- * re-renders, which re-measures — with no fixed point. An observer only fires
27
- * when the size genuinely changes, so layout settles.
28
- *
29
- * 3. A MOUNT-ONLY EFFECT MISSES THE NODE. These components early-return a
30
- * loading state before the measured container exists, so `ref.current` is
31
- * null when a `useEffect(…, [])` runs, and it never runs again. A callback
32
- * ref fires whenever the node actually attaches — including the second time.
33
- */
34
-
35
- /** The bits of a DOM node we need. This package has no `dom` lib. */
36
-
37
- function getResizeObserver() {
38
- return globalThis.ResizeObserver;
39
- }
40
- function isMeasurable(node) {
41
- return typeof node?.getBoundingClientRect === "function";
42
- }
43
- function useMeasuredWidth() {
44
- const [width, setWidth] = (0, _react.useState)(0);
45
- const observerRef = (0, _react.useRef)(null);
46
-
47
- // A sub-pixel wobble is not a layout change; anything larger is.
48
- const apply = (0, _react.useCallback)(measured => {
49
- setWidth(prev => Math.abs(prev - measured) > 1 ? measured : prev);
50
- }, []);
51
- const ref = (0, _react.useCallback)(node => {
52
- observerRef.current?.disconnect();
53
- observerRef.current = null;
54
-
55
- // Detach (node === null) or a platform without DOM measurement: leave the
56
- // last width in place so a remount doesn't flash the wrong layout.
57
- if (!isMeasurable(node)) return;
58
- apply(node.getBoundingClientRect().width);
59
- const Observer = getResizeObserver();
60
- if (!Observer) return;
61
- const observer = new Observer(entries => {
62
- const measured = entries[0]?.contentRect?.width;
63
- if (typeof measured === "number") apply(measured);
64
- });
65
- observer.observe(node);
66
- observerRef.current = observer;
67
- }, [apply]);
68
- const onLayout = (0, _react.useCallback)(event => apply(event.nativeEvent.layout.width), [apply]);
69
- return {
70
- ref,
71
- width,
72
- onLayout
73
- };
74
- }
@@ -1,21 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.useTickEverySecond = useTickEverySecond;
7
- var _react = require("react");
8
- /**
9
- * Hook that forces a re-render every second
10
- * Used to update relative timestamps (e.g., "2s ago", "1m ago")
11
- */
12
- function useTickEverySecond(enabled = true) {
13
- const [, setTick] = (0, _react.useState)(0);
14
- (0, _react.useEffect)(() => {
15
- if (!enabled) return;
16
- const interval = setInterval(() => {
17
- setTick(prev => prev + 1);
18
- }, 1000);
19
- return () => clearInterval(interval);
20
- }, [enabled]);
21
- }