@adventurelabs/scout-core 1.4.84 → 1.4.86
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/api_keys/actions.d.ts +2 -1
- package/dist/api_keys/actions.js +2 -2
- package/dist/helpers/contacts.d.ts +10 -0
- package/dist/helpers/contacts.js +71 -0
- package/dist/helpers/document_templates.d.ts +7 -0
- package/dist/helpers/document_templates.js +63 -0
- package/dist/helpers/documents.d.ts +12 -0
- package/dist/helpers/documents.js +107 -0
- package/dist/helpers/herds.js +92 -13
- package/dist/helpers/index.d.ts +9 -1
- package/dist/helpers/index.js +9 -1
- package/dist/helpers/issuers.d.ts +7 -0
- package/dist/helpers/issuers.js +63 -0
- package/dist/helpers/layers.d.ts +3 -0
- package/dist/helpers/layers.js +20 -0
- package/dist/helpers/lifecycle.d.ts +2 -1
- package/dist/helpers/lifecycle.js +9 -0
- package/dist/helpers/localizations.d.ts +6 -0
- package/dist/helpers/localizations.js +51 -0
- package/dist/helpers/maintenance_requests.d.ts +15 -0
- package/dist/helpers/maintenance_requests.js +128 -0
- package/dist/helpers/manufacturers.d.ts +8 -0
- package/dist/helpers/manufacturers.js +52 -0
- package/dist/helpers/parts.d.ts +8 -1
- package/dist/helpers/parts.js +38 -0
- package/dist/helpers/plans.d.ts +3 -0
- package/dist/helpers/plans.js +20 -0
- package/dist/helpers/product_numbers.d.ts +7 -0
- package/dist/helpers/product_numbers.js +66 -0
- package/dist/helpers/products.d.ts +9 -0
- package/dist/helpers/products.js +65 -0
- package/dist/helpers/providers.d.ts +3 -0
- package/dist/helpers/providers.js +20 -0
- package/dist/helpers/users.d.ts +1 -0
- package/dist/helpers/users.js +30 -0
- package/dist/helpers/zones.d.ts +2 -1
- package/dist/helpers/zones.js +2 -2
- package/dist/hooks/useScoutRefresh.js +24 -8
- package/dist/index.d.ts +13 -3
- package/dist/index.js +11 -1
- package/dist/store/scout.d.ts +1 -0
- package/dist/store/scout.js +18 -2
- package/dist/types/db.d.ts +38 -4
- package/dist/types/herd_module.d.ts +2 -17
- package/dist/types/herd_module.js +0 -166
- package/dist/types/supabase.d.ts +686 -45
- package/dist/types/supabase.js +1 -0
- package/package.json +1 -1
|
@@ -136,6 +136,7 @@ export function useScoutRefresh(options = {}) {
|
|
|
136
136
|
dispatch(setStatus(EnumScoutStateStatus.LOADING));
|
|
137
137
|
dispatch(setHerdModulesLoadingState(EnumHerdModulesLoadingState.LOADING));
|
|
138
138
|
let cachedHerdModules = null;
|
|
139
|
+
let cachedContentHash;
|
|
139
140
|
let cacheLoadDuration = 0;
|
|
140
141
|
// Step 1: Load from cache first if enabled
|
|
141
142
|
if (cacheFirst) {
|
|
@@ -147,6 +148,7 @@ export function useScoutRefresh(options = {}) {
|
|
|
147
148
|
dispatch(setCacheLoadDuration(cacheLoadDuration));
|
|
148
149
|
if (cacheResult.data && cacheResult.data.length > 0) {
|
|
149
150
|
cachedHerdModules = cacheResult.data;
|
|
151
|
+
cachedContentHash = cacheResult.metadata?.etag;
|
|
150
152
|
console.log(`[useScoutRefresh] Loaded ${cachedHerdModules.length} herd modules from cache in ${cacheLoadDuration}ms (age: ${Math.round(cacheResult.age / 1000)}s, stale: ${cacheResult.isStale})`);
|
|
151
153
|
// Set data source to CACHE initially
|
|
152
154
|
dispatch(setDataSource(EnumDataSource.CACHE));
|
|
@@ -158,7 +160,10 @@ export function useScoutRefresh(options = {}) {
|
|
|
158
160
|
}));
|
|
159
161
|
// Update the store with cached data
|
|
160
162
|
console.log(`[useScoutRefresh] Updating store with cached herd modules`);
|
|
161
|
-
dispatchInTransition(dispatch, setHerdModules(
|
|
163
|
+
dispatchInTransition(dispatch, setHerdModules({
|
|
164
|
+
modules: cachedHerdModules,
|
|
165
|
+
contentHash: cachedContentHash,
|
|
166
|
+
}));
|
|
162
167
|
dispatch(setHerdModulesLoadingState(EnumHerdModulesLoadingState.SUCCESSFULLY_LOADED));
|
|
163
168
|
// If cache is fresh, we still background fetch but don't wait (only when online)
|
|
164
169
|
if (!cacheResult.isStale) {
|
|
@@ -193,21 +198,25 @@ export function useScoutRefresh(options = {}) {
|
|
|
193
198
|
EnumWebResponse.SUCCESS &&
|
|
194
199
|
Array.isArray(backgroundHerdModulesResult.data) &&
|
|
195
200
|
backgroundUserResult) {
|
|
201
|
+
const backgroundContentHash = backgroundHerdModulesResult.content_hash;
|
|
196
202
|
// Update cache with fresh data
|
|
197
203
|
try {
|
|
198
|
-
await scoutCache.setHerdModules(backgroundHerdModulesResult.data, cacheTtlMs);
|
|
204
|
+
await scoutCache.setHerdModules(backgroundHerdModulesResult.data, cacheTtlMs, backgroundContentHash);
|
|
199
205
|
}
|
|
200
206
|
catch (cacheError) {
|
|
201
207
|
console.warn("[useScoutRefresh] Background cache save failed:", cacheError);
|
|
202
208
|
await handleIndexedDbError(cacheError, "background cache save", async () => {
|
|
203
209
|
if (backgroundHerdModulesResult.data) {
|
|
204
|
-
await scoutCache.setHerdModules(backgroundHerdModulesResult.data, cacheTtlMs);
|
|
210
|
+
await scoutCache.setHerdModules(backgroundHerdModulesResult.data, cacheTtlMs, backgroundContentHash);
|
|
205
211
|
}
|
|
206
212
|
});
|
|
207
213
|
}
|
|
208
214
|
// Update store with fresh data from background request
|
|
209
215
|
console.log(`[useScoutRefresh] Updating store with background herd modules`);
|
|
210
|
-
dispatchInTransition(dispatch, setHerdModules(
|
|
216
|
+
dispatchInTransition(dispatch, setHerdModules({
|
|
217
|
+
modules: backgroundHerdModulesResult.data,
|
|
218
|
+
contentHash: backgroundContentHash,
|
|
219
|
+
}));
|
|
211
220
|
// Update data source to DATABASE
|
|
212
221
|
dispatch(setDataSource(EnumDataSource.DATABASE));
|
|
213
222
|
dispatch(setDataSourceInfo({
|
|
@@ -248,7 +257,10 @@ export function useScoutRefresh(options = {}) {
|
|
|
248
257
|
source: EnumDataSource.CACHE,
|
|
249
258
|
timestamp: Date.now(),
|
|
250
259
|
}));
|
|
251
|
-
dispatchInTransition(dispatch, setHerdModules(
|
|
260
|
+
dispatchInTransition(dispatch, setHerdModules({
|
|
261
|
+
modules: cachedHerdModules,
|
|
262
|
+
contentHash: cachedContentHash,
|
|
263
|
+
}));
|
|
252
264
|
dispatch(setHerdModulesLoadingState(EnumHerdModulesLoadingState.SUCCESSFULLY_LOADED));
|
|
253
265
|
}
|
|
254
266
|
else {
|
|
@@ -310,6 +322,7 @@ export function useScoutRefresh(options = {}) {
|
|
|
310
322
|
console.log(`[useScoutRefresh] Data validation took: ${validationDuration}ms`);
|
|
311
323
|
// Use the validated data
|
|
312
324
|
const compatible_new_herd_modules = herdModulesResponse.data;
|
|
325
|
+
const freshContentHash = herdModulesResponse.content_hash;
|
|
313
326
|
// Set data source to DATABASE
|
|
314
327
|
dispatch(setDataSource(EnumDataSource.DATABASE));
|
|
315
328
|
dispatch(setDataSourceInfo({
|
|
@@ -319,7 +332,7 @@ export function useScoutRefresh(options = {}) {
|
|
|
319
332
|
// Step 3: Update cache with fresh data
|
|
320
333
|
const cacheSaveStartTime = Date.now();
|
|
321
334
|
try {
|
|
322
|
-
await scoutCache.setHerdModules(compatible_new_herd_modules, cacheTtlMs);
|
|
335
|
+
await scoutCache.setHerdModules(compatible_new_herd_modules, cacheTtlMs, freshContentHash);
|
|
323
336
|
const cacheSaveDuration = Date.now() - cacheSaveStartTime;
|
|
324
337
|
timingRefs.current.cacheSaveDuration = cacheSaveDuration;
|
|
325
338
|
console.log(`[useScoutRefresh] Cache updated in ${cacheSaveDuration}ms with TTL: ${Math.round(cacheTtlMs / 1000)}s`);
|
|
@@ -327,14 +340,17 @@ export function useScoutRefresh(options = {}) {
|
|
|
327
340
|
catch (cacheError) {
|
|
328
341
|
console.warn("[useScoutRefresh] Cache save failed:", cacheError);
|
|
329
342
|
await handleIndexedDbError(cacheError, "cache save", async () => {
|
|
330
|
-
await scoutCache.setHerdModules(compatible_new_herd_modules, cacheTtlMs);
|
|
343
|
+
await scoutCache.setHerdModules(compatible_new_herd_modules, cacheTtlMs, freshContentHash);
|
|
331
344
|
});
|
|
332
345
|
}
|
|
333
346
|
// Step 4: Update store with fresh data (reducer skips no-op updates)
|
|
334
347
|
const dataProcessingStartTime = Date.now();
|
|
335
348
|
// Update store with new data
|
|
336
349
|
console.log(`[useScoutRefresh] Updating store with fresh herd modules`);
|
|
337
|
-
dispatchInTransition(dispatch, setHerdModules(
|
|
350
|
+
dispatchInTransition(dispatch, setHerdModules({
|
|
351
|
+
modules: compatible_new_herd_modules,
|
|
352
|
+
contentHash: freshContentHash,
|
|
353
|
+
}));
|
|
338
354
|
dispatch(setHerdModulesLoadingState(EnumHerdModulesLoadingState.SUCCESSFULLY_LOADED));
|
|
339
355
|
const dataProcessingDuration = Date.now() - dataProcessingStartTime;
|
|
340
356
|
timingRefs.current.dataProcessingDuration = dataProcessingDuration;
|
package/dist/index.d.ts
CHANGED
|
@@ -20,7 +20,8 @@ export * from "./helpers/bounding_boxes";
|
|
|
20
20
|
export * from "./helpers/chat";
|
|
21
21
|
export * from "./helpers/certificates";
|
|
22
22
|
export * from "./helpers/connectivity";
|
|
23
|
-
export * from "./helpers/
|
|
23
|
+
export * from "./helpers/user_credentials";
|
|
24
|
+
export * from "./helpers/herd_credentials";
|
|
24
25
|
export * from "./helpers/db";
|
|
25
26
|
export * from "./helpers/devices";
|
|
26
27
|
export * from "./helpers/email";
|
|
@@ -60,6 +61,15 @@ export * from "./helpers/operators";
|
|
|
60
61
|
export * from "./helpers/versions_software";
|
|
61
62
|
export * from "./helpers/versions_software_server";
|
|
62
63
|
export * from "./helpers/parts";
|
|
64
|
+
export * from "./helpers/manufacturers";
|
|
65
|
+
export * from "./helpers/products";
|
|
66
|
+
export * from "./helpers/product_numbers";
|
|
67
|
+
export * from "./helpers/localizations";
|
|
68
|
+
export * from "./helpers/issuers";
|
|
69
|
+
export * from "./helpers/document_templates";
|
|
70
|
+
export * from "./helpers/documents";
|
|
71
|
+
export * from "./helpers/maintenance_requests";
|
|
72
|
+
export * from "./helpers/contacts";
|
|
63
73
|
export * from "./helpers/lifecycle";
|
|
64
74
|
export * from "./helpers/storagePath";
|
|
65
75
|
export * from "./hooks/useScoutRealtimeConnectivity";
|
|
@@ -82,6 +92,6 @@ export * from "./store/api";
|
|
|
82
92
|
export * from "./supabase/middleware";
|
|
83
93
|
export * from "./supabase/server";
|
|
84
94
|
export * from "./api_keys/actions";
|
|
85
|
-
export type {
|
|
86
|
-
export type { IDevice, IEvent, IUser, IHerd, IHerdPrettyLocation, IEventWithTags, IZoneWithActions,
|
|
95
|
+
export type { IHerdModule } from "./types/herd_module";
|
|
96
|
+
export type { IDevice, IEvent, IUser, IHerd, IHerdPrettyLocation, IEventWithTags, IZoneWithActions, IPointsForUser, PointsForUserInsert, PointsForUserUpdate, ICertificate, CertificateInsert, CertificateUpdate, ILocalization, LocalizationInsert, LocalizationUpdate, IIssuer, IssuerInsert, IssuerUpdate, IDocumentTemplate, DocumentTemplateInsert, DocumentTemplateUpdate, IDocument, DocumentInsert, DocumentUpdate, IMaintenanceRequest, MaintenanceRequestInsert, MaintenanceRequestUpdate, IContact, ContactInsert, ContactUpdate, IUserAndRole, IUserProfileRow, IHerdInvitation, IHerdInvitationWithHerdSlug, IHerdAllowedDomain, IUserRolePerHerd, IAbility, IHerdRole, IHerdRoleWithAbilities, HerdRoleSystemName, HerdInvitationStatus, IApiKeyScout, ILayer, IHeartbeat, IProvider, IConnectivity, ISession, ISessionWithCoordinates, IConnectivityWithCoordinates, IObservation, ObservationInsert, ObservationUpdate, IAnalysisJob, IAnalysisTask, AnalysisWorkStatus, } from "./types/db";
|
|
87
97
|
export { EnumSessionsVisibility } from "./types/events";
|
package/dist/index.js
CHANGED
|
@@ -23,7 +23,8 @@ export * from "./helpers/bounding_boxes";
|
|
|
23
23
|
export * from "./helpers/chat";
|
|
24
24
|
export * from "./helpers/certificates";
|
|
25
25
|
export * from "./helpers/connectivity";
|
|
26
|
-
export * from "./helpers/
|
|
26
|
+
export * from "./helpers/user_credentials";
|
|
27
|
+
export * from "./helpers/herd_credentials";
|
|
27
28
|
export * from "./helpers/db";
|
|
28
29
|
export * from "./helpers/devices";
|
|
29
30
|
export * from "./helpers/email";
|
|
@@ -63,6 +64,15 @@ export * from "./helpers/operators";
|
|
|
63
64
|
export * from "./helpers/versions_software";
|
|
64
65
|
export * from "./helpers/versions_software_server";
|
|
65
66
|
export * from "./helpers/parts";
|
|
67
|
+
export * from "./helpers/manufacturers";
|
|
68
|
+
export * from "./helpers/products";
|
|
69
|
+
export * from "./helpers/product_numbers";
|
|
70
|
+
export * from "./helpers/localizations";
|
|
71
|
+
export * from "./helpers/issuers";
|
|
72
|
+
export * from "./helpers/document_templates";
|
|
73
|
+
export * from "./helpers/documents";
|
|
74
|
+
export * from "./helpers/maintenance_requests";
|
|
75
|
+
export * from "./helpers/contacts";
|
|
66
76
|
export * from "./helpers/lifecycle";
|
|
67
77
|
export * from "./helpers/storagePath";
|
|
68
78
|
// Hooks
|
package/dist/store/scout.d.ts
CHANGED
|
@@ -17,6 +17,7 @@ export interface LoadingPerformance {
|
|
|
17
17
|
}
|
|
18
18
|
export interface ScoutState {
|
|
19
19
|
herd_modules: IHerdModule[];
|
|
20
|
+
herd_modules_content_hash: string | null;
|
|
20
21
|
status: EnumScoutStateStatus;
|
|
21
22
|
herd_modules_loading_state: EnumHerdModulesLoadingState;
|
|
22
23
|
loading_performance: LoadingPerformance;
|
package/dist/store/scout.js
CHANGED
|
@@ -9,6 +9,7 @@ export var EnumScoutStateStatus;
|
|
|
9
9
|
})(EnumScoutStateStatus || (EnumScoutStateStatus = {}));
|
|
10
10
|
const initialState = {
|
|
11
11
|
herd_modules: [],
|
|
12
|
+
herd_modules_content_hash: null,
|
|
12
13
|
status: EnumScoutStateStatus.LOADING,
|
|
13
14
|
herd_modules_loading_state: EnumHerdModulesLoadingState.NOT_LOADING,
|
|
14
15
|
loading_performance: {
|
|
@@ -33,10 +34,25 @@ export const scoutSlice = createSlice({
|
|
|
33
34
|
initialState,
|
|
34
35
|
reducers: {
|
|
35
36
|
setHerdModules: (state, action) => {
|
|
36
|
-
|
|
37
|
+
// Payload is the modules array (legacy) or { modules, contentHash }.
|
|
38
|
+
const payload = action.payload;
|
|
39
|
+
const modules = Array.isArray(payload)
|
|
40
|
+
? payload
|
|
41
|
+
: payload.modules;
|
|
42
|
+
const contentHash = Array.isArray(payload)
|
|
43
|
+
? null
|
|
44
|
+
: payload.contentHash ?? null;
|
|
45
|
+
// Prefer the cheap hash check; fall back to deep compare when absent.
|
|
46
|
+
if (contentHash != null) {
|
|
47
|
+
if (state.herd_modules_content_hash === contentHash) {
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
else if (herdModulesSemanticallyEqual(current(state.herd_modules), modules)) {
|
|
37
52
|
return;
|
|
38
53
|
}
|
|
39
|
-
state.herd_modules =
|
|
54
|
+
state.herd_modules = modules;
|
|
55
|
+
state.herd_modules_content_hash = contentHash;
|
|
40
56
|
state.lastRefreshed = Date.now();
|
|
41
57
|
},
|
|
42
58
|
setStatus: (state, action) => {
|
package/dist/types/db.d.ts
CHANGED
|
@@ -13,7 +13,7 @@ export type IUserProfileRow = Database["public"]["Tables"]["users"]["Row"];
|
|
|
13
13
|
export type IDeviceRow = Database["public"]["Tables"]["devices"]["Row"];
|
|
14
14
|
export type IDevice = Database["public"]["CompositeTypes"]["device_pretty_location"] & {
|
|
15
15
|
api_keys_scout?: IApiKeyScout[];
|
|
16
|
-
parts?:
|
|
16
|
+
parts?: IPartWithProduct[];
|
|
17
17
|
};
|
|
18
18
|
export type IPin = Database["public"]["CompositeTypes"]["pins_pretty_location"];
|
|
19
19
|
export type IEvent = Database["public"]["Tables"]["events"]["Row"];
|
|
@@ -58,7 +58,21 @@ export type IOperator = Database["public"]["Tables"]["operators"]["Row"];
|
|
|
58
58
|
export type IObservation = Database["public"]["Tables"]["observations"]["Row"];
|
|
59
59
|
export type IProvider = Database["public"]["Tables"]["providers"]["Row"];
|
|
60
60
|
export type IPart = Database["public"]["Tables"]["parts"]["Row"];
|
|
61
|
-
export type
|
|
61
|
+
export type IManufacturer = Database["public"]["Tables"]["manufacturers"]["Row"];
|
|
62
|
+
export type IProduct = Database["public"]["Tables"]["products"]["Row"];
|
|
63
|
+
export type IProductNumber = Database["public"]["Tables"]["product_numbers"]["Row"];
|
|
64
|
+
export type ISensorPose = Database["public"]["Tables"]["sensor_poses"]["Row"];
|
|
65
|
+
export type ICalibration = Database["public"]["Tables"]["calibrations"]["Row"];
|
|
66
|
+
export type ILocalization = Database["public"]["Tables"]["localizations"]["Row"];
|
|
67
|
+
export type IIssuer = Database["public"]["Tables"]["issuers"]["Row"];
|
|
68
|
+
export type IDocumentTemplate = Database["public"]["Tables"]["document_templates"]["Row"];
|
|
69
|
+
export type IDocument = Database["public"]["Tables"]["documents"]["Row"];
|
|
70
|
+
export type IMaintenanceRequest = Database["public"]["Tables"]["maintenance_requests"]["Row"];
|
|
71
|
+
export type IContact = Database["public"]["Tables"]["contacts"]["Row"];
|
|
72
|
+
/** A part with its resolved product (parts.product_number -> product_numbers -> products). */
|
|
73
|
+
export type IPartWithProduct = IPart & {
|
|
74
|
+
product?: IProduct | null;
|
|
75
|
+
};
|
|
62
76
|
export type IUserCredential = Database["public"]["Tables"]["user_credentials"]["Row"];
|
|
63
77
|
export type IHerdCredential = Database["public"]["Tables"]["herd_credentials"]["Row"];
|
|
64
78
|
export type IPointsForUser = Database["public"]["Tables"]["points_for_user"]["Row"];
|
|
@@ -102,12 +116,32 @@ export interface ISessionSummary {
|
|
|
102
116
|
}
|
|
103
117
|
export type ISessionUsageOverTime = Database["public"]["Functions"]["get_session_usage_over_time"]["Returns"];
|
|
104
118
|
export type PartInsert = Database["public"]["Tables"]["parts"]["Insert"];
|
|
105
|
-
export type
|
|
106
|
-
export type
|
|
119
|
+
export type ManufacturerInsert = Database["public"]["Tables"]["manufacturers"]["Insert"];
|
|
120
|
+
export type ManufacturerUpdate = Database["public"]["Tables"]["manufacturers"]["Update"];
|
|
121
|
+
export type ProductInsert = Database["public"]["Tables"]["products"]["Insert"];
|
|
122
|
+
export type ProductUpdate = Database["public"]["Tables"]["products"]["Update"];
|
|
123
|
+
export type ProductNumberInsert = Database["public"]["Tables"]["product_numbers"]["Insert"];
|
|
124
|
+
export type ProductNumberUpdate = Database["public"]["Tables"]["product_numbers"]["Update"];
|
|
125
|
+
export type SensorPoseInsert = Database["public"]["Tables"]["sensor_poses"]["Insert"];
|
|
126
|
+
export type SensorPoseUpdate = Database["public"]["Tables"]["sensor_poses"]["Update"];
|
|
127
|
+
export type CalibrationInsert = Database["public"]["Tables"]["calibrations"]["Insert"];
|
|
128
|
+
export type CalibrationUpdate = Database["public"]["Tables"]["calibrations"]["Update"];
|
|
107
129
|
export type UserCredentialInsert = Database["public"]["Tables"]["user_credentials"]["Insert"];
|
|
108
130
|
export type UserCredentialUpdate = Database["public"]["Tables"]["user_credentials"]["Update"];
|
|
109
131
|
export type HerdCredentialInsert = Database["public"]["Tables"]["herd_credentials"]["Insert"];
|
|
110
132
|
export type HerdCredentialUpdate = Database["public"]["Tables"]["herd_credentials"]["Update"];
|
|
133
|
+
export type LocalizationInsert = Database["public"]["Tables"]["localizations"]["Insert"];
|
|
134
|
+
export type LocalizationUpdate = Database["public"]["Tables"]["localizations"]["Update"];
|
|
135
|
+
export type IssuerInsert = Database["public"]["Tables"]["issuers"]["Insert"];
|
|
136
|
+
export type IssuerUpdate = Database["public"]["Tables"]["issuers"]["Update"];
|
|
137
|
+
export type DocumentTemplateInsert = Database["public"]["Tables"]["document_templates"]["Insert"];
|
|
138
|
+
export type DocumentTemplateUpdate = Database["public"]["Tables"]["document_templates"]["Update"];
|
|
139
|
+
export type DocumentInsert = Database["public"]["Tables"]["documents"]["Insert"];
|
|
140
|
+
export type DocumentUpdate = Database["public"]["Tables"]["documents"]["Update"];
|
|
141
|
+
export type MaintenanceRequestInsert = Database["public"]["Tables"]["maintenance_requests"]["Insert"];
|
|
142
|
+
export type MaintenanceRequestUpdate = Database["public"]["Tables"]["maintenance_requests"]["Update"];
|
|
143
|
+
export type ContactInsert = Database["public"]["Tables"]["contacts"]["Insert"];
|
|
144
|
+
export type ContactUpdate = Database["public"]["Tables"]["contacts"]["Update"];
|
|
111
145
|
export interface CredentialQueryArgs {
|
|
112
146
|
type?: string;
|
|
113
147
|
}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { SupabaseClient } from "@supabase/supabase-js";
|
|
2
1
|
import { IDevice, IHerdPrettyLocation, IPlan, ILayer, IProvider, IUserAndRole, IZoneWithActions, ISessionSummary, ISessionUsageOverTime } from "../types/db";
|
|
3
2
|
import { EnumWebResponse } from "./requests";
|
|
4
3
|
export declare enum EnumHerdModulesLoadingState {
|
|
@@ -7,22 +6,6 @@ export declare enum EnumHerdModulesLoadingState {
|
|
|
7
6
|
SUCCESSFULLY_LOADED = "SUCCESSFULLY_LOADED",
|
|
8
7
|
UNSUCCESSFULLY_LOADED = "UNSUCCESSFULLY_LOADED"
|
|
9
8
|
}
|
|
10
|
-
export declare class HerdModule {
|
|
11
|
-
herd: IHerdPrettyLocation;
|
|
12
|
-
devices: IDevice[];
|
|
13
|
-
zones: IZoneWithActions[];
|
|
14
|
-
timestamp_last_refreshed: number;
|
|
15
|
-
user_roles: IUserAndRole[] | null;
|
|
16
|
-
labels: string[];
|
|
17
|
-
plans: IPlan[];
|
|
18
|
-
layers: ILayer[];
|
|
19
|
-
providers: IProvider[];
|
|
20
|
-
session_summaries: ISessionSummary | null;
|
|
21
|
-
session_usage: ISessionUsageOverTime | null;
|
|
22
|
-
constructor(herd: IHerdPrettyLocation, devices: IDevice[], timestamp_last_refreshed: number, user_roles?: IUserAndRole[] | null, labels?: string[], plans?: IPlan[], zones?: IZoneWithActions[], layers?: ILayer[], providers?: IProvider[], session_summaries?: ISessionSummary | null, session_usage?: ISessionUsageOverTime | null);
|
|
23
|
-
to_serializable(): IHerdModule;
|
|
24
|
-
static from_herd(herd: IHerdPrettyLocation, client: SupabaseClient): Promise<HerdModule>;
|
|
25
|
-
}
|
|
26
9
|
export interface IHerdModule {
|
|
27
10
|
herd: IHerdPrettyLocation;
|
|
28
11
|
devices: IDevice[];
|
|
@@ -40,6 +23,7 @@ export interface IHerdModulesResponse {
|
|
|
40
23
|
data: IHerdModule[];
|
|
41
24
|
time_finished: number;
|
|
42
25
|
server_processing_time_ms: number;
|
|
26
|
+
content_hash: string;
|
|
43
27
|
}
|
|
44
28
|
export interface IHerdModulesResponseWithStatus {
|
|
45
29
|
status: EnumWebResponse;
|
|
@@ -48,4 +32,5 @@ export interface IHerdModulesResponseWithStatus {
|
|
|
48
32
|
time_finished: number;
|
|
49
33
|
time_sent: number;
|
|
50
34
|
server_processing_time_ms: number;
|
|
35
|
+
content_hash: string;
|
|
51
36
|
}
|
|
@@ -1,15 +1,3 @@
|
|
|
1
|
-
import { LABELS } from "../constants/annotator";
|
|
2
|
-
import { get_devices_by_herd } from "../helpers/devices";
|
|
3
|
-
import { server_get_plans_by_herd } from "../helpers/plans";
|
|
4
|
-
import { server_get_layers_by_herd } from "../helpers/layers";
|
|
5
|
-
import { server_get_providers_by_herd } from "../helpers/providers";
|
|
6
|
-
import { server_get_users_with_herd_access } from "../helpers/users";
|
|
7
|
-
import { get_parts_by_herd_id } from "../helpers/parts";
|
|
8
|
-
import { EnumWebResponse } from "./requests";
|
|
9
|
-
import { server_get_more_zones_and_actions_for_herd } from "../helpers/zones";
|
|
10
|
-
import { server_list_api_keys_batch } from "../api_keys/actions";
|
|
11
|
-
import { server_get_session_summaries_by_herd } from "../helpers/session_summaries";
|
|
12
|
-
import { server_get_session_usage_over_time_by_herd } from "../helpers/sessions";
|
|
13
1
|
export var EnumHerdModulesLoadingState;
|
|
14
2
|
(function (EnumHerdModulesLoadingState) {
|
|
15
3
|
EnumHerdModulesLoadingState["NOT_LOADING"] = "NOT_LOADING";
|
|
@@ -17,157 +5,3 @@ export var EnumHerdModulesLoadingState;
|
|
|
17
5
|
EnumHerdModulesLoadingState["SUCCESSFULLY_LOADED"] = "SUCCESSFULLY_LOADED";
|
|
18
6
|
EnumHerdModulesLoadingState["UNSUCCESSFULLY_LOADED"] = "UNSUCCESSFULLY_LOADED";
|
|
19
7
|
})(EnumHerdModulesLoadingState || (EnumHerdModulesLoadingState = {}));
|
|
20
|
-
export class HerdModule {
|
|
21
|
-
constructor(herd, devices, timestamp_last_refreshed, user_roles = null, labels = [], plans = [], zones = [], layers = [], providers = [], session_summaries = null, session_usage = null) {
|
|
22
|
-
this.user_roles = null;
|
|
23
|
-
this.labels = [];
|
|
24
|
-
this.plans = [];
|
|
25
|
-
this.layers = [];
|
|
26
|
-
this.providers = [];
|
|
27
|
-
this.session_summaries = null;
|
|
28
|
-
this.session_usage = null;
|
|
29
|
-
this.herd = herd;
|
|
30
|
-
this.devices = devices;
|
|
31
|
-
this.timestamp_last_refreshed = timestamp_last_refreshed;
|
|
32
|
-
this.user_roles = user_roles;
|
|
33
|
-
this.labels = labels;
|
|
34
|
-
this.plans = plans;
|
|
35
|
-
this.zones = zones;
|
|
36
|
-
this.layers = layers;
|
|
37
|
-
this.providers = providers;
|
|
38
|
-
this.session_summaries = session_summaries;
|
|
39
|
-
this.session_usage = session_usage;
|
|
40
|
-
}
|
|
41
|
-
to_serializable() {
|
|
42
|
-
return {
|
|
43
|
-
herd: this.herd,
|
|
44
|
-
devices: this.devices,
|
|
45
|
-
timestamp_last_refreshed: this.timestamp_last_refreshed,
|
|
46
|
-
user_roles: this.user_roles,
|
|
47
|
-
labels: this.labels,
|
|
48
|
-
plans: this.plans,
|
|
49
|
-
zones: this.zones,
|
|
50
|
-
layers: this.layers,
|
|
51
|
-
providers: this.providers,
|
|
52
|
-
session_summaries: this.session_summaries,
|
|
53
|
-
session_usage: this.session_usage,
|
|
54
|
-
};
|
|
55
|
-
}
|
|
56
|
-
static async from_herd(herd, client) {
|
|
57
|
-
const startTime = Date.now();
|
|
58
|
-
try {
|
|
59
|
-
// Start loading herd-level data in parallel with devices
|
|
60
|
-
const herdLevelPromises = Promise.allSettled([
|
|
61
|
-
server_get_more_zones_and_actions_for_herd(herd.id, 0, 10).catch((error) => {
|
|
62
|
-
console.warn(`[HerdModule] Failed to get zones and actions:`, error);
|
|
63
|
-
return { status: EnumWebResponse.ERROR, data: null };
|
|
64
|
-
}),
|
|
65
|
-
server_get_users_with_herd_access(herd.id, client).catch((error) => {
|
|
66
|
-
console.warn(`[HerdModule] Failed to get user roles:`, error);
|
|
67
|
-
return { status: EnumWebResponse.ERROR, data: null };
|
|
68
|
-
}),
|
|
69
|
-
server_get_plans_by_herd(herd.id).catch((error) => {
|
|
70
|
-
console.warn(`[HerdModule] Failed to get plans:`, error);
|
|
71
|
-
return { status: EnumWebResponse.ERROR, data: null };
|
|
72
|
-
}),
|
|
73
|
-
server_get_layers_by_herd(herd.id).catch((error) => {
|
|
74
|
-
console.warn(`[HerdModule] Failed to get layers:`, error);
|
|
75
|
-
return { status: EnumWebResponse.ERROR, data: null };
|
|
76
|
-
}),
|
|
77
|
-
server_get_providers_by_herd(herd.id).catch((error) => {
|
|
78
|
-
console.warn(`[HerdModule] Failed to get providers:`, error);
|
|
79
|
-
return { status: EnumWebResponse.ERROR, data: null };
|
|
80
|
-
}),
|
|
81
|
-
server_get_session_summaries_by_herd(herd.id, client).catch((error) => {
|
|
82
|
-
console.warn(`[HerdModule] Failed to get session summaries:`, error);
|
|
83
|
-
return { status: EnumWebResponse.ERROR, data: null };
|
|
84
|
-
}),
|
|
85
|
-
server_get_session_usage_over_time_by_herd(herd.id, client).catch((error) => {
|
|
86
|
-
console.warn(`[HerdModule] Failed to get session usage:`, error);
|
|
87
|
-
return { status: EnumWebResponse.ERROR, data: null };
|
|
88
|
-
}),
|
|
89
|
-
]);
|
|
90
|
-
// Load devices and parts in parallel
|
|
91
|
-
const devicesPromise = get_devices_by_herd(herd.id, client);
|
|
92
|
-
const partsPromise = get_parts_by_herd_id(client, herd.id);
|
|
93
|
-
// Wait for devices, parts, and herd-level data
|
|
94
|
-
const [deviceResponse, partsResponse, herdLevelResults] = await Promise.all([devicesPromise, partsPromise, herdLevelPromises]);
|
|
95
|
-
// Check devices response
|
|
96
|
-
if (deviceResponse.status == EnumWebResponse.ERROR ||
|
|
97
|
-
!deviceResponse.data) {
|
|
98
|
-
console.warn(`[HerdModule] No devices found for herd ${herd.id}`);
|
|
99
|
-
return new HerdModule(herd, [], Date.now());
|
|
100
|
-
}
|
|
101
|
-
const new_devices = deviceResponse.data;
|
|
102
|
-
// Get parts data (optional - don't fail if parts can't be loaded)
|
|
103
|
-
let parts_data = [];
|
|
104
|
-
if (partsResponse.status !== EnumWebResponse.ERROR &&
|
|
105
|
-
partsResponse.data) {
|
|
106
|
-
parts_data = partsResponse.data;
|
|
107
|
-
}
|
|
108
|
-
else {
|
|
109
|
-
console.warn(`[HerdModule] Failed to load parts for herd ${herd.id}:`, partsResponse.status);
|
|
110
|
-
}
|
|
111
|
-
// Load API keys for devices if we have any
|
|
112
|
-
if (new_devices.length > 0) {
|
|
113
|
-
try {
|
|
114
|
-
const device_ids = new_devices.map((device) => device.id ?? 0);
|
|
115
|
-
const api_keys_batch = await server_list_api_keys_batch(device_ids);
|
|
116
|
-
// Assign API keys to devices
|
|
117
|
-
for (let i = 0; i < new_devices.length; i++) {
|
|
118
|
-
const device_id = new_devices[i].id ?? 0;
|
|
119
|
-
new_devices[i].api_keys_scout = api_keys_batch[device_id] || [];
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
catch (error) {
|
|
123
|
-
console.error(`[HerdModule] Failed to load API keys:`, error);
|
|
124
|
-
// Continue without API keys
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
// Associate parts with devices
|
|
128
|
-
if (parts_data.length > 0) {
|
|
129
|
-
for (const device of new_devices) {
|
|
130
|
-
device.parts = parts_data.filter((part) => part.device_id === device.id);
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
// Extract herd-level data with safe fallbacks
|
|
134
|
-
const [res_zones, res_user_roles, res_plans, res_layers, res_providers, session_summaries_result, session_usage_result,] = herdLevelResults;
|
|
135
|
-
const zones = res_zones.status === "fulfilled" && res_zones.value?.data
|
|
136
|
-
? res_zones.value.data
|
|
137
|
-
: [];
|
|
138
|
-
const user_roles = res_user_roles.status === "fulfilled" && res_user_roles.value?.data
|
|
139
|
-
? res_user_roles.value.data
|
|
140
|
-
: null;
|
|
141
|
-
const plans = res_plans.status === "fulfilled" && res_plans.value?.data
|
|
142
|
-
? res_plans.value.data
|
|
143
|
-
: [];
|
|
144
|
-
const layers = res_layers.status === "fulfilled" && res_layers.value?.data
|
|
145
|
-
? res_layers.value.data
|
|
146
|
-
: [];
|
|
147
|
-
const providers = res_providers.status === "fulfilled" && res_providers.value?.data
|
|
148
|
-
? res_providers.value.data
|
|
149
|
-
: [];
|
|
150
|
-
const session_summaries = session_summaries_result.status === "fulfilled" &&
|
|
151
|
-
session_summaries_result.value?.data
|
|
152
|
-
? session_summaries_result.value.data
|
|
153
|
-
: null;
|
|
154
|
-
const session_usage = session_usage_result.status === "fulfilled" &&
|
|
155
|
-
session_usage_result.value?.data
|
|
156
|
-
? session_usage_result.value.data
|
|
157
|
-
: null;
|
|
158
|
-
// TODO: store in DB and retrieve on load?
|
|
159
|
-
const newLabels = LABELS;
|
|
160
|
-
const endTime = Date.now();
|
|
161
|
-
const loadTime = endTime - startTime;
|
|
162
|
-
console.log(`[HerdModule] Loaded herd ${herd.slug} in ${loadTime}ms (${new_devices.length} devices)`);
|
|
163
|
-
return new HerdModule(herd, new_devices, Date.now(), user_roles, newLabels, plans, zones, layers, providers, session_summaries, session_usage);
|
|
164
|
-
}
|
|
165
|
-
catch (error) {
|
|
166
|
-
const endTime = Date.now();
|
|
167
|
-
const loadTime = endTime - startTime;
|
|
168
|
-
console.error(`[HerdModule] Critical error in HerdModule.from_herd (${loadTime}ms):`, error);
|
|
169
|
-
// Return a minimal but valid HerdModule instance to prevent complete failure
|
|
170
|
-
return new HerdModule(herd, [], Date.now(), null, [], [], [], [], [], null, null);
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
}
|