@buoy-gg/react-query 1.7.8 → 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.
- package/lib/commonjs/index.js +619 -24
- package/lib/commonjs/preset.js +1 -1
- package/lib/commonjs/react-query/components/ReactQueryDevToolsModal.js +12 -0
- package/lib/commonjs/react-query/components/modals/MutationBrowserModal.js +2 -1
- package/lib/commonjs/react-query/components/modals/QueryBrowserModal.js +8 -14
- package/lib/commonjs/react-query/hooks/useAllMutations.js +65 -15
- package/lib/commonjs/react-query/hooks/useWifiState.js +3 -3
- package/lib/commonjs/react-query/index.js +11 -0
- package/lib/commonjs/react-query/stores/index.js +48 -0
- package/lib/commonjs/react-query/stores/reactQueryEventStore.js +311 -0
- package/lib/commonjs/react-query/utils/modalStorageOperations.js +2 -2
- package/lib/module/index.js +113 -8
- package/lib/module/preset.js +2 -2
- package/lib/module/react-query/components/ReactQueryDevToolsModal.js +13 -1
- package/lib/module/react-query/components/modals/MutationBrowserModal.js +2 -1
- package/lib/module/react-query/components/modals/QueryBrowserModal.js +9 -15
- package/lib/module/react-query/hooks/useAllMutations.js +66 -16
- package/lib/module/react-query/hooks/useWifiState.js +4 -4
- package/lib/module/react-query/index.js +2 -1
- package/lib/module/react-query/stores/index.js +3 -0
- package/lib/module/react-query/stores/reactQueryEventStore.js +302 -0
- package/lib/module/react-query/utils/modalStorageOperations.js +3 -3
- package/lib/typescript/index.d.ts +61 -5
- package/lib/typescript/index.d.ts.map +1 -1
- package/lib/typescript/react-query/components/ReactQueryDevToolsModal.d.ts.map +1 -1
- package/lib/typescript/react-query/components/modals/MutationBrowserModal.d.ts.map +1 -1
- package/lib/typescript/react-query/components/modals/QueryBrowserModal.d.ts.map +1 -1
- package/lib/typescript/react-query/hooks/useAllMutations.d.ts +2 -2
- package/lib/typescript/react-query/hooks/useAllMutations.d.ts.map +1 -1
- package/lib/typescript/react-query/hooks/useWifiState.d.ts +1 -1
- package/lib/typescript/react-query/hooks/useWifiState.d.ts.map +1 -1
- package/lib/typescript/react-query/index.d.ts +1 -0
- package/lib/typescript/react-query/index.d.ts.map +1 -1
- package/lib/typescript/react-query/stores/index.d.ts +2 -0
- package/lib/typescript/react-query/stores/index.d.ts.map +1 -0
- package/lib/typescript/react-query/stores/reactQueryEventStore.d.ts +99 -0
- package/lib/typescript/react-query/stores/reactQueryEventStore.d.ts.map +1 -0
- package/package.json +17 -3
package/lib/commonjs/preset.js
CHANGED
|
@@ -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
|
|
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);
|
|
@@ -40,7 +40,8 @@ function MutationBrowserModal({
|
|
|
40
40
|
// Clear mutation cache handler
|
|
41
41
|
const handleClearCache = (0, _react.useCallback)(() => {
|
|
42
42
|
queryClient.getMutationCache().clear();
|
|
43
|
-
|
|
43
|
+
onMutationSelect(undefined);
|
|
44
|
+
}, [queryClient, onMutationSelect]);
|
|
44
45
|
|
|
45
46
|
// Track modal mode for conditional styling
|
|
46
47
|
// Initialize with bottomSheet but it will be updated from persisted state if available
|
|
@@ -52,17 +52,11 @@ function QueryBrowserModal({
|
|
|
52
52
|
const [ignoredPatterns, setIgnoredPatterns] = (0, _react.useState)(new Set());
|
|
53
53
|
const [includedPatterns, setIncludedPatterns] = (0, _react.useState)(new Set());
|
|
54
54
|
|
|
55
|
-
// AsyncStorage for persisting ignored patterns
|
|
56
|
-
const {
|
|
57
|
-
getItem: safeGetItem,
|
|
58
|
-
setItem: safeSetItem
|
|
59
|
-
} = (0, _sharedUi.useSafeAsyncStorage)();
|
|
60
|
-
|
|
61
55
|
// Load ignored patterns from storage on mount
|
|
62
56
|
(0, _react.useEffect)(() => {
|
|
63
57
|
const loadFilters = async () => {
|
|
64
58
|
try {
|
|
65
|
-
const stored = await
|
|
59
|
+
const stored = await _sharedUi.persistentStorage.getItem(_sharedUi.devToolsStorageKeys.reactQuery.ignoredPatterns());
|
|
66
60
|
if (stored) {
|
|
67
61
|
const patterns = JSON.parse(stored);
|
|
68
62
|
if (Array.isArray(patterns)) {
|
|
@@ -74,13 +68,13 @@ function QueryBrowserModal({
|
|
|
74
68
|
}
|
|
75
69
|
};
|
|
76
70
|
loadFilters();
|
|
77
|
-
}, [
|
|
71
|
+
}, []);
|
|
78
72
|
|
|
79
73
|
// Load included patterns from storage on mount
|
|
80
74
|
(0, _react.useEffect)(() => {
|
|
81
75
|
const loadFilters = async () => {
|
|
82
76
|
try {
|
|
83
|
-
const stored = await
|
|
77
|
+
const stored = await _sharedUi.persistentStorage.getItem(_sharedUi.devToolsStorageKeys.reactQuery.includedPatterns());
|
|
84
78
|
if (stored) {
|
|
85
79
|
const patterns = JSON.parse(stored);
|
|
86
80
|
if (Array.isArray(patterns)) {
|
|
@@ -92,33 +86,33 @@ function QueryBrowserModal({
|
|
|
92
86
|
}
|
|
93
87
|
};
|
|
94
88
|
loadFilters();
|
|
95
|
-
}, [
|
|
89
|
+
}, []);
|
|
96
90
|
|
|
97
91
|
// Save ignored patterns to storage when they change
|
|
98
92
|
(0, _react.useEffect)(() => {
|
|
99
93
|
const saveFilters = async () => {
|
|
100
94
|
try {
|
|
101
95
|
const patterns = Array.from(ignoredPatterns);
|
|
102
|
-
await
|
|
96
|
+
await _sharedUi.persistentStorage.setItem(_sharedUi.devToolsStorageKeys.reactQuery.ignoredPatterns(), JSON.stringify(patterns));
|
|
103
97
|
} catch (error) {
|
|
104
98
|
console.error("Failed to save ignored patterns:", error);
|
|
105
99
|
}
|
|
106
100
|
};
|
|
107
101
|
saveFilters();
|
|
108
|
-
}, [ignoredPatterns
|
|
102
|
+
}, [ignoredPatterns]);
|
|
109
103
|
|
|
110
104
|
// Save included patterns to storage when they change
|
|
111
105
|
(0, _react.useEffect)(() => {
|
|
112
106
|
const saveFilters = async () => {
|
|
113
107
|
try {
|
|
114
108
|
const patterns = Array.from(includedPatterns);
|
|
115
|
-
await
|
|
109
|
+
await _sharedUi.persistentStorage.setItem(_sharedUi.devToolsStorageKeys.reactQuery.includedPatterns(), JSON.stringify(patterns));
|
|
116
110
|
} catch (error) {
|
|
117
111
|
console.error("Failed to save included patterns:", error);
|
|
118
112
|
}
|
|
119
113
|
};
|
|
120
114
|
saveFilters();
|
|
121
|
-
}, [includedPatterns
|
|
115
|
+
}, [includedPatterns]);
|
|
122
116
|
|
|
123
117
|
// Toggle pattern in ignored set
|
|
124
118
|
const handlePatternToggle = (0, _react.useCallback)(pattern => {
|
|
@@ -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.
|
|
11
|
-
*
|
|
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
|
-
|
|
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
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
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
|
-
|
|
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 Query
|
|
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
|
|
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
|
|
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");
|
|
@@ -0,0 +1,311 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.subscribeToReactQueryEvents = exports.setQueryClient = exports.reactQueryEventStore = exports.isReactQueryConnected = exports.getReactQueryEvents = exports.disconnectQueryClient = exports.clearReactQueryEvents = void 0;
|
|
7
|
+
var _storageQueryUtils = require("../utils/storageQueryUtils");
|
|
8
|
+
/**
|
|
9
|
+
* React Query Event Store
|
|
10
|
+
*
|
|
11
|
+
* Bridges React Query's cache subscription system to a simple pub/sub pattern
|
|
12
|
+
* that can be consumed by the unified Events DevTools.
|
|
13
|
+
*
|
|
14
|
+
* Usage:
|
|
15
|
+
* 1. In your app, call setQueryClient(queryClient) to connect
|
|
16
|
+
* 2. The store will emit events for query/mutation state changes
|
|
17
|
+
* 3. The Events DevTools subscribes to these events
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* React Query event types for the unified timeline
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Unified React Query event for the timeline
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
let eventIdCounter = 0;
|
|
29
|
+
function generateEventId() {
|
|
30
|
+
return `rq-${Date.now()}-${++eventIdCounter}`;
|
|
31
|
+
}
|
|
32
|
+
class ReactQueryEventStore {
|
|
33
|
+
events = [];
|
|
34
|
+
listeners = new Set();
|
|
35
|
+
queryClient = null;
|
|
36
|
+
queryUnsubscribe = null;
|
|
37
|
+
mutationUnsubscribe = null;
|
|
38
|
+
maxEvents = 200;
|
|
39
|
+
|
|
40
|
+
// Track fetch start times for duration calculation
|
|
41
|
+
fetchStartTimes = new Map();
|
|
42
|
+
mutationStartTimes = new Map();
|
|
43
|
+
|
|
44
|
+
// Track last known states to detect transitions
|
|
45
|
+
lastQueryStates = new Map();
|
|
46
|
+
lastMutationStates = new Map();
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Connect a QueryClient to the store
|
|
50
|
+
* Call this in your app after creating the QueryClient
|
|
51
|
+
*/
|
|
52
|
+
setQueryClient(queryClient) {
|
|
53
|
+
// Cleanup previous connection
|
|
54
|
+
this.disconnect();
|
|
55
|
+
this.queryClient = queryClient;
|
|
56
|
+
|
|
57
|
+
// Subscribe to query cache
|
|
58
|
+
this.queryUnsubscribe = queryClient.getQueryCache().subscribe(event => {
|
|
59
|
+
if (event.type === "updated" && event.query) {
|
|
60
|
+
this.handleQueryUpdate(event.query);
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
// Subscribe to mutation cache
|
|
65
|
+
this.mutationUnsubscribe = queryClient.getMutationCache().subscribe(event => {
|
|
66
|
+
if (event.type === "updated" && event.mutation) {
|
|
67
|
+
this.handleMutationUpdate(event.mutation);
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Disconnect from the QueryClient
|
|
74
|
+
*/
|
|
75
|
+
disconnect() {
|
|
76
|
+
if (this.queryUnsubscribe) {
|
|
77
|
+
this.queryUnsubscribe();
|
|
78
|
+
this.queryUnsubscribe = null;
|
|
79
|
+
}
|
|
80
|
+
if (this.mutationUnsubscribe) {
|
|
81
|
+
this.mutationUnsubscribe();
|
|
82
|
+
this.mutationUnsubscribe = null;
|
|
83
|
+
}
|
|
84
|
+
this.queryClient = null;
|
|
85
|
+
this.lastQueryStates.clear();
|
|
86
|
+
this.lastMutationStates.clear();
|
|
87
|
+
this.fetchStartTimes.clear();
|
|
88
|
+
this.mutationStartTimes.clear();
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Handle query state updates and emit appropriate events
|
|
93
|
+
*/
|
|
94
|
+
handleQueryUpdate(query) {
|
|
95
|
+
// Skip storage queries (internal to the devtools)
|
|
96
|
+
if ((0, _storageQueryUtils.isStorageQuery)(query.queryKey)) {
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
const queryHash = query.queryHash;
|
|
100
|
+
const currentState = {
|
|
101
|
+
fetchStatus: query.state.fetchStatus,
|
|
102
|
+
status: query.state.status
|
|
103
|
+
};
|
|
104
|
+
const lastState = this.lastQueryStates.get(queryHash);
|
|
105
|
+
|
|
106
|
+
// Detect state transitions
|
|
107
|
+
if (!lastState) {
|
|
108
|
+
// New query - if it's fetching, emit fetch start
|
|
109
|
+
if (currentState.fetchStatus === "fetching") {
|
|
110
|
+
this.fetchStartTimes.set(queryHash, Date.now());
|
|
111
|
+
this.addEvent({
|
|
112
|
+
id: generateEventId(),
|
|
113
|
+
type: "query-fetch-start",
|
|
114
|
+
timestamp: Date.now(),
|
|
115
|
+
queryKey: query.queryKey,
|
|
116
|
+
queryHash,
|
|
117
|
+
query
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
} else {
|
|
121
|
+
// Existing query - check for transitions
|
|
122
|
+
const wasFetching = lastState.fetchStatus === "fetching";
|
|
123
|
+
const isFetching = currentState.fetchStatus === "fetching";
|
|
124
|
+
|
|
125
|
+
// Started fetching
|
|
126
|
+
if (!wasFetching && isFetching) {
|
|
127
|
+
this.fetchStartTimes.set(queryHash, Date.now());
|
|
128
|
+
this.addEvent({
|
|
129
|
+
id: generateEventId(),
|
|
130
|
+
type: "query-fetch-start",
|
|
131
|
+
timestamp: Date.now(),
|
|
132
|
+
queryKey: query.queryKey,
|
|
133
|
+
queryHash,
|
|
134
|
+
query
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// Finished fetching
|
|
139
|
+
if (wasFetching && !isFetching) {
|
|
140
|
+
const startTime = this.fetchStartTimes.get(queryHash);
|
|
141
|
+
const duration = startTime ? Date.now() - startTime : undefined;
|
|
142
|
+
this.fetchStartTimes.delete(queryHash);
|
|
143
|
+
if (currentState.status === "error") {
|
|
144
|
+
this.addEvent({
|
|
145
|
+
id: generateEventId(),
|
|
146
|
+
type: "query-fetch-error",
|
|
147
|
+
timestamp: Date.now(),
|
|
148
|
+
queryKey: query.queryKey,
|
|
149
|
+
queryHash,
|
|
150
|
+
queryError: query.state.error,
|
|
151
|
+
duration,
|
|
152
|
+
query
|
|
153
|
+
});
|
|
154
|
+
} else {
|
|
155
|
+
this.addEvent({
|
|
156
|
+
id: generateEventId(),
|
|
157
|
+
type: "query-fetch-success",
|
|
158
|
+
timestamp: Date.now(),
|
|
159
|
+
queryKey: query.queryKey,
|
|
160
|
+
queryHash,
|
|
161
|
+
queryData: query.state.data,
|
|
162
|
+
duration,
|
|
163
|
+
query
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// Query was invalidated
|
|
169
|
+
if (!lastState.status && query.state.isInvalidated) {
|
|
170
|
+
this.addEvent({
|
|
171
|
+
id: generateEventId(),
|
|
172
|
+
type: "query-invalidated",
|
|
173
|
+
timestamp: Date.now(),
|
|
174
|
+
queryKey: query.queryKey,
|
|
175
|
+
queryHash,
|
|
176
|
+
query
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
// Update last known state
|
|
182
|
+
this.lastQueryStates.set(queryHash, currentState);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* Handle mutation state updates and emit appropriate events
|
|
187
|
+
*/
|
|
188
|
+
handleMutationUpdate(mutation) {
|
|
189
|
+
const mutationId = mutation.mutationId;
|
|
190
|
+
const currentStatus = mutation.state.status;
|
|
191
|
+
const lastStatus = this.lastMutationStates.get(mutationId);
|
|
192
|
+
if (lastStatus !== currentStatus) {
|
|
193
|
+
// Status changed
|
|
194
|
+
if (currentStatus === "pending" && lastStatus !== "pending") {
|
|
195
|
+
// Mutation started
|
|
196
|
+
this.mutationStartTimes.set(mutationId, Date.now());
|
|
197
|
+
this.addEvent({
|
|
198
|
+
id: generateEventId(),
|
|
199
|
+
type: "mutation-start",
|
|
200
|
+
timestamp: Date.now(),
|
|
201
|
+
mutationId,
|
|
202
|
+
mutationKey: mutation.options.mutationKey,
|
|
203
|
+
mutationVariables: mutation.state.variables,
|
|
204
|
+
mutation
|
|
205
|
+
});
|
|
206
|
+
} else if (currentStatus === "success" && lastStatus === "pending") {
|
|
207
|
+
// Mutation succeeded
|
|
208
|
+
const startTime = this.mutationStartTimes.get(mutationId);
|
|
209
|
+
const duration = startTime ? Date.now() - startTime : undefined;
|
|
210
|
+
this.mutationStartTimes.delete(mutationId);
|
|
211
|
+
this.addEvent({
|
|
212
|
+
id: generateEventId(),
|
|
213
|
+
type: "mutation-success",
|
|
214
|
+
timestamp: Date.now(),
|
|
215
|
+
mutationId,
|
|
216
|
+
mutationKey: mutation.options.mutationKey,
|
|
217
|
+
mutationVariables: mutation.state.variables,
|
|
218
|
+
mutationData: mutation.state.data,
|
|
219
|
+
duration,
|
|
220
|
+
mutation
|
|
221
|
+
});
|
|
222
|
+
} else if (currentStatus === "error" && lastStatus === "pending") {
|
|
223
|
+
// Mutation failed
|
|
224
|
+
const startTime = this.mutationStartTimes.get(mutationId);
|
|
225
|
+
const duration = startTime ? Date.now() - startTime : undefined;
|
|
226
|
+
this.mutationStartTimes.delete(mutationId);
|
|
227
|
+
this.addEvent({
|
|
228
|
+
id: generateEventId(),
|
|
229
|
+
type: "mutation-error",
|
|
230
|
+
timestamp: Date.now(),
|
|
231
|
+
mutationId,
|
|
232
|
+
mutationKey: mutation.options.mutationKey,
|
|
233
|
+
mutationVariables: mutation.state.variables,
|
|
234
|
+
mutationError: mutation.state.error,
|
|
235
|
+
duration,
|
|
236
|
+
mutation
|
|
237
|
+
});
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
// Update last known status
|
|
242
|
+
this.lastMutationStates.set(mutationId, currentStatus);
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
/**
|
|
246
|
+
* Add an event to the store
|
|
247
|
+
*/
|
|
248
|
+
addEvent(event) {
|
|
249
|
+
this.events = [event, ...this.events].slice(0, this.maxEvents);
|
|
250
|
+
this.notifyListeners();
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
/**
|
|
254
|
+
* Get all events
|
|
255
|
+
*/
|
|
256
|
+
getEvents() {
|
|
257
|
+
return this.events;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
/**
|
|
261
|
+
* Subscribe to event changes
|
|
262
|
+
*/
|
|
263
|
+
subscribe(listener) {
|
|
264
|
+
this.listeners.add(listener);
|
|
265
|
+
// Immediately call with current events
|
|
266
|
+
listener(this.events);
|
|
267
|
+
return () => {
|
|
268
|
+
this.listeners.delete(listener);
|
|
269
|
+
};
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
/**
|
|
273
|
+
* Notify all listeners
|
|
274
|
+
*/
|
|
275
|
+
notifyListeners() {
|
|
276
|
+
const events = this.events;
|
|
277
|
+
this.listeners.forEach(listener => listener(events));
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
/**
|
|
281
|
+
* Clear all events
|
|
282
|
+
*/
|
|
283
|
+
clearEvents() {
|
|
284
|
+
this.events = [];
|
|
285
|
+
this.notifyListeners();
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
/**
|
|
289
|
+
* Check if connected to a QueryClient
|
|
290
|
+
*/
|
|
291
|
+
isConnected() {
|
|
292
|
+
return this.queryClient !== null;
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
// Singleton instance
|
|
297
|
+
const reactQueryEventStore = exports.reactQueryEventStore = new ReactQueryEventStore();
|
|
298
|
+
|
|
299
|
+
// Convenience exports
|
|
300
|
+
const setQueryClient = queryClient => reactQueryEventStore.setQueryClient(queryClient);
|
|
301
|
+
exports.setQueryClient = setQueryClient;
|
|
302
|
+
const disconnectQueryClient = () => reactQueryEventStore.disconnect();
|
|
303
|
+
exports.disconnectQueryClient = disconnectQueryClient;
|
|
304
|
+
const getReactQueryEvents = () => reactQueryEventStore.getEvents();
|
|
305
|
+
exports.getReactQueryEvents = getReactQueryEvents;
|
|
306
|
+
const subscribeToReactQueryEvents = listener => reactQueryEventStore.subscribe(listener);
|
|
307
|
+
exports.subscribeToReactQueryEvents = subscribeToReactQueryEvents;
|
|
308
|
+
const clearReactQueryEvents = () => reactQueryEventStore.clearEvents();
|
|
309
|
+
exports.clearReactQueryEvents = clearReactQueryEvents;
|
|
310
|
+
const isReactQueryConnected = () => reactQueryEventStore.isConnected();
|
|
311
|
+
exports.isReactQueryConnected = isReactQueryConnected;
|
|
@@ -7,10 +7,10 @@ exports.savePanelHeight = exports.savePanelDimensions = exports.saveModalVisibil
|
|
|
7
7
|
var _sharedUi = require("@buoy-gg/shared-ui");
|
|
8
8
|
// Helper functions for persisting panel state using shared storage wrapper
|
|
9
9
|
const setItem = async (key, value) => {
|
|
10
|
-
await
|
|
10
|
+
await _sharedUi.persistentStorage.setItem(key, value);
|
|
11
11
|
};
|
|
12
12
|
const getItem = async key => {
|
|
13
|
-
return
|
|
13
|
+
return _sharedUi.persistentStorage.getItem(key);
|
|
14
14
|
};
|
|
15
15
|
// Storage operations
|
|
16
16
|
/**
|