@datadog/mobile-react-native-session-replay 2.12.4 → 2.13.0

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.
Files changed (60) hide show
  1. package/DatadogSDKReactNativeSessionReplay.podspec +6 -2
  2. package/README.md +90 -1
  3. package/android/build.gradle +3 -2
  4. package/android/src/main/kotlin/com/datadog/reactnative/sessionreplay/DdSessionReplayImplementation.kt +2 -2
  5. package/android/src/main/kotlin/com/datadog/reactnative/sessionreplay/ReactNativeInternalCallback.kt +121 -0
  6. package/android/src/main/kotlin/com/datadog/reactnative/sessionreplay/ReactNativeSessionReplayExtensionSupport.kt +5 -1
  7. package/android/src/main/kotlin/com/datadog/reactnative/sessionreplay/mappers/ReactViewGroupMapper.kt +1 -0
  8. package/android/src/main/kotlin/com/datadog/reactnative/sessionreplay/mappers/SvgViewMapper.kt +145 -0
  9. package/android/src/main/kotlin/com/datadog/reactnative/sessionreplay/views/DdPrivacyView.kt +10 -0
  10. package/android/src/newarch/kotlin/com/datadog/reactnative/sessionreplay/views/DdPrivacyViewManager.kt +13 -0
  11. package/android/src/oldarch/kotlin/com/datadog/reactnative/sessionreplay/views/DdPrivacyViewManager.kt +13 -0
  12. package/android/src/test/kotlin/com/datadog/reactnative/sessionreplay/DdSessionReplayImplementationTest.kt +8 -0
  13. package/android/src/test/kotlin/com/datadog/reactnative/sessionreplay/ReactNativeSessionReplayExtensionSupportTest.kt +21 -5
  14. package/assets/assets.bin +0 -0
  15. package/assets/assets.json +1 -0
  16. package/ios/Sources/DdPrivacyViewFabric.h +28 -0
  17. package/ios/Sources/DdPrivacyViewFabric.mm +22 -4
  18. package/ios/Sources/DdPrivacyViewPaper.m +24 -0
  19. package/ios/Sources/DdSessionReplayImplementation.swift +34 -6
  20. package/ios/Sources/SvgViewRecorder.swift +233 -0
  21. package/ios/Sources/Utils/Bundle+SessionReplay.swift +21 -0
  22. package/lib/commonjs/components/SessionReplayView/PrivacyView.js +2 -0
  23. package/lib/commonjs/components/SessionReplayView/PrivacyView.js.map +1 -1
  24. package/lib/commonjs/metro/index.js +75 -0
  25. package/lib/commonjs/metro/index.js.map +1 -0
  26. package/lib/commonjs/metro/processing.js +97 -0
  27. package/lib/commonjs/metro/processing.js.map +1 -0
  28. package/lib/commonjs/metro/utils.js +20 -0
  29. package/lib/commonjs/metro/utils.js.map +1 -0
  30. package/lib/commonjs/specs/DdPrivacyViewNativeComponent.js.map +1 -1
  31. package/lib/module/components/SessionReplayView/PrivacyView.js +2 -0
  32. package/lib/module/components/SessionReplayView/PrivacyView.js.map +1 -1
  33. package/lib/module/metro/index.js +68 -0
  34. package/lib/module/metro/index.js.map +1 -0
  35. package/lib/module/metro/processing.js +90 -0
  36. package/lib/module/metro/processing.js.map +1 -0
  37. package/lib/module/metro/utils.js +14 -0
  38. package/lib/module/metro/utils.js.map +1 -0
  39. package/lib/module/specs/DdPrivacyViewNativeComponent.js.map +1 -1
  40. package/lib/typescript/components/SessionReplayView/PrivacyView.d.ts +10 -1
  41. package/lib/typescript/components/SessionReplayView/PrivacyView.d.ts.map +1 -1
  42. package/lib/typescript/metro/index.d.ts +2 -0
  43. package/lib/typescript/metro/index.d.ts.map +1 -0
  44. package/lib/typescript/metro/processing.d.ts +9 -0
  45. package/lib/typescript/metro/processing.d.ts.map +1 -0
  46. package/lib/typescript/metro/utils.d.ts +2 -0
  47. package/lib/typescript/metro/utils.d.ts.map +1 -0
  48. package/lib/typescript/specs/DdPrivacyViewNativeComponent.d.ts +8 -0
  49. package/lib/typescript/specs/DdPrivacyViewNativeComponent.d.ts.map +1 -1
  50. package/lib/typescript/types/DdPrivacyView.d.ts +8 -0
  51. package/lib/typescript/types/DdPrivacyView.d.ts.map +1 -1
  52. package/metro.js +7 -0
  53. package/package.json +9 -3
  54. package/scripts/build-assets.js +31 -0
  55. package/src/components/SessionReplayView/PrivacyView.tsx +11 -0
  56. package/src/metro/index.ts +82 -0
  57. package/src/metro/processing.ts +119 -0
  58. package/src/metro/utils.ts +17 -0
  59. package/src/specs/DdPrivacyViewNativeComponent.ts +9 -0
  60. package/src/types/DdPrivacyView.ts +9 -0
@@ -0,0 +1,119 @@
1
+ /*
2
+ * Unless explicitly stated otherwise all files in this repository are licensed under the Apache License Version 2.0.
3
+ * This product includes software developed at Datadog (https://www.datadoghq.com/).
4
+ * Copyright 2016-Present Datadog, Inc.
5
+ */
6
+
7
+ import fs from 'fs';
8
+ import path from 'path';
9
+
10
+ type SvgIndexEntry = {
11
+ offset: number;
12
+ length: number;
13
+ };
14
+
15
+ type SvgIndex = Record<string, SvgIndexEntry>;
16
+
17
+ /**
18
+ * Removes the binary and JSON asset files from the specified directory.
19
+ * This is used to clean up corrupted or partial asset files before regenerating them.
20
+ *
21
+ * @param binPath - Absolute path to the assets.bin file
22
+ * @param jsonPath - Absolute path to the assets.json file
23
+ */
24
+ function cleanupFiles(binPath: string, jsonPath: string) {
25
+ try {
26
+ fs.unlinkSync(binPath);
27
+ } catch (err) {
28
+ console.warn('[cleanupFiles] Failed to cleanup binary assets', err);
29
+ }
30
+
31
+ try {
32
+ fs.unlinkSync(jsonPath);
33
+ } catch (err) {
34
+ console.warn('[cleanupFiles] Failed to cleanup json assets', err);
35
+ }
36
+ }
37
+
38
+ /**
39
+ * Merges all individual SVG files into assets.bin and creates an index in assets.json.
40
+ * This function reads all .svg files from the assets directory and packs them into
41
+ * a single binary file with an accompanying JSON index for efficient lookup.
42
+ *
43
+ * @param assetsDir - Absolute path to the assets directory
44
+ */
45
+ export function mergeSvgAssets(assetsDir: string) {
46
+ try {
47
+ const binName = 'assets.bin';
48
+ const jsonName = 'assets.json';
49
+
50
+ const binPath = path.resolve(assetsDir, binName);
51
+ const jsonPath = path.resolve(assetsDir, jsonName);
52
+
53
+ let index: SvgIndex = {};
54
+ let offset = 0;
55
+
56
+ if (!fs.existsSync(assetsDir)) {
57
+ fs.mkdirSync(assetsDir, { recursive: true });
58
+ }
59
+
60
+ try {
61
+ const jsonData = fs.readFileSync(jsonPath, 'utf8');
62
+ const binStats = fs.statSync(binPath);
63
+
64
+ index = JSON.parse(jsonData) as SvgIndex;
65
+ offset = binStats.size;
66
+ } catch (err) {
67
+ console.warn(
68
+ '[mergeSvgAssets] Assets missing or corrupted, starting fresh'
69
+ );
70
+ index = {};
71
+ offset = 0;
72
+ cleanupFiles(binPath, jsonPath);
73
+ }
74
+
75
+ const files = fs
76
+ .readdirSync(assetsDir)
77
+ .filter(f => f.endsWith('.svg'))
78
+ .sort();
79
+
80
+ let added = 0;
81
+
82
+ for (const f of files) {
83
+ const id = path.basename(f, path.extname(f));
84
+ if (index[id]) {
85
+ continue;
86
+ }
87
+
88
+ try {
89
+ const svg = fs.readFileSync(path.join(assetsDir, f), 'utf8');
90
+ const buf = Buffer.from(svg, 'utf8');
91
+ const length = buf.length;
92
+
93
+ fs.appendFileSync(binPath, buf);
94
+ index[id] = { offset, length };
95
+ offset += length;
96
+ added++;
97
+ } catch (err) {
98
+ console.warn(
99
+ `[SessionReplayAssetBundler] Failed to process ${f}:`,
100
+ err
101
+ );
102
+ }
103
+ }
104
+
105
+ fs.writeFileSync(jsonPath, JSON.stringify(index, null, 2));
106
+ if (added > 0) {
107
+ console.info(
108
+ `[SessionReplayAssetBundler] Packed ${added} new Session Replay SVG assets → total: ${
109
+ Object.keys(index).length
110
+ }`
111
+ );
112
+ }
113
+ } catch (err) {
114
+ console.error(
115
+ '[mergeSvgAssets] Unexpected error during asset merge',
116
+ err
117
+ );
118
+ }
119
+ }
@@ -0,0 +1,17 @@
1
+ /*
2
+ * Unless explicitly stated otherwise all files in this repository are licensed under the Apache License Version 2.0.
3
+ * This product includes software developed at Datadog (https://www.datadoghq.com/).
4
+ * Copyright 2016-Present Datadog, Inc.
5
+ */
6
+
7
+ export function debounce<T extends (...args: any[]) => void>(
8
+ fn: T,
9
+ ms: number
10
+ ): T {
11
+ let timer: NodeJS.Timeout;
12
+
13
+ return ((...args: Parameters<T>) => {
14
+ clearTimeout(timer);
15
+ timer = setTimeout(() => fn(...args), ms);
16
+ }) as T;
17
+ }
@@ -7,11 +7,20 @@
7
7
  import codegenNativeComponent from 'react-native/Libraries/Utilities/codegenNativeComponent';
8
8
  import type { HostComponent, ViewProps } from 'react-native';
9
9
 
10
+ type Attributes = {
11
+ type?: string;
12
+ hash?: string;
13
+ width?: string;
14
+ height?: string;
15
+ };
16
+
10
17
  interface DdPrivacyViewProps extends ViewProps {
11
18
  textAndInputPrivacy: string;
12
19
  imagePrivacy: string;
13
20
  touchPrivacy: string;
14
21
  hide: boolean;
22
+ nativeID: string;
23
+ attributes: Attributes;
15
24
  }
16
25
 
17
26
  export default codegenNativeComponent<DdPrivacyViewProps>('DdPrivacyView', {
@@ -6,9 +6,18 @@
6
6
 
7
7
  import type { ViewProps } from 'react-native';
8
8
 
9
+ export type Attributes = {
10
+ type?: string;
11
+ hash?: string;
12
+ width?: string;
13
+ height?: string;
14
+ };
15
+
9
16
  export interface DdPrivacyViewProps extends ViewProps {
10
17
  textAndInputPrivacy: string;
11
18
  imagePrivacy: string;
12
19
  touchPrivacy: string;
13
20
  hide: boolean;
21
+ nativeID: string;
22
+ attributes: Attributes;
14
23
  }