@buoy-gg/react-query 1.7.7 → 2.1.1

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/commonjs/index.js +619 -24
  2. package/lib/commonjs/preset.js +1 -1
  3. package/lib/commonjs/react-query/components/ReactQueryDevToolsModal.js +12 -0
  4. package/lib/commonjs/react-query/components/modals/MutationBrowserModal.js +10 -1
  5. package/lib/commonjs/react-query/components/modals/QueryBrowserModal.js +17 -15
  6. package/lib/commonjs/react-query/components/modals/ReactQueryModalHeader.js +14 -1
  7. package/lib/commonjs/react-query/hooks/useAllMutations.js +65 -15
  8. package/lib/commonjs/react-query/hooks/useWifiState.js +3 -3
  9. package/lib/commonjs/react-query/index.js +11 -0
  10. package/lib/commonjs/react-query/stores/index.js +48 -0
  11. package/lib/commonjs/react-query/stores/reactQueryEventStore.js +311 -0
  12. package/lib/commonjs/react-query/utils/modalStorageOperations.js +2 -2
  13. package/lib/module/index.js +113 -8
  14. package/lib/module/preset.js +2 -2
  15. package/lib/module/react-query/components/ReactQueryDevToolsModal.js +13 -1
  16. package/lib/module/react-query/components/modals/MutationBrowserModal.js +10 -1
  17. package/lib/module/react-query/components/modals/QueryBrowserModal.js +18 -16
  18. package/lib/module/react-query/components/modals/ReactQueryModalHeader.js +15 -2
  19. package/lib/module/react-query/hooks/useAllMutations.js +66 -16
  20. package/lib/module/react-query/hooks/useWifiState.js +4 -4
  21. package/lib/module/react-query/index.js +2 -1
  22. package/lib/module/react-query/stores/index.js +3 -0
  23. package/lib/module/react-query/stores/reactQueryEventStore.js +302 -0
  24. package/lib/module/react-query/utils/modalStorageOperations.js +3 -3
  25. package/lib/typescript/index.d.ts +61 -5
  26. package/lib/typescript/index.d.ts.map +1 -1
  27. package/lib/typescript/react-query/components/ReactQueryDevToolsModal.d.ts.map +1 -1
  28. package/lib/typescript/react-query/components/modals/MutationBrowserModal.d.ts.map +1 -1
  29. package/lib/typescript/react-query/components/modals/QueryBrowserModal.d.ts.map +1 -1
  30. package/lib/typescript/react-query/components/modals/ReactQueryModalHeader.d.ts +2 -1
  31. package/lib/typescript/react-query/components/modals/ReactQueryModalHeader.d.ts.map +1 -1
  32. package/lib/typescript/react-query/hooks/useAllMutations.d.ts +2 -2
  33. package/lib/typescript/react-query/hooks/useAllMutations.d.ts.map +1 -1
  34. package/lib/typescript/react-query/hooks/useWifiState.d.ts +1 -1
  35. package/lib/typescript/react-query/hooks/useWifiState.d.ts.map +1 -1
  36. package/lib/typescript/react-query/index.d.ts +1 -0
  37. package/lib/typescript/react-query/index.d.ts.map +1 -1
  38. package/lib/typescript/react-query/stores/index.d.ts +2 -0
  39. package/lib/typescript/react-query/stores/index.d.ts.map +1 -0
  40. package/lib/typescript/react-query/stores/reactQueryEventStore.d.ts +99 -0
  41. package/lib/typescript/react-query/stores/reactQueryEventStore.d.ts.map +1 -0
  42. package/package.json +17 -3
@@ -35,7 +35,7 @@ const EmptyComponent = () => null;
35
35
  // Save WiFi state to storage
36
36
  const saveWifiState = async enabled => {
37
37
  try {
38
- await (0, _sharedUi.safeSetItem)(_sharedUi.devToolsStorageKeys.settings.wifiEnabled(), enabled.toString());
38
+ await _sharedUi.persistentStorage.setItem(_sharedUi.devToolsStorageKeys.settings.wifiEnabled(), enabled.toString());
39
39
  } catch (error) {
40
40
  // Failed to save WiFi state
41
41
  }
@@ -5,7 +5,9 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.ReactQueryDevToolsModal = ReactQueryDevToolsModal;
7
7
  var _react = require("react");
8
+ var _reactQuery = require("@tanstack/react-query");
8
9
  var _ReactQueryModal = require("./modals/ReactQueryModal");
10
+ var _reactQueryEventStore = require("../stores/reactQueryEventStore");
9
11
  var _jsxRuntime = require("react/jsx-runtime");
10
12
  /** Configuration options for the high-level React Query dev tools modal wrapper. */
11
13
 
@@ -19,6 +21,16 @@ function ReactQueryDevToolsModal({
19
21
  onMinimize,
20
22
  enableSharedModalDimensions = true
21
23
  }) {
24
+ // Get QueryClient and connect to event store for unified Events DevTools
25
+ const queryClient = (0, _reactQuery.useQueryClient)();
26
+ (0, _react.useEffect)(() => {
27
+ // Connect the QueryClient to the event store so events flow to unified Events DevTools
28
+ // Only connect if not already connected (to preserve connection across modal open/close)
29
+ if (!_reactQueryEventStore.reactQueryEventStore.isConnected()) {
30
+ _reactQueryEventStore.reactQueryEventStore.setQueryClient(queryClient);
31
+ }
32
+ // Don't disconnect on unmount - keep the connection for unified Events DevTools
33
+ }, [queryClient]);
22
34
  const [selectedQueryKey, setSelectedQueryKey] = (0, _react.useState)(undefined);
23
35
  const [selectedMutationId, setSelectedMutationId] = (0, _react.useState)(undefined);
24
36
  const [activeFilter, setActiveFilter] = (0, _react.useState)(null);
@@ -4,6 +4,7 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.MutationBrowserModal = MutationBrowserModal;
7
+ var _reactQuery = require("@tanstack/react-query");
7
8
  var _react = require("react");
8
9
  var _useSelectedMutation = require("../../hooks/useSelectedMutation");
9
10
  var _MutationBrowserMode = require("../MutationBrowserMode");
@@ -30,11 +31,18 @@ function MutationBrowserModal({
30
31
  searchText = "",
31
32
  onSearchChange
32
33
  }) {
34
+ const queryClient = (0, _reactQuery.useQueryClient)();
33
35
  const selectedMutation = (0, _useSelectedMutation.useGetMutationById)(selectedMutationId);
34
36
  const [internalActiveFilter, setInternalActiveFilter] = (0, _react.useState)(null);
35
37
  const activeFilter = externalActiveFilter ?? internalActiveFilter;
36
38
  const setActiveFilter = externalOnFilterChange ?? setInternalActiveFilter;
37
39
 
40
+ // Clear mutation cache handler
41
+ const handleClearCache = (0, _react.useCallback)(() => {
42
+ queryClient.getMutationCache().clear();
43
+ onMutationSelect(undefined);
44
+ }, [queryClient, onMutationSelect]);
45
+
38
46
  // Track modal mode for conditional styling
39
47
  // Initialize with bottomSheet but it will be updated from persisted state if available
40
48
  const [modalMode, setModalMode] = (0, _react.useState)("bottomSheet");
@@ -98,7 +106,8 @@ function MutationBrowserModal({
98
106
  onTabChange: onTabChange,
99
107
  onBack: () => onMutationSelect(undefined),
100
108
  searchText: searchText,
101
- onSearchChange: onSearchChange
109
+ onSearchChange: onSearchChange,
110
+ onClearCache: handleClearCache
102
111
  });
103
112
  const footerNode = /*#__PURE__*/(0, _jsxRuntime.jsx)(_MutationBrowserFooter.MutationBrowserFooter, {
104
113
  activeFilter: activeFilter,
@@ -4,6 +4,7 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.QueryBrowserModal = QueryBrowserModal;
7
+ var _reactQuery = require("@tanstack/react-query");
7
8
  var _sharedUi = require("@buoy-gg/shared-ui");
8
9
  var _useSelectedQuery = require("../../hooks/useSelectedQuery");
9
10
  var _ReactQueryModalHeader = require("./ReactQueryModalHeader");
@@ -32,9 +33,15 @@ function QueryBrowserModal({
32
33
  searchText = "",
33
34
  onSearchChange
34
35
  }) {
36
+ const queryClient = (0, _reactQuery.useQueryClient)();
35
37
  const selectedQuery = (0, _useSelectedQuery.useGetQueryByQueryKey)(selectedQueryKey);
36
38
  const allQueries = (0, _useAllQueries.default)();
37
39
 
40
+ // Clear query cache handler
41
+ const handleClearCache = (0, _react.useCallback)(() => {
42
+ queryClient.getQueryCache().clear();
43
+ }, [queryClient]);
44
+
38
45
  // Use external filter state if provided (for persistence), otherwise use internal state
39
46
  const [internalActiveFilter, setInternalActiveFilter] = (0, _react.useState)(null);
40
47
  const activeFilter = externalActiveFilter ?? internalActiveFilter;
@@ -45,17 +52,11 @@ function QueryBrowserModal({
45
52
  const [ignoredPatterns, setIgnoredPatterns] = (0, _react.useState)(new Set());
46
53
  const [includedPatterns, setIncludedPatterns] = (0, _react.useState)(new Set());
47
54
 
48
- // AsyncStorage for persisting ignored patterns
49
- const {
50
- getItem: safeGetItem,
51
- setItem: safeSetItem
52
- } = (0, _sharedUi.useSafeAsyncStorage)();
53
-
54
55
  // Load ignored patterns from storage on mount
55
56
  (0, _react.useEffect)(() => {
56
57
  const loadFilters = async () => {
57
58
  try {
58
- const stored = await safeGetItem(_sharedUi.devToolsStorageKeys.reactQuery.ignoredPatterns());
59
+ const stored = await _sharedUi.persistentStorage.getItem(_sharedUi.devToolsStorageKeys.reactQuery.ignoredPatterns());
59
60
  if (stored) {
60
61
  const patterns = JSON.parse(stored);
61
62
  if (Array.isArray(patterns)) {
@@ -67,13 +68,13 @@ function QueryBrowserModal({
67
68
  }
68
69
  };
69
70
  loadFilters();
70
- }, [safeGetItem]);
71
+ }, []);
71
72
 
72
73
  // Load included patterns from storage on mount
73
74
  (0, _react.useEffect)(() => {
74
75
  const loadFilters = async () => {
75
76
  try {
76
- const stored = await safeGetItem(_sharedUi.devToolsStorageKeys.reactQuery.includedPatterns());
77
+ const stored = await _sharedUi.persistentStorage.getItem(_sharedUi.devToolsStorageKeys.reactQuery.includedPatterns());
77
78
  if (stored) {
78
79
  const patterns = JSON.parse(stored);
79
80
  if (Array.isArray(patterns)) {
@@ -85,33 +86,33 @@ function QueryBrowserModal({
85
86
  }
86
87
  };
87
88
  loadFilters();
88
- }, [safeGetItem]);
89
+ }, []);
89
90
 
90
91
  // Save ignored patterns to storage when they change
91
92
  (0, _react.useEffect)(() => {
92
93
  const saveFilters = async () => {
93
94
  try {
94
95
  const patterns = Array.from(ignoredPatterns);
95
- await safeSetItem(_sharedUi.devToolsStorageKeys.reactQuery.ignoredPatterns(), JSON.stringify(patterns));
96
+ await _sharedUi.persistentStorage.setItem(_sharedUi.devToolsStorageKeys.reactQuery.ignoredPatterns(), JSON.stringify(patterns));
96
97
  } catch (error) {
97
98
  console.error("Failed to save ignored patterns:", error);
98
99
  }
99
100
  };
100
101
  saveFilters();
101
- }, [ignoredPatterns, safeSetItem]);
102
+ }, [ignoredPatterns]);
102
103
 
103
104
  // Save included patterns to storage when they change
104
105
  (0, _react.useEffect)(() => {
105
106
  const saveFilters = async () => {
106
107
  try {
107
108
  const patterns = Array.from(includedPatterns);
108
- await safeSetItem(_sharedUi.devToolsStorageKeys.reactQuery.includedPatterns(), JSON.stringify(patterns));
109
+ await _sharedUi.persistentStorage.setItem(_sharedUi.devToolsStorageKeys.reactQuery.includedPatterns(), JSON.stringify(patterns));
109
110
  } catch (error) {
110
111
  console.error("Failed to save included patterns:", error);
111
112
  }
112
113
  };
113
114
  saveFilters();
114
- }, [includedPatterns, safeSetItem]);
115
+ }, [includedPatterns]);
115
116
 
116
117
  // Toggle pattern in ignored set
117
118
  const handlePatternToggle = (0, _react.useCallback)(pattern => {
@@ -177,7 +178,8 @@ function QueryBrowserModal({
177
178
  searchText: searchText,
178
179
  onSearchChange: onSearchChange,
179
180
  onFilterPress: () => setShowFilterView(true),
180
- hasActiveFilters: activeFilter !== null || ignoredPatterns.size > 0 || includedPatterns.size > 0
181
+ hasActiveFilters: activeFilter !== null || ignoredPatterns.size > 0 || includedPatterns.size > 0,
182
+ onClearCache: handleClearCache
181
183
  });
182
184
  };
183
185
  const footerNode = /*#__PURE__*/(0, _jsxRuntime.jsx)(_QueryBrowserFooter.QueryBrowserFooter, {
@@ -21,7 +21,8 @@ function ReactQueryModalHeader({
21
21
  searchText = "",
22
22
  onSearchChange,
23
23
  onFilterPress,
24
- hasActiveFilters = false
24
+ hasActiveFilters = false,
25
+ onClearCache
25
26
  }) {
26
27
  const [isSearchActive, setIsSearchActive] = (0, _react.useState)(false);
27
28
  const searchInputRef = (0, _react.useRef)(null);
@@ -133,6 +134,15 @@ function ReactQueryModalHeader({
133
134
  size: 14,
134
135
  color: hasActiveFilters ? _sharedUi.buoyColors.primary : _sharedUi.buoyColors.textSecondary
135
136
  })
137
+ }), onClearCache && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
138
+ "sentry-label": "ignore clear cache",
139
+ onPress: onClearCache,
140
+ style: [styles.headerActionButton, styles.clearCacheButton],
141
+ accessibilityLabel: `Clear ${activeTab} cache`,
142
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.Trash, {
143
+ size: 14,
144
+ color: _sharedUi.buoyColors.warning
145
+ })
136
146
  })]
137
147
  })]
138
148
  });
@@ -167,5 +177,8 @@ const styles = _reactNative.StyleSheet.create({
167
177
  },
168
178
  activeFilterButton: {
169
179
  backgroundColor: _sharedUi.buoyColors.primary + "33"
180
+ },
181
+ clearCacheButton: {
182
+ backgroundColor: _sharedUi.buoyColors.warning + "20"
170
183
  }
171
184
  });
@@ -7,27 +7,77 @@ exports.default = void 0;
7
7
  var _react = require("react");
8
8
  var _reactQuery = require("@tanstack/react-query");
9
9
  /**
10
- * Tracks all active React Query mutations with lightweight change detection. Debounces cache
11
- * updates so large mutation batches do not thrash the UI thread on mobile.
10
+ * Tracks all active React Query mutations with lightweight change detection.
11
+ * Mirrors the pattern used in useAllQueries for consistency.
12
12
  */
13
13
  function useAllMutations() {
14
14
  const queryClient = (0, _reactQuery.useQueryClient)();
15
- const [mutations, setMutations] = (0, _react.useState)([]);
16
- const mutationsSnapshotRef = (0, _react.useRef)(null);
15
+ const [mutations, setMutations] = (0, _react.useState)(() => {
16
+ // Initialize with current mutations to avoid flash
17
+ return queryClient.getMutationCache().getAll();
18
+ });
19
+
20
+ // Track mutation states using a Map for O(1) lookups
21
+ const mutationStatesRef = (0, _react.useRef)(new Map());
22
+ const updateTimerRef = (0, _react.useRef)(undefined);
23
+
24
+ // Check if mutations have changed
25
+ const hasMutationsChanged = (0, _react.useCallback)(newMutations => {
26
+ const statesMap = mutationStatesRef.current;
27
+
28
+ // Quick length check first
29
+ if (newMutations.length !== statesMap.size) {
30
+ return true;
31
+ }
32
+
33
+ // Check if any mutation state has changed
34
+ for (const mutation of newMutations) {
35
+ const prevState = statesMap.get(mutation.mutationId);
36
+ if (!prevState) return true;
37
+ if (prevState.status !== mutation.state.status || prevState.submittedAt !== mutation.state.submittedAt || prevState.isPaused !== mutation.state.isPaused) {
38
+ return true;
39
+ }
40
+ }
41
+ return false;
42
+ }, []);
43
+
44
+ // Update function
45
+ const updateMutations = (0, _react.useCallback)(() => {
46
+ const allMutations = queryClient.getMutationCache().getAll();
47
+ if (hasMutationsChanged(allMutations)) {
48
+ // Update states map
49
+ const newStatesMap = new Map();
50
+ allMutations.forEach(m => {
51
+ newStatesMap.set(m.mutationId, m.state);
52
+ });
53
+ mutationStatesRef.current = newStatesMap;
54
+ setMutations(allMutations);
55
+ }
56
+ }, [queryClient, hasMutationsChanged]);
17
57
  (0, _react.useEffect)(() => {
18
- const updateMutations = () => {
19
- const newMutations = queryClient.getMutationCache().getAll();
20
- const newStates = newMutations.map(m => m.state);
21
- const snapshot = JSON.stringify(newStates);
22
- if (mutationsSnapshotRef.current !== snapshot) {
23
- mutationsSnapshotRef.current = snapshot;
24
- setTimeout(() => setMutations(newMutations), 0);
58
+ // Initial update
59
+ updateMutations();
60
+
61
+ // Subscribe with event filtering (matching useAllQueries pattern)
62
+ const unsubscribe = queryClient.getMutationCache().subscribe(event => {
63
+ // Process events that affect mutation list
64
+ if (event.type === "added" || event.type === "removed" || event.type === "updated") {
65
+ // Debounce updates to batch rapid changes
66
+ if (updateTimerRef.current) {
67
+ clearTimeout(updateTimerRef.current);
68
+ }
69
+ updateTimerRef.current = setTimeout(() => {
70
+ updateMutations();
71
+ }, 10);
72
+ }
73
+ });
74
+ return () => {
75
+ unsubscribe();
76
+ if (updateTimerRef.current) {
77
+ clearTimeout(updateTimerRef.current);
25
78
  }
26
79
  };
27
- setTimeout(updateMutations, 0);
28
- const unsubscribe = queryClient.getMutationCache().subscribe(updateMutations);
29
- return () => unsubscribe();
30
- }, [queryClient]);
80
+ }, [queryClient, updateMutations]);
31
81
  return {
32
82
  mutations
33
83
  };
@@ -8,7 +8,7 @@ var _react = require("react");
8
8
  var _reactQuery = require("@tanstack/react-query");
9
9
  var _sharedUi = require("@buoy-gg/shared-ui");
10
10
  /**
11
- * Synchronizes a local Wi-Fi toggle with React Querys `onlineManager`, persisting the selection
11
+ * Synchronizes a local Wi-Fi toggle with React Query's `onlineManager`, persisting the selection
12
12
  * so developers can simulate offline mode across reloads.
13
13
  */
14
14
  function useWifiState() {
@@ -20,7 +20,7 @@ function useWifiState() {
20
20
  if (hasLoadedPersistedState.current) return;
21
21
  const loadPersistedState = async () => {
22
22
  try {
23
- const savedState = await (0, _sharedUi.safeGetItem)(_sharedUi.devToolsStorageKeys.settings.wifiEnabled());
23
+ const savedState = await _sharedUi.persistentStorage.getItem(_sharedUi.devToolsStorageKeys.settings.wifiEnabled());
24
24
  if (savedState !== null) {
25
25
  const isEnabled = savedState === "true";
26
26
  setIsOnline(isEnabled);
@@ -37,7 +37,7 @@ function useWifiState() {
37
37
  // Save WiFi state when it changes
38
38
  const saveWifiState = async enabled => {
39
39
  try {
40
- await (0, _sharedUi.safeSetItem)(_sharedUi.devToolsStorageKeys.settings.wifiEnabled(), enabled.toString());
40
+ await _sharedUi.persistentStorage.setItem(_sharedUi.devToolsStorageKeys.settings.wifiEnabled(), enabled.toString());
41
41
  } catch (error) {
42
42
  // Failed to save WiFi state
43
43
  }
@@ -13,4 +13,15 @@ Object.keys(_ReactQueryDevTools).forEach(function (key) {
13
13
  return _ReactQueryDevTools[key];
14
14
  }
15
15
  });
16
+ });
17
+ var _stores = require("./stores");
18
+ Object.keys(_stores).forEach(function (key) {
19
+ if (key === "default" || key === "__esModule") return;
20
+ if (key in exports && exports[key] === _stores[key]) return;
21
+ Object.defineProperty(exports, key, {
22
+ enumerable: true,
23
+ get: function () {
24
+ return _stores[key];
25
+ }
26
+ });
16
27
  });
@@ -0,0 +1,48 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ Object.defineProperty(exports, "clearReactQueryEvents", {
7
+ enumerable: true,
8
+ get: function () {
9
+ return _reactQueryEventStore.clearReactQueryEvents;
10
+ }
11
+ });
12
+ Object.defineProperty(exports, "disconnectQueryClient", {
13
+ enumerable: true,
14
+ get: function () {
15
+ return _reactQueryEventStore.disconnectQueryClient;
16
+ }
17
+ });
18
+ Object.defineProperty(exports, "getReactQueryEvents", {
19
+ enumerable: true,
20
+ get: function () {
21
+ return _reactQueryEventStore.getReactQueryEvents;
22
+ }
23
+ });
24
+ Object.defineProperty(exports, "isReactQueryConnected", {
25
+ enumerable: true,
26
+ get: function () {
27
+ return _reactQueryEventStore.isReactQueryConnected;
28
+ }
29
+ });
30
+ Object.defineProperty(exports, "reactQueryEventStore", {
31
+ enumerable: true,
32
+ get: function () {
33
+ return _reactQueryEventStore.reactQueryEventStore;
34
+ }
35
+ });
36
+ Object.defineProperty(exports, "setQueryClient", {
37
+ enumerable: true,
38
+ get: function () {
39
+ return _reactQueryEventStore.setQueryClient;
40
+ }
41
+ });
42
+ Object.defineProperty(exports, "subscribeToReactQueryEvents", {
43
+ enumerable: true,
44
+ get: function () {
45
+ return _reactQueryEventStore.subscribeToReactQueryEvents;
46
+ }
47
+ });
48
+ var _reactQueryEventStore = require("./reactQueryEventStore");