@buoy-gg/storage 7.0.7 → 7.0.9
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.
- package/lib/typescript/storage/sync/storageSyncAdapter.d.ts +1 -1
- package/package.json +5 -5
- package/lib/commonjs/storage/components/GameUIStorageStats.js +0 -746
- package/lib/commonjs/storage/components/StorageActions.js +0 -178
- package/lib/commonjs/storage/components/StorageEventListener.js +0 -357
- package/lib/commonjs/storage/components/StorageFilterViewV2.js +0 -42
- package/lib/commonjs/storage/hooks/useMeasuredWidth.js +0 -74
- package/lib/commonjs/storage/hooks/useTickEverySecond.js +0 -21
- package/lib/commonjs/storage/index.js +0 -258
- package/lib/commonjs/storage/utils/index.js +0 -230
- package/lib/commonjs/storage/utils/objectDiff.js +0 -157
- package/lib/commonjs/storage/utils/safeAsyncStorage.js +0 -140
- package/lib/module/storage/components/GameUIStorageStats.js +0 -743
- package/lib/module/storage/components/StorageActions.js +0 -174
- package/lib/module/storage/components/StorageEventListener.js +0 -354
- package/lib/module/storage/components/StorageFilterViewV2.js +0 -38
- package/lib/module/storage/hooks/useMeasuredWidth.js +0 -71
- package/lib/module/storage/hooks/useTickEverySecond.js +0 -18
- package/lib/module/storage/index.js +0 -34
- package/lib/module/storage/utils/index.js +0 -28
- package/lib/module/storage/utils/objectDiff.js +0 -153
- package/lib/module/storage/utils/safeAsyncStorage.js +0 -134
- package/lib/typescript/storage/components/GameUIStorageStats.d.ts +0 -7
- package/lib/typescript/storage/components/GameUIStorageStats.d.ts.map +0 -1
- package/lib/typescript/storage/components/StorageActions.d.ts +0 -10
- package/lib/typescript/storage/components/StorageActions.d.ts.map +0 -1
- package/lib/typescript/storage/components/StorageEventListener.d.ts +0 -6
- package/lib/typescript/storage/components/StorageEventListener.d.ts.map +0 -1
- package/lib/typescript/storage/components/StorageFilterViewV2.d.ts +0 -9
- package/lib/typescript/storage/components/StorageFilterViewV2.d.ts.map +0 -1
- package/lib/typescript/storage/hooks/useMeasuredWidth.d.ts +0 -37
- package/lib/typescript/storage/hooks/useMeasuredWidth.d.ts.map +0 -1
- package/lib/typescript/storage/hooks/useTickEverySecond.d.ts +0 -6
- package/lib/typescript/storage/hooks/useTickEverySecond.d.ts.map +0 -1
- package/lib/typescript/storage/index.d.ts +0 -21
- package/lib/typescript/storage/index.d.ts.map +0 -1
- package/lib/typescript/storage/utils/index.d.ts +0 -10
- package/lib/typescript/storage/utils/index.d.ts.map +0 -1
- package/lib/typescript/storage/utils/objectDiff.d.ts +0 -35
- package/lib/typescript/storage/utils/objectDiff.d.ts.map +0 -1
- package/lib/typescript/storage/utils/safeAsyncStorage.d.ts +0 -56
- 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
|
-
}
|