@adventurelabs/scout-core 1.4.75 → 1.4.78

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.
@@ -30,112 +30,6 @@ export interface ScoutState {
30
30
  export interface RootState {
31
31
  scout: ScoutState;
32
32
  }
33
- export declare const scoutSlice: import("@reduxjs/toolkit").Slice<ScoutState, {
34
- setHerdModules: (state: import("immer").WritableDraft<ScoutState>, action: {
35
- payload: any;
36
- type: string;
37
- }) => void;
38
- setStatus: (state: import("immer").WritableDraft<ScoutState>, action: {
39
- payload: any;
40
- type: string;
41
- }) => void;
42
- setHerdModulesLoadingState: (state: import("immer").WritableDraft<ScoutState>, action: {
43
- payload: any;
44
- type: string;
45
- }) => void;
46
- setLoadingPerformance: (state: import("immer").WritableDraft<ScoutState>, action: {
47
- payload: any;
48
- type: string;
49
- }) => void;
50
- setHerdModulesLoadedInMs: (state: import("immer").WritableDraft<ScoutState>, action: {
51
- payload: any;
52
- type: string;
53
- }) => void;
54
- setHerdModulesApiServerProcessingDuration: (state: import("immer").WritableDraft<ScoutState>, action: {
55
- payload: any;
56
- type: string;
57
- }) => void;
58
- setHerdModulesApiTotalRequestDuration: (state: import("immer").WritableDraft<ScoutState>, action: {
59
- payload: any;
60
- type: string;
61
- }) => void;
62
- setUserApiDuration: (state: import("immer").WritableDraft<ScoutState>, action: {
63
- payload: any;
64
- type: string;
65
- }) => void;
66
- setDataProcessingDuration: (state: import("immer").WritableDraft<ScoutState>, action: {
67
- payload: any;
68
- type: string;
69
- }) => void;
70
- setCacheLoadDuration: (state: import("immer").WritableDraft<ScoutState>, action: {
71
- payload: any;
72
- type: string;
73
- }) => void;
74
- setActiveHerdId: (state: import("immer").WritableDraft<ScoutState>, action: {
75
- payload: any;
76
- type: string;
77
- }) => void;
78
- setActiveDeviceId: (state: import("immer").WritableDraft<ScoutState>, action: {
79
- payload: any;
80
- type: string;
81
- }) => void;
82
- setDataSource: (state: import("immer").WritableDraft<ScoutState>, action: {
83
- payload: any;
84
- type: string;
85
- }) => void;
86
- setDataSourceInfo: (state: import("immer").WritableDraft<ScoutState>, action: {
87
- payload: any;
88
- type: string;
89
- }) => void;
90
- updateSessionSummariesForHerdModule: (state: import("immer").WritableDraft<ScoutState>, action: {
91
- payload: any;
92
- type: string;
93
- }) => void;
94
- appendPlansToHerdModule: (state: import("immer").WritableDraft<ScoutState>, action: {
95
- payload: any;
96
- type: string;
97
- }) => void;
98
- updateDeviceForHerdModule: (state: import("immer").WritableDraft<ScoutState>, action: {
99
- payload: any;
100
- type: string;
101
- }) => void;
102
- addNewDeviceToHerdModule: (state: import("immer").WritableDraft<ScoutState>, action: {
103
- payload: any;
104
- type: string;
105
- }) => void;
106
- addDevice(state: import("immer").WritableDraft<ScoutState>, action: {
107
- payload: any;
108
- type: string;
109
- }): void;
110
- deleteDevice(state: import("immer").WritableDraft<ScoutState>, action: {
111
- payload: any;
112
- type: string;
113
- }): void;
114
- updateDevice(state: import("immer").WritableDraft<ScoutState>, action: {
115
- payload: any;
116
- type: string;
117
- }): void;
118
- addPlan(state: import("immer").WritableDraft<ScoutState>, action: {
119
- payload: any;
120
- type: string;
121
- }): void;
122
- deletePlan(state: import("immer").WritableDraft<ScoutState>, action: {
123
- payload: any;
124
- type: string;
125
- }): void;
126
- updatePlan(state: import("immer").WritableDraft<ScoutState>, action: {
127
- payload: any;
128
- type: string;
129
- }): void;
130
- setUser: (state: import("immer").WritableDraft<ScoutState>, action: {
131
- payload: any;
132
- type: string;
133
- }) => void;
134
- setActiveHerdGpsTrackersConnectivity: (state: import("immer").WritableDraft<ScoutState>, action: {
135
- payload: any;
136
- type: string;
137
- }) => void;
138
- }, "scout", "scout", import("@reduxjs/toolkit").SliceSelectors<ScoutState>>;
139
33
  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">, setLoadingPerformance: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/setLoadingPerformance">, setHerdModulesLoadedInMs: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/setHerdModulesLoadedInMs">, setHerdModulesApiServerProcessingDuration: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/setHerdModulesApiServerProcessingDuration">, setHerdModulesApiTotalRequestDuration: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/setHerdModulesApiTotalRequestDuration">, setUserApiDuration: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/setUserApiDuration">, setDataProcessingDuration: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/setDataProcessingDuration">, setCacheLoadDuration: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/setCacheLoadDuration">, 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">, updateSessionSummariesForHerdModule: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/updateSessionSummariesForHerdModule">, appendPlansToHerdModule: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/appendPlansToHerdModule">, setUser: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/setUser">, 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">, setActiveHerdGpsTrackersConnectivity: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/setActiveHerdGpsTrackersConnectivity">;
140
34
  declare const _default: import("redux").Reducer<ScoutState>;
141
35
  export default _default;
@@ -1,6 +1,7 @@
1
- import { createSlice } from "@reduxjs/toolkit";
1
+ import { createSlice, current } from "@reduxjs/toolkit";
2
2
  import { EnumHerdModulesLoadingState } from "../types/herd_module";
3
3
  import { EnumDataSource } from "../types/data_source";
4
+ import { herdModulesSemanticallyEqual } from "../helpers/herd_modules_equal";
4
5
  export var EnumScoutStateStatus;
5
6
  (function (EnumScoutStateStatus) {
6
7
  EnumScoutStateStatus["LOADING"] = "LOADING";
@@ -27,11 +28,14 @@ const initialState = {
27
28
  data_source_info: null,
28
29
  active_herd_gps_trackers_connectivity: {},
29
30
  };
30
- export const scoutSlice = createSlice({
31
+ const scoutSlice = createSlice({
31
32
  name: "scout",
32
33
  initialState,
33
34
  reducers: {
34
35
  setHerdModules: (state, action) => {
36
+ if (herdModulesSemanticallyEqual(current(state.herd_modules), action.payload)) {
37
+ return;
38
+ }
35
39
  state.herd_modules = action.payload;
36
40
  state.lastRefreshed = Date.now();
37
41
  },
@@ -1,10 +1,8 @@
1
- /** Herd entry inside a minted client abilities JWT (matches edge / RPC payload). */
2
1
  export interface IClientAbilitiesHerdClaim {
3
2
  herd_id: number;
4
3
  slug: string;
5
4
  abilities: string[];
6
5
  }
7
- /** Response from `mint-client-abilities-token`. */
8
6
  export interface IClientAbilitiesTokenMint {
9
7
  token: string;
10
8
  platform_superadmin: boolean;
@@ -12,13 +10,10 @@ export interface IClientAbilitiesTokenMint {
12
10
  iat: number;
13
11
  exp: number;
14
12
  }
15
- /** Entry from `get_client_abilities_jwt_public_keys()`. */
16
13
  export interface IClientAbilitiesJwtPublicKeyEntry {
17
14
  kid: string;
18
15
  jwk: Record<string, unknown>;
19
16
  }
20
17
  export declare const CLIENT_ABILITIES_JWT_AUDIENCE = "scout-client";
21
- /** Typical edge `CLIENT_ABILITIES_TOKEN_TTL_SEC` (scheduling uses JWT `exp` from mint). */
22
18
  export declare const CLIENT_ABILITIES_TOKEN_TTL_SEC = 3600;
23
- /** UI-only gate; RLS remains authoritative for data access. */
24
- export declare function can_herd_ability(mint: IClientAbilitiesTokenMint | null | undefined, herd_id: number, ability: string): boolean;
19
+ export declare function can_herd_ability(mint: IClientAbilitiesTokenMint | null | undefined, herd_id: number, ability: string, require_valid_expiry?: boolean): boolean;
@@ -1,11 +1,13 @@
1
1
  export const CLIENT_ABILITIES_JWT_AUDIENCE = "scout-client";
2
- /** Typical edge `CLIENT_ABILITIES_TOKEN_TTL_SEC` (scheduling uses JWT `exp` from mint). */
3
2
  export const CLIENT_ABILITIES_TOKEN_TTL_SEC = 3600;
4
- /** UI-only gate; RLS remains authoritative for data access. */
5
- export function can_herd_ability(mint, herd_id, ability) {
3
+ export function can_herd_ability(mint, herd_id, ability, require_valid_expiry = true) {
6
4
  if (!mint?.token) {
7
5
  return false;
8
6
  }
7
+ if (require_valid_expiry &&
8
+ mint.exp <= Math.floor(Date.now() / 1000)) {
9
+ return false;
10
+ }
9
11
  if (mint.platform_superadmin) {
10
12
  return true;
11
13
  }
@@ -0,0 +1,10 @@
1
+ export declare enum EnumJwtMintStatus {
2
+ IDLE = "idle",
3
+ LOADING = "loading",
4
+ REFRESHING = "refreshing",
5
+ READY = "ready",
6
+ ERROR = "error"
7
+ }
8
+ export declare function derive_jwt_mint_status(enabled: boolean, mint: {
9
+ token: string;
10
+ } | null | undefined, inFlight: boolean, error: string | null): EnumJwtMintStatus;
@@ -0,0 +1,26 @@
1
+ export var EnumJwtMintStatus;
2
+ (function (EnumJwtMintStatus) {
3
+ EnumJwtMintStatus["IDLE"] = "idle";
4
+ EnumJwtMintStatus["LOADING"] = "loading";
5
+ EnumJwtMintStatus["REFRESHING"] = "refreshing";
6
+ EnumJwtMintStatus["READY"] = "ready";
7
+ EnumJwtMintStatus["ERROR"] = "error";
8
+ })(EnumJwtMintStatus || (EnumJwtMintStatus = {}));
9
+ export function derive_jwt_mint_status(enabled, mint, inFlight, error) {
10
+ if (!enabled) {
11
+ return EnumJwtMintStatus.IDLE;
12
+ }
13
+ if (inFlight && !mint?.token) {
14
+ return EnumJwtMintStatus.LOADING;
15
+ }
16
+ if (inFlight && mint?.token) {
17
+ return EnumJwtMintStatus.REFRESHING;
18
+ }
19
+ if (error) {
20
+ return EnumJwtMintStatus.ERROR;
21
+ }
22
+ if (mint?.token) {
23
+ return EnumJwtMintStatus.READY;
24
+ }
25
+ return EnumJwtMintStatus.LOADING;
26
+ }
@@ -5,3 +5,8 @@ export interface IPubsubTokenMint {
5
5
  iat: number;
6
6
  exp: number;
7
7
  }
8
+ export interface IPubsubJwtPublicKeyEntry {
9
+ kid: string;
10
+ jwk: Record<string, unknown>;
11
+ }
12
+ export declare const PUBSUB_TOKEN_TTL_SEC = 3600;
@@ -1 +1 @@
1
- export {};
1
+ export const PUBSUB_TOKEN_TTL_SEC = 3600;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adventurelabs/scout-core",
3
- "version": "1.4.75",
3
+ "version": "1.4.78",
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",
@@ -46,6 +46,7 @@
46
46
  "@reduxjs/toolkit": "^2.0.0",
47
47
  "@supabase/ssr": "^0.7.0",
48
48
  "@supabase/supabase-js": "^2.57.4",
49
+ "@types/node": "^22.0.0",
49
50
  "@types/react": "^18.0.0",
50
51
  "@types/react-dom": "^18.0.0",
51
52
  "next": ">=15.0.0",
@@ -55,6 +56,7 @@
55
56
  "typescript": "^5.0.0"
56
57
  },
57
58
  "dependencies": {
59
+ "dequal": "^2.0.3",
58
60
  "jose": "5"
59
61
  }
60
62
  }