@multiplayer-app/session-recorder-react-native 1.0.1-beta.4 → 1.0.1-beta.5
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/android/src/main/java/com/multiplayer/sessionrecordernative/SessionRecorderNativeModule.kt +2 -2
- package/lib/module/components/SessionRecorderWidget/ErrorBanner.js.map +1 -1
- package/lib/module/components/SessionRecorderWidget/ModalHeader.js.map +1 -1
- package/lib/module/components/SessionRecorderWidget/SessionRecorderWidget.js.map +1 -1
- package/lib/module/components/SessionRecorderWidget/icons.js.map +1 -1
- package/lib/module/components/SessionRecorderWidget/styles.js.map +1 -1
- package/lib/module/config/constants.js.map +1 -1
- package/lib/module/config/defaults.js.map +1 -1
- package/lib/module/config/masking.js.map +1 -1
- package/lib/module/config/session-recorder.js.map +1 -1
- package/lib/module/config/validators.js.map +1 -1
- package/lib/module/config/widget.js.map +1 -1
- package/lib/module/context/SessionRecorderStore.js.map +1 -1
- package/lib/module/context/useSessionRecorderStore.js.map +1 -1
- package/lib/module/context/useStoreSelector.js.map +1 -1
- package/lib/module/native/SessionRecorderNative.js.map +1 -1
- package/lib/module/native/index.js.map +1 -1
- package/lib/module/otel/helpers.js +1 -1
- package/lib/module/otel/helpers.js.map +1 -1
- package/lib/module/otel/index.js.map +1 -1
- package/lib/module/otel/instrumentations/index.js.map +1 -1
- package/lib/module/patch/xhr.js.map +1 -1
- package/lib/module/recorder/eventExporter.js.map +1 -1
- package/lib/module/recorder/gestureRecorder.js.map +1 -1
- package/lib/module/recorder/index.js.map +1 -1
- package/lib/module/recorder/navigationTracker.js.map +1 -1
- package/lib/module/recorder/screenRecorder.js.map +1 -1
- package/lib/module/services/api.service.js.map +1 -1
- package/lib/module/services/network.service.js.map +1 -1
- package/lib/module/services/screenMaskingService.js.map +1 -1
- package/lib/module/services/storage.service.js.map +1 -1
- package/lib/module/session-recorder.js.map +1 -1
- package/lib/module/types/index.js.map +1 -1
- package/lib/module/types/session-recorder.js.map +1 -1
- package/lib/module/utils/app-metadata.js +2 -2
- package/lib/module/utils/constants.optional.js.map +1 -1
- package/lib/module/utils/createStore.js.map +1 -1
- package/lib/module/utils/logger.js +0 -8
- package/lib/module/utils/logger.js.map +1 -1
- package/lib/module/utils/platform.js +1 -1
- package/lib/module/utils/platform.js.map +1 -1
- package/lib/module/utils/rrweb-events.js.map +1 -1
- package/lib/module/utils/session.js.map +1 -1
- package/lib/module/utils/shallowEqual.js.map +1 -1
- package/lib/module/utils/time.js.map +1 -1
- package/lib/module/version.js +1 -1
- package/lib/typescript/src/components/ScreenRecorderView/index.d.ts +1 -1
- package/lib/typescript/src/components/SessionRecorderWidget/ErrorBanner.d.ts.map +1 -1
- package/lib/typescript/src/components/SessionRecorderWidget/ModalHeader.d.ts.map +1 -1
- package/lib/typescript/src/components/SessionRecorderWidget/SessionRecorderWidget.d.ts.map +1 -1
- package/lib/typescript/src/components/SessionRecorderWidget/icons.d.ts.map +1 -1
- package/lib/typescript/src/components/SessionRecorderWidget/index.d.ts +1 -1
- package/lib/typescript/src/components/SessionRecorderWidget/styles.d.ts.map +1 -1
- package/lib/typescript/src/components/index.d.ts.map +1 -1
- package/lib/typescript/src/config/constants.d.ts.map +1 -1
- package/lib/typescript/src/config/defaults.d.ts.map +1 -1
- package/lib/typescript/src/config/index.d.ts.map +1 -1
- package/lib/typescript/src/config/masking.d.ts.map +1 -1
- package/lib/typescript/src/config/session-recorder.d.ts.map +1 -1
- package/lib/typescript/src/config/validators.d.ts.map +1 -1
- package/lib/typescript/src/config/widget.d.ts +1 -1
- package/lib/typescript/src/config/widget.d.ts.map +1 -1
- package/lib/typescript/src/context/SessionRecorderStore.d.ts.map +1 -1
- package/lib/typescript/src/context/useSessionRecorderStore.d.ts +3 -3
- package/lib/typescript/src/context/useSessionRecorderStore.d.ts.map +1 -1
- package/lib/typescript/src/context/useStoreSelector.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/native/SessionRecorderNative.d.ts.map +1 -1
- package/lib/typescript/src/native/index.d.ts +1 -1
- package/lib/typescript/src/native/index.d.ts.map +1 -1
- package/lib/typescript/src/otel/helpers.d.ts.map +1 -1
- package/lib/typescript/src/otel/index.d.ts.map +1 -1
- package/lib/typescript/src/otel/instrumentations/index.d.ts.map +1 -1
- package/lib/typescript/src/patch/index.d.ts.map +1 -1
- package/lib/typescript/src/patch/xhr.d.ts.map +1 -1
- package/lib/typescript/src/recorder/eventExporter.d.ts.map +1 -1
- package/lib/typescript/src/recorder/gestureRecorder.d.ts.map +1 -1
- package/lib/typescript/src/recorder/index.d.ts.map +1 -1
- package/lib/typescript/src/recorder/navigationTracker.d.ts.map +1 -1
- package/lib/typescript/src/recorder/screenRecorder.d.ts.map +1 -1
- package/lib/typescript/src/services/api.service.d.ts.map +1 -1
- package/lib/typescript/src/services/network.service.d.ts.map +1 -1
- package/lib/typescript/src/services/screenMaskingService.d.ts.map +1 -1
- package/lib/typescript/src/services/storage.service.d.ts.map +1 -1
- package/lib/typescript/src/session-recorder.d.ts.map +1 -1
- package/lib/typescript/src/types/configs.d.ts.map +1 -1
- package/lib/typescript/src/types/index.d.ts.map +1 -1
- package/lib/typescript/src/types/session-recorder.d.ts +4 -4
- package/lib/typescript/src/types/session-recorder.d.ts.map +1 -1
- package/lib/typescript/src/types/session.d.ts.map +1 -1
- package/lib/typescript/src/utils/app-metadata.d.ts.map +1 -1
- package/lib/typescript/src/utils/constants.optional.d.ts.map +1 -1
- package/lib/typescript/src/utils/constants.optional.expo.d.ts.map +1 -1
- package/lib/typescript/src/utils/createStore.d.ts.map +1 -1
- package/lib/typescript/src/utils/index.d.ts.map +1 -1
- package/lib/typescript/src/utils/logger.d.ts +1 -1
- package/lib/typescript/src/utils/logger.d.ts.map +1 -1
- package/lib/typescript/src/utils/platform.d.ts.map +1 -1
- package/lib/typescript/src/utils/request-utils.d.ts.map +1 -1
- package/lib/typescript/src/utils/rrweb-events.d.ts.map +1 -1
- package/lib/typescript/src/utils/session.d.ts.map +1 -1
- package/lib/typescript/src/utils/shallowEqual.d.ts.map +1 -1
- package/lib/typescript/src/utils/time.d.ts.map +1 -1
- package/lib/typescript/src/utils/type-utils.d.ts.map +1 -1
- package/lib/typescript/src/version.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/components/ScreenRecorderView/index.ts +1 -1
- package/src/components/SessionRecorderWidget/ErrorBanner.tsx +14 -14
- package/src/components/SessionRecorderWidget/ModalHeader.tsx +11 -9
- package/src/components/SessionRecorderWidget/SessionRecorderWidget.tsx +70 -56
- package/src/components/SessionRecorderWidget/icons.tsx +58 -30
- package/src/components/SessionRecorderWidget/index.ts +1 -1
- package/src/components/SessionRecorderWidget/styles.ts +17 -18
- package/src/components/index.ts +2 -2
- package/src/config/constants.ts +19 -20
- package/src/config/defaults.ts +35 -31
- package/src/config/index.ts +5 -5
- package/src/config/masking.ts +44 -18
- package/src/config/session-recorder.ts +54 -26
- package/src/config/validators.ts +43 -20
- package/src/config/widget.ts +24 -15
- package/src/context/SessionRecorderStore.ts +19 -18
- package/src/context/useSessionRecorderStore.ts +17 -10
- package/src/context/useStoreSelector.ts +20 -18
- package/src/index.ts +7 -7
- package/src/native/SessionRecorderNative.ts +83 -67
- package/src/native/index.ts +5 -1
- package/src/otel/helpers.ts +109 -93
- package/src/otel/index.ts +46 -49
- package/src/otel/instrumentations/index.ts +44 -41
- package/src/patch/index.ts +1 -1
- package/src/patch/xhr.ts +77 -78
- package/src/recorder/eventExporter.ts +63 -68
- package/src/recorder/gestureRecorder.ts +359 -212
- package/src/recorder/index.ts +75 -62
- package/src/recorder/navigationTracker.ts +120 -97
- package/src/recorder/screenRecorder.ts +214 -163
- package/src/services/api.service.ts +49 -48
- package/src/services/network.service.ts +67 -58
- package/src/services/screenMaskingService.ts +81 -50
- package/src/services/storage.service.ts +99 -70
- package/src/session-recorder.ts +270 -214
- package/src/types/configs.ts +53 -31
- package/src/types/expo-constants.d.ts +2 -2
- package/src/types/index.ts +16 -18
- package/src/types/session-recorder.ts +106 -111
- package/src/types/session.ts +45 -45
- package/src/utils/app-metadata.ts +9 -9
- package/src/utils/constants.optional.expo.ts +3 -3
- package/src/utils/constants.optional.ts +14 -12
- package/src/utils/createStore.ts +23 -20
- package/src/utils/index.ts +7 -7
- package/src/utils/logger.ts +87 -58
- package/src/utils/platform.ts +149 -118
- package/src/utils/request-utils.ts +15 -15
- package/src/utils/rrweb-events.ts +47 -34
- package/src/utils/session.ts +15 -12
- package/src/utils/shallowEqual.ts +16 -10
- package/src/utils/time.ts +7 -4
- package/src/utils/type-utils.ts +36 -36
- package/src/version.ts +1 -1
- package/android/src/main/java/com/multiplayer/sessionrecordernative/SessionRecorderNativeModuleSpec.kt +0 -51
- package/android/src/main/java/com/xxx/XxxModule.kt +0 -23
- package/ios/Xxx.h +0 -5
- package/ios/Xxx.mm +0 -21
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
import { Platform } from 'react-native'
|
|
2
|
-
import { SessionType } from '@multiplayer-app/session-recorder-common'
|
|
3
|
-
import { type ISession, type SessionState } from '../types'
|
|
4
|
-
import { logger } from '../utils'
|
|
1
|
+
import { Platform } from 'react-native';
|
|
2
|
+
import { SessionType } from '@multiplayer-app/session-recorder-common';
|
|
3
|
+
import { type ISession, type SessionState } from '../types';
|
|
4
|
+
import { logger } from '../utils';
|
|
5
5
|
|
|
6
6
|
// Safe import for AsyncStorage with web fallback
|
|
7
|
-
let AsyncStorage: any = null
|
|
8
|
-
const isWeb = Platform.OS === 'web'
|
|
7
|
+
let AsyncStorage: any = null;
|
|
8
|
+
const isWeb = Platform.OS === 'web';
|
|
9
9
|
|
|
10
10
|
if (!isWeb) {
|
|
11
11
|
try {
|
|
12
|
-
AsyncStorage = require('@react-native-async-storage/async-storage').default
|
|
12
|
+
AsyncStorage = require('@react-native-async-storage/async-storage').default;
|
|
13
13
|
} catch (error) {
|
|
14
|
-
console.warn('AsyncStorage not available:', error)
|
|
14
|
+
console.warn('AsyncStorage not available:', error);
|
|
15
15
|
}
|
|
16
16
|
} else {
|
|
17
17
|
// Web fallback using localStorage
|
|
@@ -20,23 +20,24 @@ if (!isWeb) {
|
|
|
20
20
|
setItem: (_key: string, _value: string) => Promise.resolve(undefined),
|
|
21
21
|
removeItem: (_key: string) => Promise.resolve(undefined),
|
|
22
22
|
multiRemove: (_keys: string[]) => Promise.resolve(undefined),
|
|
23
|
-
}
|
|
23
|
+
};
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
interface CacheData {
|
|
27
|
-
sessionId: string | null
|
|
28
|
-
sessionType: SessionType | null
|
|
29
|
-
sessionState: SessionState | null
|
|
30
|
-
sessionObject: ISession | null
|
|
31
|
-
floatingButtonPosition: { x: number; y: number } | null
|
|
27
|
+
sessionId: string | null;
|
|
28
|
+
sessionType: SessionType | null;
|
|
29
|
+
sessionState: SessionState | null;
|
|
30
|
+
sessionObject: ISession | null;
|
|
31
|
+
floatingButtonPosition: { x: number; y: number } | null;
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
export class StorageService {
|
|
35
|
-
private static readonly SESSION_ID_KEY = 'session_id'
|
|
36
|
-
private static readonly SESSION_TYPE_KEY = 'session_type'
|
|
37
|
-
private static readonly SESSION_STATE_KEY = 'session_state'
|
|
38
|
-
private static readonly SESSION_OBJECT_KEY = 'session_object'
|
|
39
|
-
private static readonly FLOATING_BUTTON_POSITION_KEY =
|
|
35
|
+
private static readonly SESSION_ID_KEY = 'session_id';
|
|
36
|
+
private static readonly SESSION_TYPE_KEY = 'session_type';
|
|
37
|
+
private static readonly SESSION_STATE_KEY = 'session_state';
|
|
38
|
+
private static readonly SESSION_OBJECT_KEY = 'session_object';
|
|
39
|
+
private static readonly FLOATING_BUTTON_POSITION_KEY =
|
|
40
|
+
'floating_button_position';
|
|
40
41
|
|
|
41
42
|
private static cache: CacheData = {
|
|
42
43
|
sessionId: null,
|
|
@@ -44,11 +45,11 @@ export class StorageService {
|
|
|
44
45
|
sessionState: null,
|
|
45
46
|
sessionObject: null,
|
|
46
47
|
floatingButtonPosition: null,
|
|
47
|
-
}
|
|
48
|
+
};
|
|
48
49
|
|
|
49
|
-
private static cacheInitialized = false
|
|
50
|
-
private static instance: StorageService | null = null
|
|
51
|
-
private static positionSaveTimeout: any | null = null
|
|
50
|
+
private static cacheInitialized = false;
|
|
51
|
+
private static instance: StorageService | null = null;
|
|
52
|
+
private static positionSaveTimeout: any | null = null;
|
|
52
53
|
|
|
53
54
|
private constructor() {
|
|
54
55
|
// Private constructor for singleton
|
|
@@ -56,101 +57,118 @@ export class StorageService {
|
|
|
56
57
|
|
|
57
58
|
static getInstance(): StorageService {
|
|
58
59
|
if (!StorageService.instance) {
|
|
59
|
-
StorageService.instance = new StorageService()
|
|
60
|
-
StorageService.initialize()
|
|
60
|
+
StorageService.instance = new StorageService();
|
|
61
|
+
StorageService.initialize();
|
|
61
62
|
}
|
|
62
|
-
return StorageService.instance
|
|
63
|
+
return StorageService.instance;
|
|
63
64
|
}
|
|
64
65
|
|
|
65
66
|
private static async initializeCache(): Promise<void> {
|
|
66
|
-
if (StorageService.cacheInitialized) return
|
|
67
|
+
if (StorageService.cacheInitialized) return;
|
|
67
68
|
|
|
68
69
|
try {
|
|
69
|
-
const [
|
|
70
|
+
const [
|
|
71
|
+
sessionId,
|
|
72
|
+
sessionType,
|
|
73
|
+
sessionState,
|
|
74
|
+
sessionObject,
|
|
75
|
+
floatingButtonPosition,
|
|
76
|
+
] = await Promise.all([
|
|
70
77
|
AsyncStorage.getItem(StorageService.SESSION_ID_KEY),
|
|
71
78
|
AsyncStorage.getItem(StorageService.SESSION_TYPE_KEY),
|
|
72
79
|
AsyncStorage.getItem(StorageService.SESSION_STATE_KEY),
|
|
73
80
|
AsyncStorage.getItem(StorageService.SESSION_OBJECT_KEY),
|
|
74
81
|
AsyncStorage.getItem(StorageService.FLOATING_BUTTON_POSITION_KEY),
|
|
75
|
-
])
|
|
82
|
+
]);
|
|
76
83
|
|
|
77
84
|
StorageService.cache = {
|
|
78
85
|
sessionId,
|
|
79
86
|
sessionType: sessionType as SessionType | null,
|
|
80
87
|
sessionState: sessionState as SessionState | null,
|
|
81
88
|
sessionObject: sessionObject ? JSON.parse(sessionObject) : null,
|
|
82
|
-
floatingButtonPosition: floatingButtonPosition
|
|
83
|
-
|
|
84
|
-
|
|
89
|
+
floatingButtonPosition: floatingButtonPosition
|
|
90
|
+
? JSON.parse(floatingButtonPosition)
|
|
91
|
+
: null,
|
|
92
|
+
};
|
|
93
|
+
StorageService.cacheInitialized = true;
|
|
85
94
|
} catch (error) {
|
|
86
95
|
// Failed to initialize cache - silently continue
|
|
87
|
-
StorageService.cacheInitialized = true // Mark as initialized to prevent retries
|
|
96
|
+
StorageService.cacheInitialized = true; // Mark as initialized to prevent retries
|
|
88
97
|
}
|
|
89
98
|
}
|
|
90
99
|
|
|
91
100
|
saveSessionId(sessionId: string): void {
|
|
92
101
|
try {
|
|
93
|
-
StorageService.cache.sessionId = sessionId
|
|
94
|
-
AsyncStorage.setItem(StorageService.SESSION_ID_KEY, sessionId).catch(
|
|
95
|
-
|
|
96
|
-
|
|
102
|
+
StorageService.cache.sessionId = sessionId;
|
|
103
|
+
AsyncStorage.setItem(StorageService.SESSION_ID_KEY, sessionId).catch(
|
|
104
|
+
(_error: any) => {
|
|
105
|
+
// Failed to persist session ID - silently continue
|
|
106
|
+
}
|
|
107
|
+
);
|
|
97
108
|
} catch (error) {
|
|
98
109
|
// Failed to save session ID - silently continue
|
|
99
|
-
throw error
|
|
110
|
+
throw error;
|
|
100
111
|
}
|
|
101
112
|
}
|
|
102
113
|
|
|
103
114
|
getSessionId(): string | null {
|
|
104
|
-
return StorageService.cache.sessionId
|
|
115
|
+
return StorageService.cache.sessionId;
|
|
105
116
|
}
|
|
106
117
|
|
|
107
118
|
saveSessionType(sessionType: SessionType): void {
|
|
108
119
|
try {
|
|
109
|
-
StorageService.cache.sessionType = sessionType
|
|
110
|
-
AsyncStorage.setItem(StorageService.SESSION_TYPE_KEY, sessionType).catch(
|
|
111
|
-
|
|
112
|
-
|
|
120
|
+
StorageService.cache.sessionType = sessionType;
|
|
121
|
+
AsyncStorage.setItem(StorageService.SESSION_TYPE_KEY, sessionType).catch(
|
|
122
|
+
(_error: any) => {
|
|
123
|
+
// Failed to persist session type - silently continue
|
|
124
|
+
}
|
|
125
|
+
);
|
|
113
126
|
} catch (error) {
|
|
114
127
|
// Failed to save session type - silently continue
|
|
115
|
-
throw error
|
|
128
|
+
throw error;
|
|
116
129
|
}
|
|
117
130
|
}
|
|
118
131
|
|
|
119
132
|
getSessionType(): SessionType | null {
|
|
120
|
-
return StorageService.cache.sessionType
|
|
133
|
+
return StorageService.cache.sessionType;
|
|
121
134
|
}
|
|
122
135
|
|
|
123
136
|
saveSessionState(state: SessionState): void {
|
|
124
137
|
try {
|
|
125
|
-
StorageService.cache.sessionState = state
|
|
138
|
+
StorageService.cache.sessionState = state;
|
|
126
139
|
|
|
127
|
-
AsyncStorage.setItem(StorageService.SESSION_STATE_KEY, state).catch(
|
|
128
|
-
|
|
129
|
-
|
|
140
|
+
AsyncStorage.setItem(StorageService.SESSION_STATE_KEY, state).catch(
|
|
141
|
+
(_error: any) => {
|
|
142
|
+
// Failed to persist session state - silently continue
|
|
143
|
+
}
|
|
144
|
+
);
|
|
130
145
|
} catch (error) {
|
|
131
146
|
// Failed to save session state - silently continue
|
|
132
|
-
throw error
|
|
147
|
+
throw error;
|
|
133
148
|
}
|
|
134
149
|
}
|
|
135
150
|
|
|
136
151
|
getSessionState(): SessionState | null {
|
|
137
|
-
return StorageService.cache.sessionState
|
|
152
|
+
return StorageService.cache.sessionState;
|
|
138
153
|
}
|
|
139
154
|
|
|
140
155
|
saveSessionObject(session: ISession): void {
|
|
141
156
|
try {
|
|
142
|
-
StorageService.cache.sessionObject = session
|
|
143
|
-
AsyncStorage.setItem(
|
|
157
|
+
StorageService.cache.sessionObject = session;
|
|
158
|
+
AsyncStorage.setItem(
|
|
159
|
+
StorageService.SESSION_OBJECT_KEY,
|
|
160
|
+
JSON.stringify(session)
|
|
161
|
+
).catch((_error: any) => {
|
|
144
162
|
// Failed to persist session object - silently continue
|
|
145
|
-
})
|
|
163
|
+
});
|
|
146
164
|
} catch (error) {
|
|
147
165
|
// Failed to save session object - silently continue
|
|
148
|
-
throw error
|
|
166
|
+
throw error;
|
|
149
167
|
}
|
|
150
168
|
}
|
|
151
169
|
|
|
152
170
|
getSessionObject(): ISession | null {
|
|
153
|
-
return StorageService.cache.sessionObject
|
|
171
|
+
return StorageService.cache.sessionObject;
|
|
154
172
|
}
|
|
155
173
|
|
|
156
174
|
clearSessionData(): void {
|
|
@@ -162,7 +180,7 @@ export class StorageService {
|
|
|
162
180
|
sessionType: null,
|
|
163
181
|
sessionState: null,
|
|
164
182
|
sessionObject: null,
|
|
165
|
-
}
|
|
183
|
+
};
|
|
166
184
|
|
|
167
185
|
// Clear persistent storage asynchronously
|
|
168
186
|
AsyncStorage.multiRemove([
|
|
@@ -172,10 +190,10 @@ export class StorageService {
|
|
|
172
190
|
StorageService.SESSION_OBJECT_KEY,
|
|
173
191
|
]).catch((_error: any) => {
|
|
174
192
|
// Failed to clear session data from storage - silently continue
|
|
175
|
-
})
|
|
193
|
+
});
|
|
176
194
|
} catch (error) {
|
|
177
195
|
// Failed to clear session data - silently continue
|
|
178
|
-
throw error
|
|
196
|
+
throw error;
|
|
179
197
|
}
|
|
180
198
|
}
|
|
181
199
|
|
|
@@ -185,35 +203,46 @@ export class StorageService {
|
|
|
185
203
|
sessionType: StorageService.cache.sessionType,
|
|
186
204
|
sessionState: StorageService.cache.sessionState,
|
|
187
205
|
sessionObject: StorageService.cache.sessionObject,
|
|
188
|
-
}
|
|
206
|
+
};
|
|
189
207
|
}
|
|
190
208
|
|
|
191
209
|
saveFloatingButtonPosition(position: { x: number; y: number }): void {
|
|
192
210
|
try {
|
|
193
|
-
StorageService.cache.floatingButtonPosition = position
|
|
211
|
+
StorageService.cache.floatingButtonPosition = position;
|
|
194
212
|
|
|
195
213
|
// Debounce AsyncStorage writes to avoid excessive I/O
|
|
196
214
|
if (StorageService.positionSaveTimeout) {
|
|
197
|
-
clearTimeout(StorageService.positionSaveTimeout)
|
|
215
|
+
clearTimeout(StorageService.positionSaveTimeout);
|
|
198
216
|
}
|
|
199
217
|
|
|
200
218
|
StorageService.positionSaveTimeout = setTimeout(() => {
|
|
201
|
-
AsyncStorage.setItem(
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
219
|
+
AsyncStorage.setItem(
|
|
220
|
+
StorageService.FLOATING_BUTTON_POSITION_KEY,
|
|
221
|
+
JSON.stringify(position)
|
|
222
|
+
).catch((error: any) => {
|
|
223
|
+
logger.error(
|
|
224
|
+
'StorageService',
|
|
225
|
+
'Failed to persist floating button position',
|
|
226
|
+
error
|
|
227
|
+
);
|
|
228
|
+
});
|
|
229
|
+
}, 100); // 100ms debounce
|
|
205
230
|
} catch (error) {
|
|
206
|
-
logger.error(
|
|
207
|
-
|
|
231
|
+
logger.error(
|
|
232
|
+
'StorageService',
|
|
233
|
+
'Failed to save floating button position',
|
|
234
|
+
error
|
|
235
|
+
);
|
|
236
|
+
throw error;
|
|
208
237
|
}
|
|
209
238
|
}
|
|
210
239
|
|
|
211
240
|
getFloatingButtonPosition(): { x: number; y: number } | null {
|
|
212
|
-
return StorageService.cache.floatingButtonPosition
|
|
241
|
+
return StorageService.cache.floatingButtonPosition;
|
|
213
242
|
}
|
|
214
243
|
|
|
215
244
|
// Initialize cache on first use - call this method when the service is first used
|
|
216
245
|
static async initialize(): Promise<void> {
|
|
217
|
-
await StorageService.initializeCache()
|
|
246
|
+
await StorageService.initializeCache();
|
|
218
247
|
}
|
|
219
248
|
}
|