@oxyhq/services 5.6.10 → 5.7.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/lib/commonjs/core/index.js +57 -0
- package/lib/commonjs/core/index.js.map +1 -1
- package/lib/commonjs/ui/context/OxyContext.js +29 -9
- package/lib/commonjs/ui/context/OxyContext.js.map +1 -1
- package/lib/commonjs/ui/hooks/useSessionSocket.js +4 -1
- package/lib/commonjs/ui/hooks/useSessionSocket.js.map +1 -1
- package/lib/module/core/index.js +57 -0
- package/lib/module/core/index.js.map +1 -1
- package/lib/module/ui/context/OxyContext.js +29 -9
- package/lib/module/ui/context/OxyContext.js.map +1 -1
- package/lib/module/ui/hooks/useSessionSocket.js +4 -1
- package/lib/module/ui/hooks/useSessionSocket.js.map +1 -1
- package/lib/typescript/core/index.d.ts +6 -0
- package/lib/typescript/core/index.d.ts.map +1 -1
- package/lib/typescript/ui/context/OxyContext.d.ts.map +1 -1
- package/lib/typescript/ui/hooks/useSessionSocket.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/core/index.ts +60 -0
- package/src/ui/context/OxyContext.tsx +29 -9
- package/src/ui/hooks/useSessionSocket.ts +4 -1
|
@@ -138,6 +138,18 @@ export const OxyContextProvider: React.FC<OxyContextProviderProps> = ({
|
|
|
138
138
|
// Add a new state to track token restoration
|
|
139
139
|
const [tokenReady, setTokenReady] = React.useState(false);
|
|
140
140
|
|
|
141
|
+
// Add refs to prevent duplicate API calls
|
|
142
|
+
const initAuthRef = React.useRef(false);
|
|
143
|
+
const tokenRestoreRef = React.useRef(false);
|
|
144
|
+
|
|
145
|
+
// Development warning about React StrictMode
|
|
146
|
+
React.useEffect(() => {
|
|
147
|
+
if (__DEV__) {
|
|
148
|
+
console.log('🔍 OxyContext: React StrictMode may cause effects to run twice in development');
|
|
149
|
+
console.log('🔍 This is normal and helps detect side effects. Production builds will not have this behavior.');
|
|
150
|
+
}
|
|
151
|
+
}, []);
|
|
152
|
+
|
|
141
153
|
// Storage keys (memoized to prevent infinite loops)
|
|
142
154
|
const keys = useMemo(() => getSecureStorageKeys(storageKeyPrefix), [storageKeyPrefix]);
|
|
143
155
|
|
|
@@ -159,8 +171,12 @@ export const OxyContextProvider: React.FC<OxyContextProviderProps> = ({
|
|
|
159
171
|
// Effect to initialize authentication state
|
|
160
172
|
useEffect(() => {
|
|
161
173
|
const initAuth = async () => {
|
|
162
|
-
if (!storage) return;
|
|
174
|
+
if (!storage || initAuthRef.current) return;
|
|
175
|
+
|
|
176
|
+
// Prevent multiple simultaneous initializations
|
|
177
|
+
if (isLoading) return;
|
|
163
178
|
|
|
179
|
+
initAuthRef.current = true;
|
|
164
180
|
useAuthStore.setState({ isLoading: true });
|
|
165
181
|
try {
|
|
166
182
|
// Load stored sessions
|
|
@@ -254,15 +270,16 @@ export const OxyContextProvider: React.FC<OxyContextProviderProps> = ({
|
|
|
254
270
|
}
|
|
255
271
|
};
|
|
256
272
|
|
|
257
|
-
if (storage) {
|
|
273
|
+
if (storage && !isLoading) {
|
|
258
274
|
initAuth();
|
|
259
275
|
}
|
|
260
|
-
}, [storage, oxyServices, keys,
|
|
276
|
+
}, [storage, oxyServices, keys.sessions, keys.activeSessionId]); // Removed onAuthStateChange from deps
|
|
261
277
|
|
|
262
|
-
// Effect to restore token on app load or session switch
|
|
278
|
+
// Effect to restore token on app load or session switch - with proper guards
|
|
263
279
|
useEffect(() => {
|
|
264
280
|
const restoreToken = async () => {
|
|
265
|
-
if (activeSessionId && oxyServices) {
|
|
281
|
+
if (activeSessionId && oxyServices && !tokenReady && !tokenRestoreRef.current) {
|
|
282
|
+
tokenRestoreRef.current = true;
|
|
266
283
|
try {
|
|
267
284
|
await oxyServices.getTokenBySession(activeSessionId);
|
|
268
285
|
setTokenReady(true);
|
|
@@ -271,13 +288,16 @@ export const OxyContextProvider: React.FC<OxyContextProviderProps> = ({
|
|
|
271
288
|
await logout();
|
|
272
289
|
setTokenReady(false);
|
|
273
290
|
}
|
|
274
|
-
} else {
|
|
291
|
+
} else if (!activeSessionId && !tokenReady) {
|
|
275
292
|
setTokenReady(true); // No session, so token is not needed
|
|
276
293
|
}
|
|
277
294
|
};
|
|
278
|
-
|
|
279
|
-
// Only run
|
|
280
|
-
|
|
295
|
+
|
|
296
|
+
// Only run if we haven't already set tokenReady
|
|
297
|
+
if (!tokenReady) {
|
|
298
|
+
restoreToken();
|
|
299
|
+
}
|
|
300
|
+
}, [activeSessionId, oxyServices, tokenReady]); // Added tokenReady to prevent re-runs
|
|
281
301
|
|
|
282
302
|
// Remove invalid session
|
|
283
303
|
const removeInvalidSession = useCallback(async (sessionId: string): Promise<void> => {
|
|
@@ -13,9 +13,10 @@ interface UseSessionSocketProps {
|
|
|
13
13
|
|
|
14
14
|
export function useSessionSocket({ userId, activeSessionId, refreshSessions, logout, baseURL, onRemoteSignOut }: UseSessionSocketProps) {
|
|
15
15
|
const socketRef = useRef<any>(null);
|
|
16
|
+
const connectedRef = useRef(false);
|
|
16
17
|
|
|
17
18
|
useEffect(() => {
|
|
18
|
-
if (!userId || !baseURL) return;
|
|
19
|
+
if (!userId || !baseURL || connectedRef.current) return;
|
|
19
20
|
|
|
20
21
|
if (!socketRef.current) {
|
|
21
22
|
socketRef.current = io(baseURL, {
|
|
@@ -26,6 +27,7 @@ export function useSessionSocket({ userId, activeSessionId, refreshSessions, log
|
|
|
26
27
|
|
|
27
28
|
socket.on('connect', () => {
|
|
28
29
|
console.log('Socket connected:', socket.id);
|
|
30
|
+
connectedRef.current = true;
|
|
29
31
|
});
|
|
30
32
|
|
|
31
33
|
socket.emit('join', { userId: `user:${userId}` });
|
|
@@ -43,6 +45,7 @@ export function useSessionSocket({ userId, activeSessionId, refreshSessions, log
|
|
|
43
45
|
});
|
|
44
46
|
|
|
45
47
|
return () => {
|
|
48
|
+
connectedRef.current = false;
|
|
46
49
|
socket.emit('leave', { userId: `user:${userId}` });
|
|
47
50
|
socket.off('session_update');
|
|
48
51
|
};
|