@adventurelabs/scout-core 1.0.59 → 1.0.61

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.
@@ -1,2 +1,2 @@
1
- export * from "./useScoutDbListener";
2
- export * from "./useScoutRefresh";
1
+ export { useScoutDbListener } from "./useScoutDbListener";
2
+ export { useScoutRefresh, type UseScoutRefreshOptions, } from "./useScoutRefresh";
@@ -1,2 +1,2 @@
1
- export * from "./useScoutDbListener";
2
- export * from "./useScoutRefresh";
1
+ export { useScoutDbListener } from "./useScoutDbListener";
2
+ export { useScoutRefresh, } from "./useScoutRefresh";
@@ -2,6 +2,37 @@ export interface UseScoutRefreshOptions {
2
2
  autoRefresh?: boolean;
3
3
  onRefreshComplete?: () => void;
4
4
  }
5
+ /**
6
+ * Hook for refreshing scout data with detailed timing measurements
7
+ *
8
+ * @param options - Configuration options for the refresh behavior
9
+ * @param options.autoRefresh - Whether to automatically refresh on mount (default: true)
10
+ * @param options.onRefreshComplete - Callback function called when refresh completes
11
+ *
12
+ * @returns Object containing:
13
+ * - handleRefresh: Function to manually trigger a refresh
14
+ * - getTimingStats: Function to get detailed timing statistics for the last refresh
15
+ *
16
+ * @example
17
+ * ```tsx
18
+ * const { handleRefresh, getTimingStats } = useScoutRefresh();
19
+ *
20
+ * // Get timing stats after a refresh
21
+ * const stats = getTimingStats();
22
+ * console.log('Herd modules API took:', stats.herdModulesApi, 'ms');
23
+ * console.log('User API took:', stats.userApi, 'ms');
24
+ * console.log('Data processing took:', stats.dataProcessing, 'ms');
25
+ * console.log('LocalStorage operations took:', stats.localStorage, 'ms');
26
+ * console.log('Total duration:', stats.totalDuration, 'ms');
27
+ * ```
28
+ */
5
29
  export declare function useScoutRefresh(options?: UseScoutRefreshOptions): {
6
30
  handleRefresh: () => Promise<void>;
31
+ getTimingStats: () => {
32
+ totalDuration: number;
33
+ herdModulesApi: number;
34
+ userApi: number;
35
+ dataProcessing: number;
36
+ localStorage: number;
37
+ };
7
38
  };
@@ -1,13 +1,45 @@
1
1
  import { useEffect, useCallback, useRef } from "react";
2
2
  import { useAppDispatch } from "../store/hooks";
3
- import { EnumScoutStateStatus, setActiveHerdId, setHerdModules, setStatus, setHerdModulesLoadingState, setHerdModulesLoadedInMs, setUser, } from "../store/scout";
3
+ import { EnumScoutStateStatus, setActiveHerdId, setHerdModules, setStatus, setHerdModulesLoadingState, setHerdModulesLoadedInMs, setHerdModulesApiDuration, setUserApiDuration, setDataProcessingDuration, setLocalStorageDuration, setUser, } from "../store/scout";
4
4
  import { EnumHerdModulesLoadingState } from "../types/herd_module";
5
5
  import { server_load_herd_modules } from "../helpers/herds";
6
6
  import { server_get_user } from "../helpers/users";
7
+ /**
8
+ * Hook for refreshing scout data with detailed timing measurements
9
+ *
10
+ * @param options - Configuration options for the refresh behavior
11
+ * @param options.autoRefresh - Whether to automatically refresh on mount (default: true)
12
+ * @param options.onRefreshComplete - Callback function called when refresh completes
13
+ *
14
+ * @returns Object containing:
15
+ * - handleRefresh: Function to manually trigger a refresh
16
+ * - getTimingStats: Function to get detailed timing statistics for the last refresh
17
+ *
18
+ * @example
19
+ * ```tsx
20
+ * const { handleRefresh, getTimingStats } = useScoutRefresh();
21
+ *
22
+ * // Get timing stats after a refresh
23
+ * const stats = getTimingStats();
24
+ * console.log('Herd modules API took:', stats.herdModulesApi, 'ms');
25
+ * console.log('User API took:', stats.userApi, 'ms');
26
+ * console.log('Data processing took:', stats.dataProcessing, 'ms');
27
+ * console.log('LocalStorage operations took:', stats.localStorage, 'ms');
28
+ * console.log('Total duration:', stats.totalDuration, 'ms');
29
+ * ```
30
+ */
7
31
  export function useScoutRefresh(options = {}) {
8
32
  const { autoRefresh = true, onRefreshComplete } = options;
9
33
  const dispatch = useAppDispatch();
10
34
  const refreshInProgressRef = useRef(false);
35
+ // Refs to store timing measurements
36
+ const timingRefs = useRef({
37
+ startTime: 0,
38
+ herdModulesDuration: 0,
39
+ userApiDuration: 0,
40
+ dataProcessingDuration: 0,
41
+ localStorageDuration: 0,
42
+ });
11
43
  const handleRefresh = useCallback(async () => {
12
44
  // Prevent concurrent refresh calls
13
45
  if (refreshInProgressRef.current) {
@@ -16,11 +48,48 @@ export function useScoutRefresh(options = {}) {
16
48
  }
17
49
  refreshInProgressRef.current = true;
18
50
  const startTime = Date.now();
51
+ timingRefs.current.startTime = startTime;
19
52
  try {
20
53
  dispatch(setStatus(EnumScoutStateStatus.LOADING));
21
54
  dispatch(setHerdModulesLoadingState(EnumHerdModulesLoadingState.LOADING));
22
- const compatible_new_herd_modules = await server_load_herd_modules();
23
- const res_new_user = await server_get_user();
55
+ // Run API requests in parallel for better performance
56
+ console.log("[useScoutRefresh] Starting parallel API requests...");
57
+ const parallelStartTime = Date.now();
58
+ const [herdModulesResult, userResult] = await Promise.all([
59
+ (async () => {
60
+ const start = Date.now();
61
+ const result = await server_load_herd_modules();
62
+ const duration = Date.now() - start;
63
+ return { result, duration, start };
64
+ })(),
65
+ (async () => {
66
+ const start = Date.now();
67
+ const result = await server_get_user();
68
+ const duration = Date.now() - start;
69
+ return { result, duration, start };
70
+ })(),
71
+ ]);
72
+ const parallelDuration = Date.now() - parallelStartTime;
73
+ console.log(`[useScoutRefresh] Parallel API requests completed in ${parallelDuration}ms`);
74
+ // Extract results and timing
75
+ const compatible_new_herd_modules = herdModulesResult.result;
76
+ const res_new_user = userResult.result;
77
+ const herdModulesDuration = herdModulesResult.duration;
78
+ const userApiDuration = userResult.duration;
79
+ // Store timing values
80
+ timingRefs.current.herdModulesDuration = herdModulesDuration;
81
+ timingRefs.current.userApiDuration = userApiDuration;
82
+ // Dispatch timing actions
83
+ dispatch(setHerdModulesApiDuration(herdModulesDuration));
84
+ dispatch(setUserApiDuration(userApiDuration));
85
+ // Calculate network overhead
86
+ const totalApiTime = herdModulesDuration + userApiDuration;
87
+ const networkOverhead = parallelDuration - Math.max(herdModulesDuration, userApiDuration);
88
+ console.log(`[useScoutRefresh] API timing breakdown:`);
89
+ console.log(` - Herd modules: ${herdModulesDuration}ms (server processing + network)`);
90
+ console.log(` - User API: ${userApiDuration}ms (server processing + network)`);
91
+ console.log(` - Parallel execution: ${parallelDuration}ms`);
92
+ console.log(` - Network overhead: ${networkOverhead}ms`);
24
93
  // Validate API responses
25
94
  if (!compatible_new_herd_modules ||
26
95
  !Array.isArray(compatible_new_herd_modules)) {
@@ -29,11 +98,16 @@ export function useScoutRefresh(options = {}) {
29
98
  if (!res_new_user || !res_new_user.data) {
30
99
  throw new Error("Invalid user response");
31
100
  }
32
- const loadingDuration = Date.now() - startTime;
101
+ // Measure data processing duration
102
+ const dataProcessingStartTime = Date.now();
33
103
  dispatch(setHerdModules(compatible_new_herd_modules));
34
104
  dispatch(setUser(res_new_user.data));
35
105
  dispatch(setHerdModulesLoadingState(EnumHerdModulesLoadingState.SUCCESSFULLY_LOADED));
36
- dispatch(setHerdModulesLoadedInMs(loadingDuration));
106
+ const dataProcessingDuration = Date.now() - dataProcessingStartTime;
107
+ timingRefs.current.dataProcessingDuration = dataProcessingDuration;
108
+ dispatch(setDataProcessingDuration(dataProcessingDuration));
109
+ // Measure localStorage operations duration
110
+ const localStorageStartTime = Date.now();
37
111
  // Safely handle localStorage operations
38
112
  try {
39
113
  // Check local storage for a last selected herd
@@ -59,7 +133,22 @@ export function useScoutRefresh(options = {}) {
59
133
  dispatch(setActiveHerdId(compatible_new_herd_modules[0].herd.id.toString()));
60
134
  }
61
135
  }
136
+ const localStorageDuration = Date.now() - localStorageStartTime;
137
+ timingRefs.current.localStorageDuration = localStorageDuration;
138
+ dispatch(setLocalStorageDuration(localStorageDuration));
139
+ const loadingDuration = Date.now() - startTime;
140
+ dispatch(setHerdModulesLoadedInMs(loadingDuration));
62
141
  dispatch(setStatus(EnumScoutStateStatus.DONE_LOADING));
142
+ // Log comprehensive timing statistics
143
+ console.log("[useScoutRefresh] Refresh completed successfully. Full timing breakdown:");
144
+ console.log(` - Herd modules API: ${herdModulesDuration}ms`);
145
+ console.log(` - User API: ${userApiDuration}ms`);
146
+ console.log(` - Parallel execution: ${parallelDuration}ms`);
147
+ console.log(` - Network overhead: ${networkOverhead}ms`);
148
+ console.log(` - Data processing: ${dataProcessingDuration}ms`);
149
+ console.log(` - LocalStorage operations: ${localStorageDuration}ms`);
150
+ console.log(` - Total duration: ${loadingDuration}ms`);
151
+ console.log(` - Time saved with parallel execution: ${totalApiTime - parallelDuration}ms`);
63
152
  onRefreshComplete?.();
64
153
  }
65
154
  catch (error) {
@@ -69,6 +158,13 @@ export function useScoutRefresh(options = {}) {
69
158
  dispatch(setHerdModulesLoadingState(EnumHerdModulesLoadingState.UNSUCCESSFULLY_LOADED));
70
159
  dispatch(setHerdModulesLoadedInMs(loadingDuration));
71
160
  dispatch(setStatus(EnumScoutStateStatus.DONE_LOADING));
161
+ // Log timing statistics even on error
162
+ console.log("[useScoutRefresh] Refresh failed. Partial timing breakdown:");
163
+ console.log(` - Herd modules API: ${timingRefs.current.herdModulesDuration}ms`);
164
+ console.log(` - User API: ${timingRefs.current.userApiDuration}ms`);
165
+ console.log(` - Data processing: ${timingRefs.current.dataProcessingDuration}ms`);
166
+ console.log(` - LocalStorage operations: ${timingRefs.current.localStorageDuration}ms`);
167
+ console.log(` - Total duration: ${loadingDuration}ms`);
72
168
  }
73
169
  finally {
74
170
  refreshInProgressRef.current = false;
@@ -79,7 +175,20 @@ export function useScoutRefresh(options = {}) {
79
175
  handleRefresh();
80
176
  }
81
177
  }, [autoRefresh, handleRefresh]);
178
+ // Utility function to get timing statistics
179
+ const getTimingStats = useCallback(() => {
180
+ const now = Date.now();
181
+ const startTime = timingRefs.current.startTime;
182
+ return {
183
+ totalDuration: startTime > 0 ? now - startTime : 0,
184
+ herdModulesApi: timingRefs.current.herdModulesDuration,
185
+ userApi: timingRefs.current.userApiDuration,
186
+ dataProcessing: timingRefs.current.dataProcessingDuration,
187
+ localStorage: timingRefs.current.localStorageDuration,
188
+ };
189
+ }, []);
82
190
  return {
83
191
  handleRefresh,
192
+ getTimingStats,
84
193
  };
85
194
  }
@@ -9,6 +9,10 @@ export interface ScoutState {
9
9
  status: EnumScoutStateStatus;
10
10
  herd_modules_loading_state: EnumHerdModulesLoadingState;
11
11
  herd_modules_loaded_in_ms: number | null;
12
+ herd_modules_api_duration_ms: number | null;
13
+ user_api_duration_ms: number | null;
14
+ data_processing_duration_ms: number | null;
15
+ localStorage_duration_ms: number | null;
12
16
  active_herd_id: string | null;
13
17
  active_device_id: string | null;
14
18
  lastRefreshed: number;
@@ -31,6 +35,22 @@ export declare const scoutSlice: import("@reduxjs/toolkit").Slice<ScoutState, {
31
35
  payload: any;
32
36
  type: string;
33
37
  }) => void;
38
+ setHerdModulesApiDuration: (state: import("immer").WritableDraft<ScoutState>, action: {
39
+ payload: any;
40
+ type: string;
41
+ }) => void;
42
+ setUserApiDuration: (state: import("immer").WritableDraft<ScoutState>, action: {
43
+ payload: any;
44
+ type: string;
45
+ }) => void;
46
+ setDataProcessingDuration: (state: import("immer").WritableDraft<ScoutState>, action: {
47
+ payload: any;
48
+ type: string;
49
+ }) => void;
50
+ setLocalStorageDuration: (state: import("immer").WritableDraft<ScoutState>, action: {
51
+ payload: any;
52
+ type: string;
53
+ }) => void;
34
54
  setActiveHerdId: (state: import("immer").WritableDraft<ScoutState>, action: {
35
55
  payload: any;
36
56
  type: string;
@@ -120,6 +140,6 @@ export declare const scoutSlice: import("@reduxjs/toolkit").Slice<ScoutState, {
120
140
  type: string;
121
141
  }) => void;
122
142
  }, "scout", "scout", import("@reduxjs/toolkit").SliceSelectors<ScoutState>>;
123
- 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">, setActiveHerdId: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/setActiveHerdId">, setActiveDeviceId: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/setActiveDeviceId">, 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">;
143
+ 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">, setLocalStorageDuration: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/setLocalStorageDuration">, setActiveHerdId: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/setActiveHerdId">, setActiveDeviceId: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/setActiveDeviceId">, 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">;
124
144
  declare const _default: import("redux").Reducer<ScoutState>;
125
145
  export default _default;
@@ -10,6 +10,11 @@ const initialState = {
10
10
  status: EnumScoutStateStatus.LOADING,
11
11
  herd_modules_loading_state: EnumHerdModulesLoadingState.NOT_LOADING,
12
12
  herd_modules_loaded_in_ms: null,
13
+ // Initialize timing variables
14
+ herd_modules_api_duration_ms: null,
15
+ user_api_duration_ms: null,
16
+ data_processing_duration_ms: null,
17
+ localStorage_duration_ms: null,
13
18
  lastRefreshed: 0,
14
19
  active_herd_id: null,
15
20
  active_device_id: null,
@@ -32,6 +37,18 @@ export const scoutSlice = createSlice({
32
37
  setHerdModulesLoadedInMs: (state, action) => {
33
38
  state.herd_modules_loaded_in_ms = action.payload;
34
39
  },
40
+ setHerdModulesApiDuration: (state, action) => {
41
+ state.herd_modules_api_duration_ms = action.payload;
42
+ },
43
+ setUserApiDuration: (state, action) => {
44
+ state.user_api_duration_ms = action.payload;
45
+ },
46
+ setDataProcessingDuration: (state, action) => {
47
+ state.data_processing_duration_ms = action.payload;
48
+ },
49
+ setLocalStorageDuration: (state, action) => {
50
+ state.localStorage_duration_ms = action.payload;
51
+ },
35
52
  setActiveHerdId: (state, action) => {
36
53
  state.active_herd_id = action.payload;
37
54
  },
@@ -237,5 +254,5 @@ export const scoutSlice = createSlice({
237
254
  },
238
255
  });
239
256
  // Action creators are generated for each case reducer function
240
- export const { setHerdModules, setStatus, setHerdModulesLoadingState, setHerdModulesLoadedInMs, setActiveHerdId, setActiveDeviceId, appendEventsToHerdModule, replaceEventsForHerdModule, updateEventValuesForHerdModule, updatePageIndexForHerdModule, appendPlansToHerdModule, setUser, addTag, deleteTag, updateTag, addNewDeviceToHerdModule, updateDeviceForHerdModule, addDevice, deleteDevice, updateDevice, addPlan, deletePlan, updatePlan, addSessionToStore, deleteSessionFromStore, updateSessionInStore, } = scoutSlice.actions;
257
+ export const { setHerdModules, setStatus, setHerdModulesLoadingState, setHerdModulesLoadedInMs, setHerdModulesApiDuration, setUserApiDuration, setDataProcessingDuration, setLocalStorageDuration, setActiveHerdId, setActiveDeviceId, appendEventsToHerdModule, replaceEventsForHerdModule, updateEventValuesForHerdModule, updatePageIndexForHerdModule, appendPlansToHerdModule, setUser, addTag, deleteTag, updateTag, addNewDeviceToHerdModule, updateDeviceForHerdModule, addDevice, deleteDevice, updateDevice, addPlan, deletePlan, updatePlan, addSessionToStore, deleteSessionFromStore, updateSessionInStore, } = scoutSlice.actions;
241
258
  export default scoutSlice.reducer;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adventurelabs/scout-core",
3
- "version": "1.0.59",
3
+ "version": "1.0.61",
4
4
  "description": "Core utilities and helpers for Adventure Labs Scout applications",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",