@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,6 +1,13 @@
|
|
|
1
|
-
import { Dimensions } from 'react-native'
|
|
2
|
-
import {
|
|
3
|
-
|
|
1
|
+
import { Dimensions } from 'react-native';
|
|
2
|
+
import {
|
|
3
|
+
EventType,
|
|
4
|
+
type eventWithTime,
|
|
5
|
+
NodeType,
|
|
6
|
+
type serializedNodeWithId,
|
|
7
|
+
IncrementalSource,
|
|
8
|
+
type mutationData,
|
|
9
|
+
} from '@rrweb/types';
|
|
10
|
+
import { getAppMetadata } from './platform';
|
|
4
11
|
|
|
5
12
|
/**
|
|
6
13
|
* Creates a meta event to mark the start of recording
|
|
@@ -10,18 +17,19 @@ import { getAppMetadata } from './platform'
|
|
|
10
17
|
* @returns MetaEvent object
|
|
11
18
|
*/
|
|
12
19
|
export function createRecordingMetaEvent(): eventWithTime {
|
|
13
|
-
const screenDimensions = Dimensions.get('window')
|
|
14
|
-
const metadata = getAppMetadata()
|
|
20
|
+
const screenDimensions = Dimensions.get('window');
|
|
21
|
+
const metadata = getAppMetadata();
|
|
15
22
|
|
|
16
23
|
return {
|
|
17
24
|
type: EventType.Meta,
|
|
18
25
|
data: {
|
|
19
|
-
href:
|
|
26
|
+
href:
|
|
27
|
+
metadata.bundleId || metadata.name || 'https://native.multiplayer.app',
|
|
20
28
|
width: screenDimensions.width,
|
|
21
29
|
height: screenDimensions.height,
|
|
22
30
|
},
|
|
23
31
|
timestamp: Date.now(),
|
|
24
|
-
}
|
|
32
|
+
};
|
|
25
33
|
}
|
|
26
34
|
|
|
27
35
|
/**
|
|
@@ -40,7 +48,7 @@ export function createFullSnapshotEvent(
|
|
|
40
48
|
height: number,
|
|
41
49
|
captureFormat: string = 'jpg',
|
|
42
50
|
nodeIdCounter: { current: number },
|
|
43
|
-
timestamp?: number
|
|
51
|
+
timestamp?: number
|
|
44
52
|
): eventWithTime {
|
|
45
53
|
// Create a virtual DOM node representing the screen as an image
|
|
46
54
|
const imageNode: serializedNodeWithId = {
|
|
@@ -54,7 +62,7 @@ export function createFullSnapshotEvent(
|
|
|
54
62
|
style: `width: ${width}px; height: ${height}px;`,
|
|
55
63
|
},
|
|
56
64
|
childNodes: [],
|
|
57
|
-
}
|
|
65
|
+
};
|
|
58
66
|
|
|
59
67
|
// Create the root container
|
|
60
68
|
const rootNode: serializedNodeWithId = {
|
|
@@ -65,7 +73,7 @@ export function createFullSnapshotEvent(
|
|
|
65
73
|
style: `width: ${width}px; height: ${height}px; position: relative;`,
|
|
66
74
|
},
|
|
67
75
|
childNodes: [imageNode],
|
|
68
|
-
}
|
|
76
|
+
};
|
|
69
77
|
|
|
70
78
|
const domNode: serializedNodeWithId = {
|
|
71
79
|
type: NodeType.Document,
|
|
@@ -99,7 +107,8 @@ export function createFullSnapshotEvent(
|
|
|
99
107
|
tagName: 'meta',
|
|
100
108
|
attributes: {
|
|
101
109
|
name: 'viewport',
|
|
102
|
-
content:
|
|
110
|
+
content:
|
|
111
|
+
'width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no',
|
|
103
112
|
},
|
|
104
113
|
childNodes: [],
|
|
105
114
|
id: nodeIdCounter.current++,
|
|
@@ -121,7 +130,7 @@ export function createFullSnapshotEvent(
|
|
|
121
130
|
},
|
|
122
131
|
],
|
|
123
132
|
id: nodeIdCounter.current++,
|
|
124
|
-
}
|
|
133
|
+
};
|
|
125
134
|
|
|
126
135
|
return {
|
|
127
136
|
type: EventType.FullSnapshot,
|
|
@@ -130,7 +139,7 @@ export function createFullSnapshotEvent(
|
|
|
130
139
|
initialOffset: { left: 0, top: 0 },
|
|
131
140
|
},
|
|
132
141
|
timestamp: timestamp || Date.now(),
|
|
133
|
-
}
|
|
142
|
+
};
|
|
134
143
|
}
|
|
135
144
|
|
|
136
145
|
/**
|
|
@@ -143,7 +152,7 @@ export function createFullSnapshotEvent(
|
|
|
143
152
|
export function createIncrementalSnapshotWithImageUpdate(
|
|
144
153
|
base64Image: string,
|
|
145
154
|
captureFormat: string = 'jpg',
|
|
146
|
-
timestamp?: number
|
|
155
|
+
timestamp?: number
|
|
147
156
|
): eventWithTime {
|
|
148
157
|
const mutationData: mutationData = {
|
|
149
158
|
source: IncrementalSource.Mutation,
|
|
@@ -158,13 +167,13 @@ export function createIncrementalSnapshotWithImageUpdate(
|
|
|
158
167
|
],
|
|
159
168
|
removes: [],
|
|
160
169
|
adds: [],
|
|
161
|
-
}
|
|
170
|
+
};
|
|
162
171
|
|
|
163
172
|
return {
|
|
164
173
|
type: EventType.IncrementalSnapshot,
|
|
165
174
|
data: mutationData,
|
|
166
175
|
timestamp: timestamp || Date.now(),
|
|
167
|
-
}
|
|
176
|
+
};
|
|
168
177
|
}
|
|
169
178
|
|
|
170
179
|
/**
|
|
@@ -181,7 +190,7 @@ export function createImageNode(
|
|
|
181
190
|
width: number,
|
|
182
191
|
height: number,
|
|
183
192
|
captureFormat: string = 'jpg',
|
|
184
|
-
nodeId: number
|
|
193
|
+
nodeId: number
|
|
185
194
|
): serializedNodeWithId {
|
|
186
195
|
return {
|
|
187
196
|
type: NodeType.Element,
|
|
@@ -194,7 +203,7 @@ export function createImageNode(
|
|
|
194
203
|
style: `width: ${width}px; height: ${height}px;`,
|
|
195
204
|
},
|
|
196
205
|
childNodes: [],
|
|
197
|
-
}
|
|
206
|
+
};
|
|
198
207
|
}
|
|
199
208
|
|
|
200
209
|
/**
|
|
@@ -209,7 +218,7 @@ export function createDocumentNode(
|
|
|
209
218
|
imageNode: serializedNodeWithId,
|
|
210
219
|
width: number,
|
|
211
220
|
height: number,
|
|
212
|
-
nodeIdCounter: { current: number }
|
|
221
|
+
nodeIdCounter: { current: number }
|
|
213
222
|
): serializedNodeWithId {
|
|
214
223
|
// Create the root container
|
|
215
224
|
const rootNode: serializedNodeWithId = {
|
|
@@ -220,7 +229,7 @@ export function createDocumentNode(
|
|
|
220
229
|
style: `width: ${width}px; height: ${height}px; position: relative;`,
|
|
221
230
|
},
|
|
222
231
|
childNodes: [imageNode],
|
|
223
|
-
}
|
|
232
|
+
};
|
|
224
233
|
|
|
225
234
|
return {
|
|
226
235
|
type: NodeType.Document,
|
|
@@ -254,7 +263,8 @@ export function createDocumentNode(
|
|
|
254
263
|
tagName: 'meta',
|
|
255
264
|
attributes: {
|
|
256
265
|
name: 'viewport',
|
|
257
|
-
content:
|
|
266
|
+
content:
|
|
267
|
+
'width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no',
|
|
258
268
|
},
|
|
259
269
|
childNodes: [],
|
|
260
270
|
id: nodeIdCounter.current++,
|
|
@@ -274,7 +284,7 @@ export function createDocumentNode(
|
|
|
274
284
|
},
|
|
275
285
|
],
|
|
276
286
|
id: nodeIdCounter.current++,
|
|
277
|
-
}
|
|
287
|
+
};
|
|
278
288
|
}
|
|
279
289
|
|
|
280
290
|
/**
|
|
@@ -285,19 +295,22 @@ export function createDocumentNode(
|
|
|
285
295
|
* @param sampleSize - Number of characters to sample from each part
|
|
286
296
|
* @returns Hash string for comparison
|
|
287
297
|
*/
|
|
288
|
-
export function generateScreenHash(
|
|
298
|
+
export function generateScreenHash(
|
|
299
|
+
base64Image: string,
|
|
300
|
+
sampleSize: number = 100
|
|
301
|
+
): string {
|
|
289
302
|
// Use a simple hash that samples the beginning, middle, and end of the base64 string
|
|
290
303
|
// This is much faster than comparing the entire string
|
|
291
|
-
const start = base64Image.substring(0, sampleSize)
|
|
304
|
+
const start = base64Image.substring(0, sampleSize);
|
|
292
305
|
const middle = base64Image.substring(
|
|
293
306
|
Math.floor(base64Image.length / 2) - sampleSize / 2,
|
|
294
|
-
Math.floor(base64Image.length / 2) + sampleSize / 2
|
|
295
|
-
)
|
|
296
|
-
const end = base64Image.substring(base64Image.length - sampleSize)
|
|
307
|
+
Math.floor(base64Image.length / 2) + sampleSize / 2
|
|
308
|
+
);
|
|
309
|
+
const end = base64Image.substring(base64Image.length - sampleSize);
|
|
297
310
|
|
|
298
311
|
// Combine samples and create a simple hash
|
|
299
|
-
const combined = start + middle + end
|
|
300
|
-
return simpleHash(combined)
|
|
312
|
+
const combined = start + middle + end;
|
|
313
|
+
return simpleHash(combined);
|
|
301
314
|
}
|
|
302
315
|
|
|
303
316
|
/**
|
|
@@ -306,11 +319,11 @@ export function generateScreenHash(base64Image: string, sampleSize: number = 100
|
|
|
306
319
|
* @returns Hash value as string
|
|
307
320
|
*/
|
|
308
321
|
export function simpleHash(str: string): string {
|
|
309
|
-
let hash = 0
|
|
322
|
+
let hash = 0;
|
|
310
323
|
for (let i = 0; i < str.length; i++) {
|
|
311
|
-
const char = str.charCodeAt(i)
|
|
312
|
-
hash = (hash << 5) - hash + char
|
|
313
|
-
hash = hash & hash // Convert to 32-bit integer
|
|
324
|
+
const char = str.charCodeAt(i);
|
|
325
|
+
hash = (hash << 5) - hash + char;
|
|
326
|
+
hash = hash & hash; // Convert to 32-bit integer
|
|
314
327
|
}
|
|
315
|
-
return Math.abs(hash).toString(36)
|
|
328
|
+
return Math.abs(hash).toString(36);
|
|
316
329
|
}
|
package/src/utils/session.ts
CHANGED
|
@@ -1,19 +1,22 @@
|
|
|
1
|
-
import { SessionType } from '@multiplayer-app/session-recorder-common'
|
|
2
|
-
import { DEBUG_SESSION_MAX_DURATION_SECONDS } from '../config/constants'
|
|
1
|
+
import { SessionType } from '@multiplayer-app/session-recorder-common';
|
|
2
|
+
import { DEBUG_SESSION_MAX_DURATION_SECONDS } from '../config/constants';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Session-related utility functions for React Native
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
export const isSessionActive = (
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
8
|
+
export const isSessionActive = (
|
|
9
|
+
session: any,
|
|
10
|
+
sessionType: SessionType | null
|
|
11
|
+
): boolean => {
|
|
12
|
+
if (!session) return false;
|
|
13
|
+
if (sessionType === SessionType.CONTINUOUS) return true;
|
|
14
|
+
const startedAt = new Date(session.startedAt || session.createdAt);
|
|
15
|
+
const now = new Date();
|
|
16
|
+
const diff = now.getTime() - startedAt.getTime();
|
|
17
|
+
return diff < DEBUG_SESSION_MAX_DURATION_SECONDS * 1000;
|
|
18
|
+
};
|
|
16
19
|
|
|
17
20
|
export const isConsoleEvent = (event: any): boolean => {
|
|
18
|
-
return event.type === 'Plugin' && event.data?.plugin === 'rrweb/console@1'
|
|
19
|
-
}
|
|
21
|
+
return event.type === 'Plugin' && event.data?.plugin === 'rrweb/console@1';
|
|
22
|
+
};
|
|
@@ -1,14 +1,20 @@
|
|
|
1
|
-
export function shallowEqual<T extends Record<string, any>>(
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
if (
|
|
1
|
+
export function shallowEqual<T extends Record<string, any>>(
|
|
2
|
+
a: T,
|
|
3
|
+
b: T
|
|
4
|
+
): boolean {
|
|
5
|
+
if (Object.is(a, b)) return true;
|
|
6
|
+
if (!a || !b) return false;
|
|
7
|
+
const aKeys = Object.keys(a);
|
|
8
|
+
const bKeys = Object.keys(b);
|
|
9
|
+
if (aKeys.length !== bKeys.length) return false;
|
|
7
10
|
for (let i = 0; i < aKeys.length; i++) {
|
|
8
|
-
const key = aKeys[i]
|
|
9
|
-
if (
|
|
10
|
-
|
|
11
|
+
const key = aKeys[i];
|
|
12
|
+
if (
|
|
13
|
+
!Object.prototype.hasOwnProperty.call(b, key!) ||
|
|
14
|
+
!Object.is(a[key!], b[key!])
|
|
15
|
+
) {
|
|
16
|
+
return false;
|
|
11
17
|
}
|
|
12
18
|
}
|
|
13
|
-
return true
|
|
19
|
+
return true;
|
|
14
20
|
}
|
package/src/utils/time.ts
CHANGED
|
@@ -2,7 +2,10 @@
|
|
|
2
2
|
* Time and date utility functions for React Native
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
export const getFormattedDate = (
|
|
5
|
+
export const getFormattedDate = (
|
|
6
|
+
date: number | Date,
|
|
7
|
+
options?: any
|
|
8
|
+
): string => {
|
|
6
9
|
return new Date(date).toLocaleDateString(
|
|
7
10
|
'en-US',
|
|
8
11
|
options || {
|
|
@@ -12,6 +15,6 @@ export const getFormattedDate = (date: number | Date, options?: any): string =>
|
|
|
12
15
|
hour: 'numeric',
|
|
13
16
|
minute: '2-digit',
|
|
14
17
|
second: '2-digit',
|
|
15
|
-
}
|
|
16
|
-
)
|
|
17
|
-
}
|
|
18
|
+
}
|
|
19
|
+
);
|
|
20
|
+
};
|
package/src/utils/type-utils.ts
CHANGED
|
@@ -1,75 +1,75 @@
|
|
|
1
|
-
const nativeIsArray = Array.isArray
|
|
2
|
-
const ObjProto = Object.prototype
|
|
3
|
-
export const hasOwnProperty = ObjProto.hasOwnProperty
|
|
4
|
-
const toString = ObjProto.toString
|
|
1
|
+
const nativeIsArray = Array.isArray;
|
|
2
|
+
const ObjProto = Object.prototype;
|
|
3
|
+
export const hasOwnProperty = ObjProto.hasOwnProperty;
|
|
4
|
+
const toString = ObjProto.toString;
|
|
5
5
|
|
|
6
6
|
export const isArray =
|
|
7
7
|
nativeIsArray ||
|
|
8
8
|
function (obj: any): obj is any[] {
|
|
9
|
-
return toString.call(obj) === '[object Array]'
|
|
10
|
-
}
|
|
9
|
+
return toString.call(obj) === '[object Array]';
|
|
10
|
+
};
|
|
11
11
|
export const isUint8Array = function (x: unknown): x is Uint8Array {
|
|
12
|
-
return toString.call(x) === '[object Uint8Array]'
|
|
13
|
-
}
|
|
12
|
+
return toString.call(x) === '[object Uint8Array]';
|
|
13
|
+
};
|
|
14
14
|
// from a comment on http://dbj.org/dbj/?p=286
|
|
15
15
|
// fails on only one very rare and deliberate custom object:
|
|
16
16
|
// let bomb = { toString : undefined, valueOf: function(o) { return "function BOMBA!"; }};
|
|
17
17
|
export const isFunction = function (f: any): f is (...args: any[]) => any {
|
|
18
|
-
return typeof f === 'function'
|
|
19
|
-
}
|
|
18
|
+
return typeof f === 'function';
|
|
19
|
+
};
|
|
20
20
|
// Underscore Addons
|
|
21
21
|
export const isObject = function (x: unknown): x is Record<string, any> {
|
|
22
|
-
return x === Object(x) && !isArray(x)
|
|
23
|
-
}
|
|
22
|
+
return x === Object(x) && !isArray(x);
|
|
23
|
+
};
|
|
24
24
|
export const isEmptyObject = function (x: unknown): x is Record<string, any> {
|
|
25
25
|
if (isObject(x)) {
|
|
26
26
|
for (const key in x) {
|
|
27
27
|
if (hasOwnProperty.call(x, key)) {
|
|
28
|
-
return false
|
|
28
|
+
return false;
|
|
29
29
|
}
|
|
30
30
|
}
|
|
31
|
-
return true
|
|
31
|
+
return true;
|
|
32
32
|
}
|
|
33
|
-
return false
|
|
34
|
-
}
|
|
33
|
+
return false;
|
|
34
|
+
};
|
|
35
35
|
export const isUndefined = function (x: unknown): x is undefined {
|
|
36
|
-
return x === void 0
|
|
37
|
-
}
|
|
36
|
+
return x === void 0;
|
|
37
|
+
};
|
|
38
38
|
|
|
39
39
|
export const isString = function (x: unknown): x is string {
|
|
40
|
-
return toString.call(x) == '[object String]'
|
|
41
|
-
}
|
|
40
|
+
return toString.call(x) == '[object String]';
|
|
41
|
+
};
|
|
42
42
|
|
|
43
43
|
export const isEmptyString = function (x: unknown): boolean {
|
|
44
|
-
return isString(x) && x.trim().length === 0
|
|
45
|
-
}
|
|
44
|
+
return isString(x) && x.trim().length === 0;
|
|
45
|
+
};
|
|
46
46
|
|
|
47
47
|
export const isNull = function (x: unknown): x is null {
|
|
48
|
-
return x === null
|
|
49
|
-
}
|
|
48
|
+
return x === null;
|
|
49
|
+
};
|
|
50
50
|
|
|
51
51
|
/*
|
|
52
52
|
sometimes you want to check if something is null or undefined
|
|
53
53
|
that's what this is for
|
|
54
54
|
*/
|
|
55
55
|
export const isNullish = function (x: unknown): x is null | undefined {
|
|
56
|
-
return isUndefined(x) || isNull(x)
|
|
57
|
-
}
|
|
56
|
+
return isUndefined(x) || isNull(x);
|
|
57
|
+
};
|
|
58
58
|
|
|
59
59
|
export const isDate = function (x: unknown): x is Date {
|
|
60
|
-
return toString.call(x) == '[object Date]'
|
|
61
|
-
}
|
|
60
|
+
return toString.call(x) == '[object Date]';
|
|
61
|
+
};
|
|
62
62
|
export const isNumber = function (x: unknown): x is number {
|
|
63
|
-
return toString.call(x) == '[object Number]'
|
|
64
|
-
}
|
|
63
|
+
return toString.call(x) == '[object Number]';
|
|
64
|
+
};
|
|
65
65
|
export const isBoolean = function (x: unknown): x is boolean {
|
|
66
|
-
return toString.call(x) === '[object Boolean]'
|
|
67
|
-
}
|
|
66
|
+
return toString.call(x) === '[object Boolean]';
|
|
67
|
+
};
|
|
68
68
|
|
|
69
69
|
export const isFormData = (x: unknown): x is FormData => {
|
|
70
|
-
return x instanceof FormData
|
|
71
|
-
}
|
|
70
|
+
return x instanceof FormData;
|
|
71
|
+
};
|
|
72
72
|
|
|
73
73
|
export const isFile = (x: unknown): x is File => {
|
|
74
|
-
return x instanceof File
|
|
75
|
-
}
|
|
74
|
+
return x instanceof File;
|
|
75
|
+
};
|
package/src/version.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const version =
|
|
1
|
+
export const version = '1.0.1-beta.3';
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
package com.multiplayer.sessionrecordernative
|
|
2
|
-
|
|
3
|
-
import com.facebook.react.bridge.ReactApplicationContext
|
|
4
|
-
import com.facebook.react.bridge.ReactMethod
|
|
5
|
-
import com.facebook.react.bridge.Promise
|
|
6
|
-
import com.facebook.react.bridge.Callback
|
|
7
|
-
import com.facebook.react.bridge.ReadableMap
|
|
8
|
-
import com.facebook.react.bridge.Arguments
|
|
9
|
-
import com.facebook.react.bridge.WritableMap
|
|
10
|
-
import com.facebook.react.modules.core.DeviceEventManagerModule
|
|
11
|
-
import com.facebook.react.bridge.TurboModule
|
|
12
|
-
|
|
13
|
-
abstract class SessionRecorderNativeModuleSpec : TurboModule {
|
|
14
|
-
|
|
15
|
-
@ReactMethod
|
|
16
|
-
abstract fun captureAndMask(promise: Promise)
|
|
17
|
-
|
|
18
|
-
@ReactMethod
|
|
19
|
-
abstract fun captureAndMaskWithOptions(options: ReadableMap, promise: Promise)
|
|
20
|
-
|
|
21
|
-
@ReactMethod
|
|
22
|
-
abstract fun startGestureRecording(promise: Promise)
|
|
23
|
-
|
|
24
|
-
@ReactMethod
|
|
25
|
-
abstract fun stopGestureRecording(promise: Promise)
|
|
26
|
-
|
|
27
|
-
@ReactMethod
|
|
28
|
-
abstract fun isGestureRecordingActive(promise: Promise)
|
|
29
|
-
|
|
30
|
-
@ReactMethod
|
|
31
|
-
abstract fun setGestureCallback(callback: Callback)
|
|
32
|
-
|
|
33
|
-
@ReactMethod
|
|
34
|
-
abstract fun recordGesture(
|
|
35
|
-
gestureType: String,
|
|
36
|
-
x: Double,
|
|
37
|
-
y: Double,
|
|
38
|
-
target: String?,
|
|
39
|
-
metadata: ReadableMap?
|
|
40
|
-
)
|
|
41
|
-
|
|
42
|
-
@ReactMethod
|
|
43
|
-
fun addListener(eventName: String) {
|
|
44
|
-
// Required for RN event emitter contracts
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
@ReactMethod
|
|
48
|
-
fun removeListeners(count: Int) {
|
|
49
|
-
// Required for RN event emitter contracts
|
|
50
|
-
}
|
|
51
|
-
}
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
package com.xxx
|
|
2
|
-
|
|
3
|
-
import com.facebook.react.bridge.ReactApplicationContext
|
|
4
|
-
import com.facebook.react.module.annotations.ReactModule
|
|
5
|
-
|
|
6
|
-
@ReactModule(name = XxxModule.NAME)
|
|
7
|
-
class XxxModule(reactContext: ReactApplicationContext) :
|
|
8
|
-
NativeXxxSpec(reactContext) {
|
|
9
|
-
|
|
10
|
-
override fun getName(): String {
|
|
11
|
-
return NAME
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
// Example method
|
|
15
|
-
// See https://reactnative.dev/docs/native-modules-android
|
|
16
|
-
override fun multiply(a: Double, b: Double): Double {
|
|
17
|
-
return a * b
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
companion object {
|
|
21
|
-
const val NAME = "Xxx"
|
|
22
|
-
}
|
|
23
|
-
}
|
package/ios/Xxx.h
DELETED
package/ios/Xxx.mm
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
#import "Xxx.h"
|
|
2
|
-
|
|
3
|
-
@implementation Xxx
|
|
4
|
-
- (NSNumber *)multiply:(double)a b:(double)b {
|
|
5
|
-
NSNumber *result = @(a * b);
|
|
6
|
-
|
|
7
|
-
return result;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:
|
|
11
|
-
(const facebook::react::ObjCTurboModule::InitParams &)params
|
|
12
|
-
{
|
|
13
|
-
return std::make_shared<facebook::react::NativeXxxSpecJSI>(params);
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
+ (NSString *)moduleName
|
|
17
|
-
{
|
|
18
|
-
return @"Xxx";
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
@end
|