@adventurelabs/scout-core 1.0.107 → 1.0.109
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/dist/hooks/useScoutRefresh.d.ts +2 -17
- package/dist/hooks/useScoutRefresh.js +119 -177
- package/dist/store/scout.d.ts +1 -6
- package/dist/store/scout.js +1 -5
- package/package.json +1 -1
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { CacheStats, TimingStats, DatabaseHealth } from "../helpers/cache";
|
|
2
1
|
export interface UseScoutRefreshOptions {
|
|
3
2
|
autoRefresh?: boolean;
|
|
4
3
|
onRefreshComplete?: () => void;
|
|
@@ -16,33 +15,19 @@ export interface UseScoutRefreshOptions {
|
|
|
16
15
|
*
|
|
17
16
|
* @returns Object containing:
|
|
18
17
|
* - handleRefresh: Function to manually trigger a refresh
|
|
19
|
-
* - getTimingStats: Function to get detailed timing statistics for the last refresh
|
|
20
18
|
* - clearCache: Function to clear the cache
|
|
21
|
-
* - getCacheStats: Function to get cache statistics
|
|
22
19
|
*
|
|
23
20
|
* @example
|
|
24
21
|
* ```tsx
|
|
25
|
-
* const { handleRefresh,
|
|
22
|
+
* const { handleRefresh, clearCache } = useScoutRefresh({
|
|
26
23
|
* cacheFirst: true,
|
|
27
24
|
* cacheTtlMs: 10 * 60 * 1000 // 10 minutes
|
|
28
25
|
* });
|
|
29
26
|
*
|
|
30
|
-
* //
|
|
31
|
-
* const stats = getTimingStats();
|
|
32
|
-
* console.log('Herd modules API took:', stats.herdModulesApi, 'ms');
|
|
33
|
-
* console.log('User API took:', stats.userApi, 'ms');
|
|
34
|
-
* console.log('Data processing took:', stats.dataProcessing, 'ms');
|
|
35
|
-
* console.log('LocalStorage operations took:', stats.localStorage, 'ms');
|
|
36
|
-
* console.log('Total duration:', stats.totalDuration, 'ms');
|
|
27
|
+
* // Timing stats are available in Redux store via selectors
|
|
37
28
|
* ```
|
|
38
29
|
*/
|
|
39
30
|
export declare function useScoutRefresh(options?: UseScoutRefreshOptions): {
|
|
40
31
|
handleRefresh: () => Promise<void>;
|
|
41
|
-
getTimingStats: () => TimingStats;
|
|
42
32
|
clearCache: () => Promise<void>;
|
|
43
|
-
getCacheStats: () => Promise<CacheStats>;
|
|
44
|
-
checkDatabaseHealth: () => Promise<DatabaseHealth>;
|
|
45
|
-
resetDatabase: () => Promise<void>;
|
|
46
|
-
isCacheVersionCompatible: () => Promise<boolean>;
|
|
47
|
-
getCurrentDbVersion: () => number;
|
|
48
33
|
};
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { useEffect, useCallback, useRef } from "react";
|
|
2
2
|
import { useAppDispatch } from "../store/hooks";
|
|
3
|
-
import {
|
|
3
|
+
import { useStore } from "react-redux";
|
|
4
|
+
import { EnumScoutStateStatus, setHerdModules, setStatus, setHerdModulesLoadingState, setHerdModulesLoadedInMs, setHerdModulesApiDuration, setUserApiDuration, setDataProcessingDuration, setUser, setDataSource, setDataSourceInfo, } from "../store/scout";
|
|
4
5
|
import { EnumHerdModulesLoadingState } from "../types/herd_module";
|
|
5
6
|
import { server_load_herd_modules } from "../helpers/herds";
|
|
6
7
|
import { server_get_user } from "../helpers/users";
|
|
7
|
-
import { scoutCache
|
|
8
|
+
import { scoutCache } from "../helpers/cache";
|
|
8
9
|
import { EnumDataSource } from "../types/data_source";
|
|
9
10
|
/**
|
|
10
11
|
* Hook for refreshing scout data with detailed timing measurements and cache-first loading
|
|
@@ -17,30 +18,23 @@ import { EnumDataSource } from "../types/data_source";
|
|
|
17
18
|
*
|
|
18
19
|
* @returns Object containing:
|
|
19
20
|
* - handleRefresh: Function to manually trigger a refresh
|
|
20
|
-
* - getTimingStats: Function to get detailed timing statistics for the last refresh
|
|
21
21
|
* - clearCache: Function to clear the cache
|
|
22
|
-
* - getCacheStats: Function to get cache statistics
|
|
23
22
|
*
|
|
24
23
|
* @example
|
|
25
24
|
* ```tsx
|
|
26
|
-
* const { handleRefresh,
|
|
25
|
+
* const { handleRefresh, clearCache } = useScoutRefresh({
|
|
27
26
|
* cacheFirst: true,
|
|
28
27
|
* cacheTtlMs: 10 * 60 * 1000 // 10 minutes
|
|
29
28
|
* });
|
|
30
29
|
*
|
|
31
|
-
* //
|
|
32
|
-
* const stats = getTimingStats();
|
|
33
|
-
* console.log('Herd modules API took:', stats.herdModulesApi, 'ms');
|
|
34
|
-
* console.log('User API took:', stats.userApi, 'ms');
|
|
35
|
-
* console.log('Data processing took:', stats.dataProcessing, 'ms');
|
|
36
|
-
* console.log('LocalStorage operations took:', stats.localStorage, 'ms');
|
|
37
|
-
* console.log('Total duration:', stats.totalDuration, 'ms');
|
|
30
|
+
* // Timing stats are available in Redux store via selectors
|
|
38
31
|
* ```
|
|
39
32
|
*/
|
|
40
33
|
export function useScoutRefresh(options = {}) {
|
|
41
34
|
const { autoRefresh = true, onRefreshComplete, cacheFirst = true, cacheTtlMs = 24 * 60 * 60 * 1000, // 24 hours default (1 day)
|
|
42
35
|
} = options;
|
|
43
36
|
const dispatch = useAppDispatch();
|
|
37
|
+
const store = useStore();
|
|
44
38
|
const refreshInProgressRef = useRef(false);
|
|
45
39
|
// Refs to store timing measurements
|
|
46
40
|
const timingRefs = useRef({
|
|
@@ -48,10 +42,82 @@ export function useScoutRefresh(options = {}) {
|
|
|
48
42
|
herdModulesDuration: 0,
|
|
49
43
|
userApiDuration: 0,
|
|
50
44
|
dataProcessingDuration: 0,
|
|
51
|
-
localStorageDuration: 0,
|
|
52
45
|
cacheLoadDuration: 0,
|
|
53
46
|
cacheSaveDuration: 0,
|
|
54
47
|
});
|
|
48
|
+
// Helper function for deep comparison of objects
|
|
49
|
+
const deepEqual = useCallback((obj1, obj2, visited = new WeakMap()) => {
|
|
50
|
+
if (obj1 === obj2)
|
|
51
|
+
return true;
|
|
52
|
+
if (obj1 == null || obj2 == null)
|
|
53
|
+
return obj1 === obj2;
|
|
54
|
+
if (typeof obj1 !== typeof obj2)
|
|
55
|
+
return false;
|
|
56
|
+
if (typeof obj1 !== "object")
|
|
57
|
+
return obj1 === obj2;
|
|
58
|
+
// Handle circular references
|
|
59
|
+
if (visited.has(obj1)) {
|
|
60
|
+
return visited.get(obj1) === obj2;
|
|
61
|
+
}
|
|
62
|
+
visited.set(obj1, obj2);
|
|
63
|
+
// Handle Date objects
|
|
64
|
+
if (obj1 instanceof Date && obj2 instanceof Date) {
|
|
65
|
+
return obj1.getTime() === obj2.getTime();
|
|
66
|
+
}
|
|
67
|
+
if (Array.isArray(obj1) !== Array.isArray(obj2))
|
|
68
|
+
return false;
|
|
69
|
+
if (Array.isArray(obj1)) {
|
|
70
|
+
if (obj1.length !== obj2.length)
|
|
71
|
+
return false;
|
|
72
|
+
for (let i = 0; i < obj1.length; i++) {
|
|
73
|
+
if (!deepEqual(obj1[i], obj2[i], visited))
|
|
74
|
+
return false;
|
|
75
|
+
}
|
|
76
|
+
return true;
|
|
77
|
+
}
|
|
78
|
+
const keys1 = Object.keys(obj1);
|
|
79
|
+
const keys2 = Object.keys(obj2);
|
|
80
|
+
if (keys1.length !== keys2.length)
|
|
81
|
+
return false;
|
|
82
|
+
for (const key of keys1) {
|
|
83
|
+
if (!keys2.includes(key))
|
|
84
|
+
return false;
|
|
85
|
+
if (!deepEqual(obj1[key], obj2[key], visited))
|
|
86
|
+
return false;
|
|
87
|
+
}
|
|
88
|
+
return true;
|
|
89
|
+
}, []);
|
|
90
|
+
// Helper function to conditionally dispatch only if data has changed
|
|
91
|
+
const conditionalDispatch = useCallback((newData, currentData, actionCreator, dataType) => {
|
|
92
|
+
if (!deepEqual(newData, currentData)) {
|
|
93
|
+
console.log(`[useScoutRefresh] ${dataType} data changed, updating store`);
|
|
94
|
+
dispatch(actionCreator(newData));
|
|
95
|
+
return true;
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
console.log(`[useScoutRefresh] ${dataType} data unchanged, skipping store update`);
|
|
99
|
+
return false;
|
|
100
|
+
}
|
|
101
|
+
}, [dispatch, deepEqual]);
|
|
102
|
+
// Helper function to handle IndexedDB errors - memoized for stability
|
|
103
|
+
const handleIndexedDbError = useCallback(async (error, operation, retryFn) => {
|
|
104
|
+
if (error instanceof Error &&
|
|
105
|
+
(error.message.includes("object store") ||
|
|
106
|
+
error.message.includes("NotFoundError"))) {
|
|
107
|
+
console.log(`[useScoutRefresh] Attempting database reset due to ${operation} error...`);
|
|
108
|
+
try {
|
|
109
|
+
await scoutCache.resetDatabase();
|
|
110
|
+
console.log("[useScoutRefresh] Database reset successful");
|
|
111
|
+
if (retryFn) {
|
|
112
|
+
await retryFn();
|
|
113
|
+
console.log(`[useScoutRefresh] ${operation} successful after database reset`);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
catch (resetError) {
|
|
117
|
+
console.error(`[useScoutRefresh] Database reset and retry failed:`, resetError);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}, []);
|
|
55
121
|
const handleRefresh = useCallback(async () => {
|
|
56
122
|
// Prevent concurrent refresh calls
|
|
57
123
|
if (refreshInProgressRef.current) {
|
|
@@ -85,9 +151,13 @@ export function useScoutRefresh(options = {}) {
|
|
|
85
151
|
cacheAge: cacheResult.age,
|
|
86
152
|
isStale: cacheResult.isStale,
|
|
87
153
|
}));
|
|
88
|
-
//
|
|
89
|
-
|
|
90
|
-
|
|
154
|
+
// Conditionally update the store with cached data if different
|
|
155
|
+
// Get current state at execution time to avoid dependency issues
|
|
156
|
+
const currentHerdModules = store.getState().scout.herd_modules;
|
|
157
|
+
const herdModulesChanged = conditionalDispatch(cachedHerdModules, currentHerdModules, setHerdModules, "Herd modules (cache)");
|
|
158
|
+
if (herdModulesChanged) {
|
|
159
|
+
dispatch(setHerdModulesLoadingState(EnumHerdModulesLoadingState.SUCCESSFULLY_LOADED));
|
|
160
|
+
}
|
|
91
161
|
// Always load user data from API
|
|
92
162
|
const userStartTime = Date.now();
|
|
93
163
|
const res_new_user = await server_get_user();
|
|
@@ -95,7 +165,8 @@ export function useScoutRefresh(options = {}) {
|
|
|
95
165
|
timingRefs.current.userApiDuration = userApiDuration;
|
|
96
166
|
dispatch(setUserApiDuration(userApiDuration));
|
|
97
167
|
if (res_new_user && res_new_user.data) {
|
|
98
|
-
|
|
168
|
+
const currentUser = store.getState().scout.user;
|
|
169
|
+
conditionalDispatch(res_new_user.data, currentUser, setUser, "User (initial)");
|
|
99
170
|
}
|
|
100
171
|
// If cache is fresh, we still background fetch but don't wait
|
|
101
172
|
if (!cacheResult.isStale) {
|
|
@@ -123,25 +194,17 @@ export function useScoutRefresh(options = {}) {
|
|
|
123
194
|
}
|
|
124
195
|
catch (cacheError) {
|
|
125
196
|
console.warn("[useScoutRefresh] Background cache save failed:", cacheError);
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
(cacheError.message.includes("object store") ||
|
|
129
|
-
cacheError.message.includes("NotFoundError"))) {
|
|
130
|
-
console.log("[useScoutRefresh] Attempting database reset due to schema error...");
|
|
131
|
-
try {
|
|
132
|
-
await scoutCache.resetDatabase();
|
|
133
|
-
console.log("[useScoutRefresh] Database reset successful, retrying cache save...");
|
|
197
|
+
await handleIndexedDbError(cacheError, "background cache save", async () => {
|
|
198
|
+
if (backgroundHerdModulesResult.data) {
|
|
134
199
|
await scoutCache.setHerdModules(backgroundHerdModulesResult.data, cacheTtlMs);
|
|
135
|
-
console.log("[useScoutRefresh] Cache save successful after database reset");
|
|
136
|
-
}
|
|
137
|
-
catch (resetError) {
|
|
138
|
-
console.error("[useScoutRefresh] Database reset and retry failed:", resetError);
|
|
139
200
|
}
|
|
140
|
-
}
|
|
201
|
+
});
|
|
141
202
|
}
|
|
142
|
-
//
|
|
143
|
-
|
|
144
|
-
|
|
203
|
+
// Conditionally update store with fresh background data
|
|
204
|
+
const currentHerdModules = store.getState().scout.herd_modules;
|
|
205
|
+
const currentUser = store.getState().scout.user;
|
|
206
|
+
conditionalDispatch(backgroundHerdModulesResult.data, currentHerdModules, setHerdModules, "Herd modules (background)");
|
|
207
|
+
conditionalDispatch(backgroundUserResult.data, currentUser, setUser, "User (background)");
|
|
145
208
|
// Update data source to DATABASE
|
|
146
209
|
dispatch(setDataSource(EnumDataSource.DATABASE));
|
|
147
210
|
dispatch(setDataSourceInfo({
|
|
@@ -172,19 +235,7 @@ export function useScoutRefresh(options = {}) {
|
|
|
172
235
|
}
|
|
173
236
|
catch (cacheError) {
|
|
174
237
|
console.warn("[useScoutRefresh] Cache load failed:", cacheError);
|
|
175
|
-
|
|
176
|
-
if (cacheError instanceof Error &&
|
|
177
|
-
(cacheError.message.includes("object store") ||
|
|
178
|
-
cacheError.message.includes("NotFoundError"))) {
|
|
179
|
-
console.log("[useScoutRefresh] Attempting database reset due to cache load error...");
|
|
180
|
-
try {
|
|
181
|
-
await scoutCache.resetDatabase();
|
|
182
|
-
console.log("[useScoutRefresh] Database reset successful");
|
|
183
|
-
}
|
|
184
|
-
catch (resetError) {
|
|
185
|
-
console.error("[useScoutRefresh] Database reset failed:", resetError);
|
|
186
|
-
}
|
|
187
|
-
}
|
|
238
|
+
await handleIndexedDbError(cacheError, "cache load");
|
|
188
239
|
// Continue with API call
|
|
189
240
|
}
|
|
190
241
|
}
|
|
@@ -251,65 +302,22 @@ export function useScoutRefresh(options = {}) {
|
|
|
251
302
|
}
|
|
252
303
|
catch (cacheError) {
|
|
253
304
|
console.warn("[useScoutRefresh] Cache save failed:", cacheError);
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
cacheError.message.includes("NotFoundError"))) {
|
|
258
|
-
console.log("[useScoutRefresh] Attempting database reset due to cache save error...");
|
|
259
|
-
try {
|
|
260
|
-
await scoutCache.resetDatabase();
|
|
261
|
-
console.log("[useScoutRefresh] Database reset successful, retrying cache save...");
|
|
262
|
-
await scoutCache.setHerdModules(compatible_new_herd_modules, cacheTtlMs);
|
|
263
|
-
console.log("[useScoutRefresh] Cache save successful after database reset");
|
|
264
|
-
}
|
|
265
|
-
catch (resetError) {
|
|
266
|
-
console.error("[useScoutRefresh] Database reset and retry failed:", resetError);
|
|
267
|
-
}
|
|
268
|
-
}
|
|
305
|
+
await handleIndexedDbError(cacheError, "cache save", async () => {
|
|
306
|
+
await scoutCache.setHerdModules(compatible_new_herd_modules, cacheTtlMs);
|
|
307
|
+
});
|
|
269
308
|
}
|
|
270
|
-
// Step 4:
|
|
309
|
+
// Step 4: Conditionally update store with fresh data if different
|
|
271
310
|
const dataProcessingStartTime = Date.now();
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
311
|
+
const currentHerdModules = store.getState().scout.herd_modules;
|
|
312
|
+
const currentUser = store.getState().scout.user;
|
|
313
|
+
const herdModulesChanged = conditionalDispatch(compatible_new_herd_modules, currentHerdModules, setHerdModules, "Herd modules (fresh API)");
|
|
314
|
+
const userChanged = conditionalDispatch(res_new_user.data, currentUser, setUser, "User (fresh API)");
|
|
315
|
+
if (herdModulesChanged) {
|
|
316
|
+
dispatch(setHerdModulesLoadingState(EnumHerdModulesLoadingState.SUCCESSFULLY_LOADED));
|
|
317
|
+
}
|
|
275
318
|
const dataProcessingDuration = Date.now() - dataProcessingStartTime;
|
|
276
319
|
timingRefs.current.dataProcessingDuration = dataProcessingDuration;
|
|
277
320
|
dispatch(setDataProcessingDuration(dataProcessingDuration));
|
|
278
|
-
// // Step 5: Handle localStorage operations
|
|
279
|
-
const localStorageStartTime = Date.now();
|
|
280
|
-
// try {
|
|
281
|
-
// // Check local storage for a last selected herd
|
|
282
|
-
// const lastSelectedHerd = localStorage.getItem("last_selected_herd");
|
|
283
|
-
// if (lastSelectedHerd) {
|
|
284
|
-
// const found_herd = compatible_new_herd_modules.find(
|
|
285
|
-
// (hm) => hm.herd.id.toString() === lastSelectedHerd,
|
|
286
|
-
// )?.herd;
|
|
287
|
-
// // If herd is found then set it
|
|
288
|
-
// if (found_herd) {
|
|
289
|
-
// dispatch(setActiveHerdId(found_herd.id.toString()));
|
|
290
|
-
// }
|
|
291
|
-
// }
|
|
292
|
-
// // If there is no last selected herd then select the first one
|
|
293
|
-
// else if (compatible_new_herd_modules.length > 0) {
|
|
294
|
-
// const firstHerdId = compatible_new_herd_modules[0].herd.id.toString();
|
|
295
|
-
// localStorage.setItem("last_selected_herd", firstHerdId);
|
|
296
|
-
// dispatch(setActiveHerdId(firstHerdId));
|
|
297
|
-
// }
|
|
298
|
-
// } catch (localStorageError) {
|
|
299
|
-
// console.warn(
|
|
300
|
-
// "[useScoutRefresh] localStorage not available:",
|
|
301
|
-
// localStorageError,
|
|
302
|
-
// );
|
|
303
|
-
// // Fallback: select first herd without localStorage
|
|
304
|
-
// if (compatible_new_herd_modules.length > 0) {
|
|
305
|
-
// dispatch(
|
|
306
|
-
// setActiveHerdId(compatible_new_herd_modules[0].herd.id.toString()),
|
|
307
|
-
// );
|
|
308
|
-
// }
|
|
309
|
-
// }
|
|
310
|
-
const localStorageDuration = Date.now() - localStorageStartTime;
|
|
311
|
-
timingRefs.current.localStorageDuration = localStorageDuration;
|
|
312
|
-
dispatch(setLocalStorageDuration(localStorageDuration));
|
|
313
321
|
const loadingDuration = Date.now() - startTime;
|
|
314
322
|
dispatch(setHerdModulesLoadedInMs(loadingDuration));
|
|
315
323
|
dispatch(setStatus(EnumScoutStateStatus.DONE_LOADING));
|
|
@@ -321,7 +329,6 @@ export function useScoutRefresh(options = {}) {
|
|
|
321
329
|
console.log(` - User API: ${userApiDuration}ms`);
|
|
322
330
|
console.log(` - Cache save: ${timingRefs.current.cacheSaveDuration}ms`);
|
|
323
331
|
console.log(` - Data processing: ${dataProcessingDuration}ms`);
|
|
324
|
-
console.log(` - LocalStorage: ${localStorageDuration}ms`);
|
|
325
332
|
console.log(` - Cache TTL: ${Math.round(cacheTtlMs / 1000)}s`);
|
|
326
333
|
onRefreshComplete?.();
|
|
327
334
|
}
|
|
@@ -343,30 +350,26 @@ export function useScoutRefresh(options = {}) {
|
|
|
343
350
|
console.log(` - Total duration: ${loadingDuration}ms`);
|
|
344
351
|
console.log(` - Herd modules: ${timingRefs.current.herdModulesDuration}ms`);
|
|
345
352
|
console.log(` - User API: ${timingRefs.current.userApiDuration}ms`);
|
|
353
|
+
// Call completion callback even on error for consistency
|
|
354
|
+
onRefreshComplete?.();
|
|
346
355
|
}
|
|
347
356
|
finally {
|
|
348
357
|
refreshInProgressRef.current = false;
|
|
349
358
|
}
|
|
350
|
-
}, [
|
|
359
|
+
}, [
|
|
360
|
+
dispatch,
|
|
361
|
+
store,
|
|
362
|
+
onRefreshComplete,
|
|
363
|
+
cacheFirst,
|
|
364
|
+
cacheTtlMs,
|
|
365
|
+
conditionalDispatch,
|
|
366
|
+
handleIndexedDbError,
|
|
367
|
+
]);
|
|
351
368
|
useEffect(() => {
|
|
352
369
|
if (autoRefresh) {
|
|
353
370
|
handleRefresh();
|
|
354
371
|
}
|
|
355
372
|
}, [autoRefresh, handleRefresh]);
|
|
356
|
-
// Utility function to get timing statistics
|
|
357
|
-
const getTimingStats = useCallback(() => {
|
|
358
|
-
const now = Date.now();
|
|
359
|
-
const startTime = timingRefs.current.startTime;
|
|
360
|
-
return {
|
|
361
|
-
totalDuration: startTime > 0 ? now - startTime : 0,
|
|
362
|
-
cacheLoad: timingRefs.current.cacheLoadDuration,
|
|
363
|
-
herdModulesApi: timingRefs.current.herdModulesDuration,
|
|
364
|
-
userApi: timingRefs.current.userApiDuration,
|
|
365
|
-
cacheSave: timingRefs.current.cacheSaveDuration,
|
|
366
|
-
dataProcessing: timingRefs.current.dataProcessingDuration,
|
|
367
|
-
localStorage: timingRefs.current.localStorageDuration,
|
|
368
|
-
};
|
|
369
|
-
}, []);
|
|
370
373
|
// Utility function to clear cache
|
|
371
374
|
const clearCache = useCallback(async () => {
|
|
372
375
|
try {
|
|
@@ -377,69 +380,8 @@ export function useScoutRefresh(options = {}) {
|
|
|
377
380
|
console.error("[useScoutRefresh] Failed to clear cache:", error);
|
|
378
381
|
}
|
|
379
382
|
}, []);
|
|
380
|
-
// Utility function to get cache statistics
|
|
381
|
-
const getCacheStats = useCallback(async () => {
|
|
382
|
-
try {
|
|
383
|
-
return await scoutCache.getCacheStats();
|
|
384
|
-
}
|
|
385
|
-
catch (error) {
|
|
386
|
-
console.error("[useScoutRefresh] Failed to get cache stats:", error);
|
|
387
|
-
return {
|
|
388
|
-
size: 0,
|
|
389
|
-
lastUpdated: 0,
|
|
390
|
-
isStale: true,
|
|
391
|
-
hitRate: 0,
|
|
392
|
-
totalHits: 0,
|
|
393
|
-
totalMisses: 0,
|
|
394
|
-
};
|
|
395
|
-
}
|
|
396
|
-
}, []);
|
|
397
|
-
// Utility function to check database health
|
|
398
|
-
const checkDatabaseHealth = useCallback(async () => {
|
|
399
|
-
try {
|
|
400
|
-
return await scoutCache.checkDatabaseHealth();
|
|
401
|
-
}
|
|
402
|
-
catch (error) {
|
|
403
|
-
console.error("[useScoutRefresh] Failed to check database health:", error);
|
|
404
|
-
return {
|
|
405
|
-
healthy: false,
|
|
406
|
-
issues: [`Health check failed: ${error}`],
|
|
407
|
-
};
|
|
408
|
-
}
|
|
409
|
-
}, []);
|
|
410
|
-
// Utility function to reset database
|
|
411
|
-
const resetDatabase = useCallback(async () => {
|
|
412
|
-
try {
|
|
413
|
-
await scoutCache.resetDatabase();
|
|
414
|
-
console.log("[useScoutRefresh] Database reset successfully");
|
|
415
|
-
}
|
|
416
|
-
catch (error) {
|
|
417
|
-
console.error("[useScoutRefresh] Failed to reset database:", error);
|
|
418
|
-
throw error;
|
|
419
|
-
}
|
|
420
|
-
}, []);
|
|
421
|
-
// Utility function to check cache version compatibility
|
|
422
|
-
const isCacheVersionCompatible = useCallback(async () => {
|
|
423
|
-
try {
|
|
424
|
-
return await scoutCache.isCacheVersionCompatible();
|
|
425
|
-
}
|
|
426
|
-
catch (error) {
|
|
427
|
-
console.error("[useScoutRefresh] Failed to check cache version compatibility:", error);
|
|
428
|
-
return false;
|
|
429
|
-
}
|
|
430
|
-
}, []);
|
|
431
|
-
// Utility function to get current DB version
|
|
432
|
-
const getCurrentDbVersion = useCallback(() => {
|
|
433
|
-
return scoutCache.getCurrentDbVersion();
|
|
434
|
-
}, []);
|
|
435
383
|
return {
|
|
436
384
|
handleRefresh,
|
|
437
|
-
getTimingStats,
|
|
438
385
|
clearCache,
|
|
439
|
-
getCacheStats,
|
|
440
|
-
checkDatabaseHealth,
|
|
441
|
-
resetDatabase,
|
|
442
|
-
isCacheVersionCompatible,
|
|
443
|
-
getCurrentDbVersion,
|
|
444
386
|
};
|
|
445
387
|
}
|
package/dist/store/scout.d.ts
CHANGED
|
@@ -14,7 +14,6 @@ export interface ScoutState {
|
|
|
14
14
|
herd_modules_api_duration_ms: number | null;
|
|
15
15
|
user_api_duration_ms: number | null;
|
|
16
16
|
data_processing_duration_ms: number | null;
|
|
17
|
-
localStorage_duration_ms: number | null;
|
|
18
17
|
active_herd_id: string | null;
|
|
19
18
|
active_device_id: string | null;
|
|
20
19
|
lastRefreshed: number;
|
|
@@ -55,10 +54,6 @@ export declare const scoutSlice: import("@reduxjs/toolkit").Slice<ScoutState, {
|
|
|
55
54
|
payload: any;
|
|
56
55
|
type: string;
|
|
57
56
|
}) => void;
|
|
58
|
-
setLocalStorageDuration: (state: import("immer").WritableDraft<ScoutState>, action: {
|
|
59
|
-
payload: any;
|
|
60
|
-
type: string;
|
|
61
|
-
}) => void;
|
|
62
57
|
setActiveHerdId: (state: import("immer").WritableDraft<ScoutState>, action: {
|
|
63
58
|
payload: any;
|
|
64
59
|
type: string;
|
|
@@ -160,6 +155,6 @@ export declare const scoutSlice: import("@reduxjs/toolkit").Slice<ScoutState, {
|
|
|
160
155
|
type: string;
|
|
161
156
|
}) => void;
|
|
162
157
|
}, "scout", "scout", import("@reduxjs/toolkit").SliceSelectors<ScoutState>>;
|
|
163
|
-
export declare const setHerdModules: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/setHerdModules">, setStatus: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/setStatus">, setHerdModulesLoadingState: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/setHerdModulesLoadingState">, setHerdModulesLoadedInMs: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/setHerdModulesLoadedInMs">, setHerdModulesApiDuration: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/setHerdModulesApiDuration">, setUserApiDuration: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/setUserApiDuration">, setDataProcessingDuration: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/setDataProcessingDuration">,
|
|
158
|
+
export declare const setHerdModules: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/setHerdModules">, setStatus: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/setStatus">, setHerdModulesLoadingState: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/setHerdModulesLoadingState">, setHerdModulesLoadedInMs: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/setHerdModulesLoadedInMs">, setHerdModulesApiDuration: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/setHerdModulesApiDuration">, setUserApiDuration: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/setUserApiDuration">, setDataProcessingDuration: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/setDataProcessingDuration">, setActiveHerdId: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/setActiveHerdId">, setActiveDeviceId: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/setActiveDeviceId">, setDataSource: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/setDataSource">, setDataSourceInfo: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/setDataSourceInfo">, appendEventsToHerdModule: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/appendEventsToHerdModule">, replaceEventsForHerdModule: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/replaceEventsForHerdModule">, updateEventValuesForHerdModule: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/updateEventValuesForHerdModule">, updatePageIndexForHerdModule: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/updatePageIndexForHerdModule">, appendPlansToHerdModule: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/appendPlansToHerdModule">, setUser: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/setUser">, addTag: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/addTag">, deleteTag: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/deleteTag">, updateTag: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/updateTag">, addNewDeviceToHerdModule: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/addNewDeviceToHerdModule">, updateDeviceForHerdModule: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/updateDeviceForHerdModule">, addDevice: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/addDevice">, deleteDevice: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/deleteDevice">, updateDevice: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/updateDevice">, addPlan: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/addPlan">, deletePlan: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/deletePlan">, updatePlan: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/updatePlan">, addSessionToStore: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/addSessionToStore">, deleteSessionFromStore: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/deleteSessionFromStore">, updateSessionInStore: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/updateSessionInStore">, setActiveHerdGpsTrackersConnectivity: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/setActiveHerdGpsTrackersConnectivity">;
|
|
164
159
|
declare const _default: import("redux").Reducer<ScoutState>;
|
|
165
160
|
export default _default;
|
package/dist/store/scout.js
CHANGED
|
@@ -15,7 +15,6 @@ const initialState = {
|
|
|
15
15
|
herd_modules_api_duration_ms: null,
|
|
16
16
|
user_api_duration_ms: null,
|
|
17
17
|
data_processing_duration_ms: null,
|
|
18
|
-
localStorage_duration_ms: null,
|
|
19
18
|
lastRefreshed: 0,
|
|
20
19
|
active_herd_id: null,
|
|
21
20
|
active_device_id: null,
|
|
@@ -51,9 +50,6 @@ export const scoutSlice = createSlice({
|
|
|
51
50
|
setDataProcessingDuration: (state, action) => {
|
|
52
51
|
state.data_processing_duration_ms = action.payload;
|
|
53
52
|
},
|
|
54
|
-
setLocalStorageDuration: (state, action) => {
|
|
55
|
-
state.localStorage_duration_ms = action.payload;
|
|
56
|
-
},
|
|
57
53
|
setActiveHerdId: (state, action) => {
|
|
58
54
|
state.active_herd_id = action.payload;
|
|
59
55
|
state.active_herd_gps_trackers_connectivity = {};
|
|
@@ -269,5 +265,5 @@ export const scoutSlice = createSlice({
|
|
|
269
265
|
},
|
|
270
266
|
});
|
|
271
267
|
// Action creators are generated for each case reducer function
|
|
272
|
-
export const { setHerdModules, setStatus, setHerdModulesLoadingState, setHerdModulesLoadedInMs, setHerdModulesApiDuration, setUserApiDuration, setDataProcessingDuration,
|
|
268
|
+
export const { setHerdModules, setStatus, setHerdModulesLoadingState, setHerdModulesLoadedInMs, setHerdModulesApiDuration, setUserApiDuration, setDataProcessingDuration, setActiveHerdId, setActiveDeviceId, setDataSource, setDataSourceInfo, appendEventsToHerdModule, replaceEventsForHerdModule, updateEventValuesForHerdModule, updatePageIndexForHerdModule, appendPlansToHerdModule, setUser, addTag, deleteTag, updateTag, addNewDeviceToHerdModule, updateDeviceForHerdModule, addDevice, deleteDevice, updateDevice, addPlan, deletePlan, updatePlan, addSessionToStore, deleteSessionFromStore, updateSessionInStore, setActiveHerdGpsTrackersConnectivity, } = scoutSlice.actions;
|
|
273
269
|
export default scoutSlice.reducer;
|