@clarityops/preferences 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +204 -0
- package/dist/index.d.ts +204 -0
- package/dist/index.js +625 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +596 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +42 -0
- package/src/PreferencesContext.tsx +309 -0
- package/src/PreferencesService.ts +443 -0
- package/src/avatar-cache.ts +55 -0
- package/src/index.ts +38 -0
- package/src/types.ts +94 -0
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import { ReactNode } from 'react';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* User preferences types shared across InsightForge and InsightFlow
|
|
6
|
+
*/
|
|
7
|
+
interface AnalysisCenterFilterPreset {
|
|
8
|
+
id: string;
|
|
9
|
+
name: string;
|
|
10
|
+
pattern: 'one_time' | 'recurring_structured' | 'continuous_monitoring';
|
|
11
|
+
category: string | null;
|
|
12
|
+
depth: 'quick_scan' | 'deep_dive' | null;
|
|
13
|
+
createdAt: string;
|
|
14
|
+
}
|
|
15
|
+
interface UserPreferences {
|
|
16
|
+
theme?: 'light' | 'dark' | 'system';
|
|
17
|
+
avatar_url?: string;
|
|
18
|
+
locale?: string;
|
|
19
|
+
notification_settings?: {
|
|
20
|
+
email?: boolean;
|
|
21
|
+
push?: boolean;
|
|
22
|
+
sound?: boolean;
|
|
23
|
+
sound_volume?: number;
|
|
24
|
+
};
|
|
25
|
+
sidebar_collapsed?: boolean;
|
|
26
|
+
default_client_id?: string;
|
|
27
|
+
timezone?: string;
|
|
28
|
+
avatar_updated_at?: string;
|
|
29
|
+
avatar_storage_path?: string;
|
|
30
|
+
show_demo_companies?: boolean;
|
|
31
|
+
analysis_center_filter_presets?: AnalysisCenterFilterPreset[];
|
|
32
|
+
/** Show WebSocket debug panel for connection troubleshooting (platform admins only) */
|
|
33
|
+
show_ws_debug_panel?: boolean;
|
|
34
|
+
}
|
|
35
|
+
interface AvatarData {
|
|
36
|
+
avatarUrl: string | null;
|
|
37
|
+
hasAvatar: boolean;
|
|
38
|
+
loading: boolean;
|
|
39
|
+
error: string | null;
|
|
40
|
+
refresh: () => Promise<void>;
|
|
41
|
+
handleImageError: () => void;
|
|
42
|
+
}
|
|
43
|
+
interface PrepareAvatarUploadResponse {
|
|
44
|
+
upload_id: string;
|
|
45
|
+
user_id: string;
|
|
46
|
+
upload_url: string;
|
|
47
|
+
storage_path: string;
|
|
48
|
+
expires_at: string;
|
|
49
|
+
max_size_bytes: number;
|
|
50
|
+
allowed_types: string[];
|
|
51
|
+
}
|
|
52
|
+
interface ConfirmAvatarUploadResponse {
|
|
53
|
+
user_id: string;
|
|
54
|
+
avatar_url: string;
|
|
55
|
+
file_size_bytes: number;
|
|
56
|
+
storage_path: string;
|
|
57
|
+
}
|
|
58
|
+
interface MyAvatarResponse {
|
|
59
|
+
user_id: string;
|
|
60
|
+
has_avatar: boolean;
|
|
61
|
+
avatar_url: string | null;
|
|
62
|
+
expires_at?: string;
|
|
63
|
+
cache_max_age_seconds?: number;
|
|
64
|
+
}
|
|
65
|
+
interface PreferencesConfig {
|
|
66
|
+
apiBaseUrl: string;
|
|
67
|
+
brandingUrl: string;
|
|
68
|
+
getToken: () => string | null;
|
|
69
|
+
/** Called when token is invalid/expired to attempt refresh */
|
|
70
|
+
onTokenInvalid?: () => Promise<string | null>;
|
|
71
|
+
}
|
|
72
|
+
interface PreferencesContextValue {
|
|
73
|
+
preferences: UserPreferences;
|
|
74
|
+
loading: boolean;
|
|
75
|
+
error: string | null;
|
|
76
|
+
avatar: AvatarData;
|
|
77
|
+
updatePreferences: (prefs: Partial<UserPreferences>) => Promise<void>;
|
|
78
|
+
refreshPreferences: () => Promise<void>;
|
|
79
|
+
uploadAvatar: (file: File) => Promise<string>;
|
|
80
|
+
clearAvatarCache: (userId?: string) => void;
|
|
81
|
+
/** Sync preferences on login and apply theme immediately */
|
|
82
|
+
syncOnLogin: () => Promise<void>;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
interface PreferencesProviderProps {
|
|
86
|
+
children: ReactNode;
|
|
87
|
+
config: PreferencesConfig;
|
|
88
|
+
/** Optional initial preferences to avoid loading state */
|
|
89
|
+
initialPreferences?: UserPreferences;
|
|
90
|
+
}
|
|
91
|
+
declare function PreferencesProvider({ children, config, initialPreferences, }: PreferencesProviderProps): react_jsx_runtime.JSX.Element;
|
|
92
|
+
/**
|
|
93
|
+
* Hook to access preferences context
|
|
94
|
+
* Throws if used outside PreferencesProvider
|
|
95
|
+
*/
|
|
96
|
+
declare function usePreferences(): PreferencesContextValue;
|
|
97
|
+
/**
|
|
98
|
+
* Hook to safely access preferences context
|
|
99
|
+
* Returns null if used outside PreferencesProvider (useful during hot reload)
|
|
100
|
+
*/
|
|
101
|
+
declare function usePreferencesSafe(): PreferencesContextValue | null;
|
|
102
|
+
/**
|
|
103
|
+
* Hook to access just avatar data
|
|
104
|
+
*/
|
|
105
|
+
declare function useAvatar(): AvatarData;
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Service class for user preferences and avatar management
|
|
109
|
+
* Shared across InsightForge and InsightFlow platforms
|
|
110
|
+
*/
|
|
111
|
+
declare class PreferencesService {
|
|
112
|
+
private baseUrl;
|
|
113
|
+
private brandingUrl;
|
|
114
|
+
private getToken;
|
|
115
|
+
private onTokenInvalid?;
|
|
116
|
+
constructor(config: PreferencesConfig);
|
|
117
|
+
/**
|
|
118
|
+
* Update the config (e.g., when token changes)
|
|
119
|
+
*/
|
|
120
|
+
updateConfig(config: Partial<PreferencesConfig>): void;
|
|
121
|
+
/**
|
|
122
|
+
* Refresh token with debounce to prevent multiple simultaneous refresh attempts
|
|
123
|
+
*/
|
|
124
|
+
private refreshWithDebounce;
|
|
125
|
+
/**
|
|
126
|
+
* Get a valid token, refreshing if necessary with debounce protection
|
|
127
|
+
*/
|
|
128
|
+
private getValidToken;
|
|
129
|
+
private request;
|
|
130
|
+
/**
|
|
131
|
+
* Get user preferences
|
|
132
|
+
*/
|
|
133
|
+
getPreferences(): Promise<{
|
|
134
|
+
data: {
|
|
135
|
+
preferences: UserPreferences;
|
|
136
|
+
};
|
|
137
|
+
}>;
|
|
138
|
+
/**
|
|
139
|
+
* Update preferences (merge update)
|
|
140
|
+
*/
|
|
141
|
+
updatePreferences(preferences: Partial<UserPreferences>): Promise<{
|
|
142
|
+
data: {
|
|
143
|
+
preferences: UserPreferences;
|
|
144
|
+
};
|
|
145
|
+
message?: string;
|
|
146
|
+
}>;
|
|
147
|
+
/**
|
|
148
|
+
* Replace all preferences
|
|
149
|
+
*/
|
|
150
|
+
replacePreferences(preferences: UserPreferences): Promise<{
|
|
151
|
+
data: {
|
|
152
|
+
preferences: UserPreferences;
|
|
153
|
+
};
|
|
154
|
+
message?: string;
|
|
155
|
+
}>;
|
|
156
|
+
/**
|
|
157
|
+
* Step 1: Prepare avatar upload - get signed URL for GCS
|
|
158
|
+
*/
|
|
159
|
+
prepareAvatarUpload(filename: string, mimeType: string): Promise<PrepareAvatarUploadResponse>;
|
|
160
|
+
/**
|
|
161
|
+
* Step 2: Upload file directly to GCS
|
|
162
|
+
*/
|
|
163
|
+
uploadToGCS(uploadUrl: string, file: File): Promise<void>;
|
|
164
|
+
/**
|
|
165
|
+
* Step 3: Confirm avatar upload
|
|
166
|
+
*/
|
|
167
|
+
confirmAvatarUpload(storagePath: string): Promise<ConfirmAvatarUploadResponse>;
|
|
168
|
+
/**
|
|
169
|
+
* Get current user's avatar
|
|
170
|
+
*/
|
|
171
|
+
getMyAvatar(): Promise<MyAvatarResponse>;
|
|
172
|
+
/**
|
|
173
|
+
* Get any user's avatar
|
|
174
|
+
*/
|
|
175
|
+
getUserAvatar(userId: string): Promise<MyAvatarResponse>;
|
|
176
|
+
/**
|
|
177
|
+
* Complete avatar upload flow (3-step process)
|
|
178
|
+
*/
|
|
179
|
+
uploadAvatar(file: File): Promise<string>;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* In-memory cache for avatar URLs
|
|
184
|
+
* Shared across all components using the preferences context
|
|
185
|
+
*/
|
|
186
|
+
declare const AVATAR_CACHE_TTL: number;
|
|
187
|
+
/**
|
|
188
|
+
* Get cached avatar URL if valid
|
|
189
|
+
*/
|
|
190
|
+
declare function getCachedAvatar(userId: string): string | null;
|
|
191
|
+
/**
|
|
192
|
+
* Set avatar URL in cache
|
|
193
|
+
*/
|
|
194
|
+
declare function setCachedAvatar(userId: string, url: string): void;
|
|
195
|
+
/**
|
|
196
|
+
* Clear cached avatar for a specific user or all users
|
|
197
|
+
*/
|
|
198
|
+
declare function clearAvatarCache(userId?: string): void;
|
|
199
|
+
/**
|
|
200
|
+
* Check if cache entry exists and is valid
|
|
201
|
+
*/
|
|
202
|
+
declare function hasCachedAvatar(userId: string): boolean;
|
|
203
|
+
|
|
204
|
+
export { AVATAR_CACHE_TTL, type AvatarData, type ConfirmAvatarUploadResponse, type MyAvatarResponse, type PreferencesConfig, type PreferencesContextValue, PreferencesProvider, type PreferencesProviderProps, PreferencesService, type PrepareAvatarUploadResponse, type UserPreferences, clearAvatarCache, getCachedAvatar, hasCachedAvatar, setCachedAvatar, useAvatar, usePreferences, usePreferencesSafe };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import { ReactNode } from 'react';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* User preferences types shared across InsightForge and InsightFlow
|
|
6
|
+
*/
|
|
7
|
+
interface AnalysisCenterFilterPreset {
|
|
8
|
+
id: string;
|
|
9
|
+
name: string;
|
|
10
|
+
pattern: 'one_time' | 'recurring_structured' | 'continuous_monitoring';
|
|
11
|
+
category: string | null;
|
|
12
|
+
depth: 'quick_scan' | 'deep_dive' | null;
|
|
13
|
+
createdAt: string;
|
|
14
|
+
}
|
|
15
|
+
interface UserPreferences {
|
|
16
|
+
theme?: 'light' | 'dark' | 'system';
|
|
17
|
+
avatar_url?: string;
|
|
18
|
+
locale?: string;
|
|
19
|
+
notification_settings?: {
|
|
20
|
+
email?: boolean;
|
|
21
|
+
push?: boolean;
|
|
22
|
+
sound?: boolean;
|
|
23
|
+
sound_volume?: number;
|
|
24
|
+
};
|
|
25
|
+
sidebar_collapsed?: boolean;
|
|
26
|
+
default_client_id?: string;
|
|
27
|
+
timezone?: string;
|
|
28
|
+
avatar_updated_at?: string;
|
|
29
|
+
avatar_storage_path?: string;
|
|
30
|
+
show_demo_companies?: boolean;
|
|
31
|
+
analysis_center_filter_presets?: AnalysisCenterFilterPreset[];
|
|
32
|
+
/** Show WebSocket debug panel for connection troubleshooting (platform admins only) */
|
|
33
|
+
show_ws_debug_panel?: boolean;
|
|
34
|
+
}
|
|
35
|
+
interface AvatarData {
|
|
36
|
+
avatarUrl: string | null;
|
|
37
|
+
hasAvatar: boolean;
|
|
38
|
+
loading: boolean;
|
|
39
|
+
error: string | null;
|
|
40
|
+
refresh: () => Promise<void>;
|
|
41
|
+
handleImageError: () => void;
|
|
42
|
+
}
|
|
43
|
+
interface PrepareAvatarUploadResponse {
|
|
44
|
+
upload_id: string;
|
|
45
|
+
user_id: string;
|
|
46
|
+
upload_url: string;
|
|
47
|
+
storage_path: string;
|
|
48
|
+
expires_at: string;
|
|
49
|
+
max_size_bytes: number;
|
|
50
|
+
allowed_types: string[];
|
|
51
|
+
}
|
|
52
|
+
interface ConfirmAvatarUploadResponse {
|
|
53
|
+
user_id: string;
|
|
54
|
+
avatar_url: string;
|
|
55
|
+
file_size_bytes: number;
|
|
56
|
+
storage_path: string;
|
|
57
|
+
}
|
|
58
|
+
interface MyAvatarResponse {
|
|
59
|
+
user_id: string;
|
|
60
|
+
has_avatar: boolean;
|
|
61
|
+
avatar_url: string | null;
|
|
62
|
+
expires_at?: string;
|
|
63
|
+
cache_max_age_seconds?: number;
|
|
64
|
+
}
|
|
65
|
+
interface PreferencesConfig {
|
|
66
|
+
apiBaseUrl: string;
|
|
67
|
+
brandingUrl: string;
|
|
68
|
+
getToken: () => string | null;
|
|
69
|
+
/** Called when token is invalid/expired to attempt refresh */
|
|
70
|
+
onTokenInvalid?: () => Promise<string | null>;
|
|
71
|
+
}
|
|
72
|
+
interface PreferencesContextValue {
|
|
73
|
+
preferences: UserPreferences;
|
|
74
|
+
loading: boolean;
|
|
75
|
+
error: string | null;
|
|
76
|
+
avatar: AvatarData;
|
|
77
|
+
updatePreferences: (prefs: Partial<UserPreferences>) => Promise<void>;
|
|
78
|
+
refreshPreferences: () => Promise<void>;
|
|
79
|
+
uploadAvatar: (file: File) => Promise<string>;
|
|
80
|
+
clearAvatarCache: (userId?: string) => void;
|
|
81
|
+
/** Sync preferences on login and apply theme immediately */
|
|
82
|
+
syncOnLogin: () => Promise<void>;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
interface PreferencesProviderProps {
|
|
86
|
+
children: ReactNode;
|
|
87
|
+
config: PreferencesConfig;
|
|
88
|
+
/** Optional initial preferences to avoid loading state */
|
|
89
|
+
initialPreferences?: UserPreferences;
|
|
90
|
+
}
|
|
91
|
+
declare function PreferencesProvider({ children, config, initialPreferences, }: PreferencesProviderProps): react_jsx_runtime.JSX.Element;
|
|
92
|
+
/**
|
|
93
|
+
* Hook to access preferences context
|
|
94
|
+
* Throws if used outside PreferencesProvider
|
|
95
|
+
*/
|
|
96
|
+
declare function usePreferences(): PreferencesContextValue;
|
|
97
|
+
/**
|
|
98
|
+
* Hook to safely access preferences context
|
|
99
|
+
* Returns null if used outside PreferencesProvider (useful during hot reload)
|
|
100
|
+
*/
|
|
101
|
+
declare function usePreferencesSafe(): PreferencesContextValue | null;
|
|
102
|
+
/**
|
|
103
|
+
* Hook to access just avatar data
|
|
104
|
+
*/
|
|
105
|
+
declare function useAvatar(): AvatarData;
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Service class for user preferences and avatar management
|
|
109
|
+
* Shared across InsightForge and InsightFlow platforms
|
|
110
|
+
*/
|
|
111
|
+
declare class PreferencesService {
|
|
112
|
+
private baseUrl;
|
|
113
|
+
private brandingUrl;
|
|
114
|
+
private getToken;
|
|
115
|
+
private onTokenInvalid?;
|
|
116
|
+
constructor(config: PreferencesConfig);
|
|
117
|
+
/**
|
|
118
|
+
* Update the config (e.g., when token changes)
|
|
119
|
+
*/
|
|
120
|
+
updateConfig(config: Partial<PreferencesConfig>): void;
|
|
121
|
+
/**
|
|
122
|
+
* Refresh token with debounce to prevent multiple simultaneous refresh attempts
|
|
123
|
+
*/
|
|
124
|
+
private refreshWithDebounce;
|
|
125
|
+
/**
|
|
126
|
+
* Get a valid token, refreshing if necessary with debounce protection
|
|
127
|
+
*/
|
|
128
|
+
private getValidToken;
|
|
129
|
+
private request;
|
|
130
|
+
/**
|
|
131
|
+
* Get user preferences
|
|
132
|
+
*/
|
|
133
|
+
getPreferences(): Promise<{
|
|
134
|
+
data: {
|
|
135
|
+
preferences: UserPreferences;
|
|
136
|
+
};
|
|
137
|
+
}>;
|
|
138
|
+
/**
|
|
139
|
+
* Update preferences (merge update)
|
|
140
|
+
*/
|
|
141
|
+
updatePreferences(preferences: Partial<UserPreferences>): Promise<{
|
|
142
|
+
data: {
|
|
143
|
+
preferences: UserPreferences;
|
|
144
|
+
};
|
|
145
|
+
message?: string;
|
|
146
|
+
}>;
|
|
147
|
+
/**
|
|
148
|
+
* Replace all preferences
|
|
149
|
+
*/
|
|
150
|
+
replacePreferences(preferences: UserPreferences): Promise<{
|
|
151
|
+
data: {
|
|
152
|
+
preferences: UserPreferences;
|
|
153
|
+
};
|
|
154
|
+
message?: string;
|
|
155
|
+
}>;
|
|
156
|
+
/**
|
|
157
|
+
* Step 1: Prepare avatar upload - get signed URL for GCS
|
|
158
|
+
*/
|
|
159
|
+
prepareAvatarUpload(filename: string, mimeType: string): Promise<PrepareAvatarUploadResponse>;
|
|
160
|
+
/**
|
|
161
|
+
* Step 2: Upload file directly to GCS
|
|
162
|
+
*/
|
|
163
|
+
uploadToGCS(uploadUrl: string, file: File): Promise<void>;
|
|
164
|
+
/**
|
|
165
|
+
* Step 3: Confirm avatar upload
|
|
166
|
+
*/
|
|
167
|
+
confirmAvatarUpload(storagePath: string): Promise<ConfirmAvatarUploadResponse>;
|
|
168
|
+
/**
|
|
169
|
+
* Get current user's avatar
|
|
170
|
+
*/
|
|
171
|
+
getMyAvatar(): Promise<MyAvatarResponse>;
|
|
172
|
+
/**
|
|
173
|
+
* Get any user's avatar
|
|
174
|
+
*/
|
|
175
|
+
getUserAvatar(userId: string): Promise<MyAvatarResponse>;
|
|
176
|
+
/**
|
|
177
|
+
* Complete avatar upload flow (3-step process)
|
|
178
|
+
*/
|
|
179
|
+
uploadAvatar(file: File): Promise<string>;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* In-memory cache for avatar URLs
|
|
184
|
+
* Shared across all components using the preferences context
|
|
185
|
+
*/
|
|
186
|
+
declare const AVATAR_CACHE_TTL: number;
|
|
187
|
+
/**
|
|
188
|
+
* Get cached avatar URL if valid
|
|
189
|
+
*/
|
|
190
|
+
declare function getCachedAvatar(userId: string): string | null;
|
|
191
|
+
/**
|
|
192
|
+
* Set avatar URL in cache
|
|
193
|
+
*/
|
|
194
|
+
declare function setCachedAvatar(userId: string, url: string): void;
|
|
195
|
+
/**
|
|
196
|
+
* Clear cached avatar for a specific user or all users
|
|
197
|
+
*/
|
|
198
|
+
declare function clearAvatarCache(userId?: string): void;
|
|
199
|
+
/**
|
|
200
|
+
* Check if cache entry exists and is valid
|
|
201
|
+
*/
|
|
202
|
+
declare function hasCachedAvatar(userId: string): boolean;
|
|
203
|
+
|
|
204
|
+
export { AVATAR_CACHE_TTL, type AvatarData, type ConfirmAvatarUploadResponse, type MyAvatarResponse, type PreferencesConfig, type PreferencesContextValue, PreferencesProvider, type PreferencesProviderProps, PreferencesService, type PrepareAvatarUploadResponse, type UserPreferences, clearAvatarCache, getCachedAvatar, hasCachedAvatar, setCachedAvatar, useAvatar, usePreferences, usePreferencesSafe };
|