@multiplayer-app/session-recorder-react-native 1.0.1-beta.3 → 1.0.1-beta.4
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/LICENSE +1 -2
- package/README.md +216 -155
- package/SessionRecorderNative.podspec +9 -14
- package/android/build.gradle +21 -44
- package/android/gradle.properties +4 -4
- package/android/src/main/AndroidManifest.xml +2 -0
- package/android/src/main/java/com/multiplayer/sessionrecordernative/SessionRecorderNativeConfig.kt +52 -0
- package/android/src/main/java/com/multiplayer/sessionrecordernative/SessionRecorderNativeModule.kt +860 -0
- package/android/src/main/java/com/multiplayer/sessionrecordernative/SessionRecorderNativeModuleSpec.kt +51 -0
- package/android/src/main/java/com/multiplayer/sessionrecordernative/SessionRecorderNativePackage.kt +33 -0
- package/android/src/main/java/com/multiplayer/sessionrecordernative/model/TargetInfo.kt +9 -0
- package/android/src/main/java/com/multiplayer/sessionrecordernative/util/ViewUtils.kt +72 -0
- package/android/src/main/java/com/xxx/XxxModule.kt +23 -0
- package/ios/SessionRecorderNative.podspec +4 -2
- package/ios/SessionRecorderNative.swift +1 -1
- package/ios/SessionRecorderNativeSpec.swift +3 -3
- package/ios/Xxx.h +5 -0
- package/ios/Xxx.mm +21 -0
- package/lib/module/components/ScreenRecorderView/ScreenRecorderView.js +23 -0
- package/lib/module/components/ScreenRecorderView/ScreenRecorderView.js.map +1 -0
- package/lib/module/components/ScreenRecorderView/index.js +4 -0
- package/lib/module/components/ScreenRecorderView/index.js.map +1 -0
- package/lib/module/components/SessionRecorderWidget/ErrorBanner.js +64 -0
- package/lib/module/components/SessionRecorderWidget/ErrorBanner.js.map +1 -0
- package/lib/module/components/SessionRecorderWidget/FinalPopover.js +74 -0
- package/lib/module/components/SessionRecorderWidget/FinalPopover.js.map +1 -0
- package/lib/module/components/SessionRecorderWidget/FloatingButton.js +191 -0
- package/lib/module/components/SessionRecorderWidget/FloatingButton.js.map +1 -0
- package/lib/module/components/SessionRecorderWidget/InitialPopover.js +138 -0
- package/lib/module/components/SessionRecorderWidget/InitialPopover.js.map +1 -0
- package/lib/module/components/SessionRecorderWidget/ModalContainer.js +177 -0
- package/lib/module/components/SessionRecorderWidget/ModalContainer.js.map +1 -0
- package/lib/module/components/SessionRecorderWidget/ModalHeader.js +27 -0
- package/lib/module/components/SessionRecorderWidget/ModalHeader.js.map +1 -0
- package/lib/module/components/SessionRecorderWidget/SessionRecorderWidget.js +133 -0
- package/lib/module/components/SessionRecorderWidget/SessionRecorderWidget.js.map +1 -0
- package/lib/module/components/SessionRecorderWidget/icons.js +93 -0
- package/lib/module/components/SessionRecorderWidget/icons.js.map +1 -0
- package/lib/module/components/SessionRecorderWidget/index.js +5 -0
- package/lib/module/components/SessionRecorderWidget/index.js.map +1 -0
- package/lib/module/components/SessionRecorderWidget/styles.js +173 -0
- package/lib/module/components/SessionRecorderWidget/styles.js.map +1 -0
- package/lib/module/components/index.js +5 -0
- package/lib/module/components/index.js.map +1 -0
- package/lib/module/config/constants.js +42 -0
- package/lib/module/config/constants.js.map +1 -0
- package/lib/module/config/defaults.js +81 -0
- package/lib/module/config/defaults.js.map +1 -0
- package/lib/module/config/index.js +9 -0
- package/lib/module/config/index.js.map +1 -0
- package/lib/module/config/masking.js +35 -0
- package/lib/module/config/masking.js.map +1 -0
- package/lib/module/config/session-recorder.js +44 -0
- package/lib/module/config/session-recorder.js.map +1 -0
- package/lib/module/config/validators.js +28 -0
- package/lib/module/config/validators.js.map +1 -0
- package/lib/module/config/widget.js +35 -0
- package/lib/module/config/widget.js.map +1 -0
- package/lib/module/context/SessionRecorderContext.js +93 -0
- package/lib/module/context/SessionRecorderContext.js.map +1 -0
- package/lib/module/context/SessionRecorderStore.js +12 -0
- package/lib/module/context/SessionRecorderStore.js.map +1 -0
- package/lib/module/context/useSessionRecorderStore.js +20 -0
- package/lib/module/context/useSessionRecorderStore.js.map +1 -0
- package/lib/module/context/useStoreSelector.js +27 -0
- package/lib/module/context/useStoreSelector.js.map +1 -0
- package/lib/module/index.js +13 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/native/SessionRecorderNative.js +74 -0
- package/lib/module/native/SessionRecorderNative.js.map +1 -0
- package/lib/module/native/index.js +4 -0
- package/lib/module/native/index.js.map +1 -0
- package/lib/module/otel/helpers.js +218 -0
- package/lib/module/otel/helpers.js.map +1 -0
- package/lib/module/otel/index.js +95 -0
- package/lib/module/otel/index.js.map +1 -0
- package/lib/module/otel/instrumentations/index.js +102 -0
- package/lib/module/otel/instrumentations/index.js.map +1 -0
- package/lib/module/package.json +1 -0
- package/lib/module/patch/index.js +4 -0
- package/lib/module/patch/index.js.map +1 -0
- package/lib/module/patch/xhr.js +116 -0
- package/lib/module/patch/xhr.js.map +1 -0
- package/lib/module/recorder/eventExporter.js +130 -0
- package/lib/module/recorder/eventExporter.js.map +1 -0
- package/lib/module/recorder/gestureRecorder.js +641 -0
- package/lib/module/recorder/gestureRecorder.js.map +1 -0
- package/lib/module/recorder/index.js +168 -0
- package/lib/module/recorder/index.js.map +1 -0
- package/lib/module/recorder/navigationTracker.js +228 -0
- package/lib/module/recorder/navigationTracker.js.map +1 -0
- package/lib/module/recorder/screenRecorder.js +495 -0
- package/lib/module/recorder/screenRecorder.js.map +1 -0
- package/lib/module/services/api.service.js +149 -0
- package/lib/module/services/api.service.js.map +1 -0
- package/lib/module/services/network.service.js +178 -0
- package/lib/module/services/network.service.js.map +1 -0
- package/lib/module/services/screenMaskingService.js +107 -0
- package/lib/module/services/screenMaskingService.js.map +1 -0
- package/lib/module/services/storage.service.js +179 -0
- package/lib/module/services/storage.service.js.map +1 -0
- package/lib/module/session-recorder.js +541 -0
- package/lib/module/session-recorder.js.map +1 -0
- package/lib/module/types/configs.js +4 -0
- package/lib/module/types/configs.js.map +1 -0
- package/lib/module/types/expo-constants.d.js +2 -0
- package/lib/module/types/expo-constants.d.js.map +1 -0
- package/lib/module/types/index.js +11 -0
- package/lib/module/types/index.js.map +1 -0
- package/lib/module/types/session-recorder.js +68 -0
- package/lib/module/types/session-recorder.js.map +1 -0
- package/lib/module/types/session.js +9 -0
- package/lib/module/types/session.js.map +1 -0
- package/lib/module/utils/app-metadata.js +28 -0
- package/lib/module/utils/app-metadata.js.map +1 -0
- package/lib/module/utils/constants.optional.expo.js +6 -0
- package/lib/module/utils/constants.optional.expo.js.map +1 -0
- package/lib/module/utils/constants.optional.js +8 -0
- package/lib/module/utils/constants.optional.js.map +1 -0
- package/lib/module/utils/createStore.js +27 -0
- package/lib/module/utils/createStore.js.map +1 -0
- package/lib/module/utils/index.js +11 -0
- package/lib/module/utils/index.js.map +1 -0
- package/lib/module/utils/logger.js +193 -0
- package/lib/module/utils/logger.js.map +1 -0
- package/lib/module/utils/platform.js +340 -0
- package/lib/module/utils/platform.js.map +1 -0
- package/lib/module/utils/request-utils.js +58 -0
- package/lib/module/utils/request-utils.js.map +1 -0
- package/lib/module/utils/rrweb-events.js +276 -0
- package/lib/module/utils/rrweb-events.js.map +1 -0
- package/lib/module/utils/session.js +21 -0
- package/lib/module/utils/session.js.map +1 -0
- package/lib/module/utils/shallowEqual.js +17 -0
- package/lib/module/utils/shallowEqual.js.map +1 -0
- package/lib/module/utils/time.js +17 -0
- package/lib/module/utils/time.js.map +1 -0
- package/lib/module/utils/type-utils.js +69 -0
- package/lib/module/utils/type-utils.js.map +1 -0
- package/lib/module/version.js +4 -0
- package/lib/module/version.js.map +1 -0
- package/lib/typescript/package.json +1 -0
- package/lib/typescript/src/components/ScreenRecorderView/ScreenRecorderView.d.ts +6 -0
- package/lib/typescript/src/components/ScreenRecorderView/ScreenRecorderView.d.ts.map +1 -0
- package/lib/typescript/src/components/ScreenRecorderView/index.d.ts +2 -0
- package/lib/typescript/src/components/ScreenRecorderView/index.d.ts.map +1 -0
- package/{dist → lib/typescript/src}/components/SessionRecorderWidget/ErrorBanner.d.ts +1 -0
- package/lib/typescript/src/components/SessionRecorderWidget/ErrorBanner.d.ts.map +1 -0
- package/{dist → lib/typescript/src}/components/SessionRecorderWidget/FinalPopover.d.ts +2 -1
- package/lib/typescript/src/components/SessionRecorderWidget/FinalPopover.d.ts.map +1 -0
- package/{dist → lib/typescript/src}/components/SessionRecorderWidget/FloatingButton.d.ts +1 -0
- package/lib/typescript/src/components/SessionRecorderWidget/FloatingButton.d.ts.map +1 -0
- package/{dist → lib/typescript/src}/components/SessionRecorderWidget/InitialPopover.d.ts +2 -1
- package/lib/typescript/src/components/SessionRecorderWidget/InitialPopover.d.ts.map +1 -0
- package/{dist → lib/typescript/src}/components/SessionRecorderWidget/ModalContainer.d.ts +1 -0
- package/lib/typescript/src/components/SessionRecorderWidget/ModalContainer.d.ts.map +1 -0
- package/{dist → lib/typescript/src}/components/SessionRecorderWidget/ModalHeader.d.ts +1 -0
- package/lib/typescript/src/components/SessionRecorderWidget/ModalHeader.d.ts.map +1 -0
- package/{dist → lib/typescript/src}/components/SessionRecorderWidget/SessionRecorderWidget.d.ts +1 -0
- package/lib/typescript/src/components/SessionRecorderWidget/SessionRecorderWidget.d.ts.map +1 -0
- package/{dist → lib/typescript/src}/components/SessionRecorderWidget/icons.d.ts +1 -0
- package/lib/typescript/src/components/SessionRecorderWidget/icons.d.ts.map +1 -0
- package/lib/typescript/src/components/SessionRecorderWidget/index.d.ts +3 -0
- package/lib/typescript/src/components/SessionRecorderWidget/index.d.ts.map +1 -0
- package/{dist → lib/typescript/src}/components/SessionRecorderWidget/styles.d.ts +4 -3
- package/lib/typescript/src/components/SessionRecorderWidget/styles.d.ts.map +1 -0
- package/{dist → lib/typescript/src}/components/index.d.ts +1 -0
- package/lib/typescript/src/components/index.d.ts.map +1 -0
- package/{dist → lib/typescript/src}/config/constants.d.ts +1 -0
- package/lib/typescript/src/config/constants.d.ts.map +1 -0
- package/{dist → lib/typescript/src}/config/defaults.d.ts +2 -1
- package/lib/typescript/src/config/defaults.d.ts.map +1 -0
- package/{dist → lib/typescript/src}/config/index.d.ts +1 -0
- package/lib/typescript/src/config/index.d.ts.map +1 -0
- package/lib/typescript/src/config/masking.d.ts +3 -0
- package/lib/typescript/src/config/masking.d.ts.map +1 -0
- package/lib/typescript/src/config/session-recorder.d.ts +3 -0
- package/lib/typescript/src/config/session-recorder.d.ts.map +1 -0
- package/{dist → lib/typescript/src}/config/validators.d.ts +1 -0
- package/lib/typescript/src/config/validators.d.ts.map +1 -0
- package/{dist → lib/typescript/src}/config/widget.d.ts +2 -1
- package/lib/typescript/src/config/widget.d.ts.map +1 -0
- package/{dist → lib/typescript/src}/context/SessionRecorderContext.d.ts +3 -2
- package/lib/typescript/src/context/SessionRecorderContext.d.ts.map +1 -0
- package/{dist → lib/typescript/src}/context/SessionRecorderStore.d.ts +2 -1
- package/lib/typescript/src/context/SessionRecorderStore.d.ts.map +1 -0
- package/{dist → lib/typescript/src}/context/useSessionRecorderStore.d.ts +2 -1
- package/lib/typescript/src/context/useSessionRecorderStore.d.ts.map +1 -0
- package/{dist → lib/typescript/src}/context/useStoreSelector.d.ts +2 -1
- package/lib/typescript/src/context/useStoreSelector.d.ts.map +1 -0
- package/{dist → lib/typescript/src}/index.d.ts +1 -0
- package/lib/typescript/src/index.d.ts.map +1 -0
- package/{dist → lib/typescript/src}/native/SessionRecorderNative.d.ts +21 -3
- package/lib/typescript/src/native/SessionRecorderNative.d.ts.map +1 -0
- package/{dist → lib/typescript/src}/native/index.d.ts +1 -0
- package/lib/typescript/src/native/index.d.ts.map +1 -0
- package/{dist → lib/typescript/src}/otel/helpers.d.ts +3 -2
- package/lib/typescript/src/otel/helpers.d.ts.map +1 -0
- package/{dist → lib/typescript/src}/otel/index.d.ts +2 -2
- package/lib/typescript/src/otel/index.d.ts.map +1 -0
- package/{dist → lib/typescript/src}/otel/instrumentations/index.d.ts +2 -1
- package/lib/typescript/src/otel/instrumentations/index.d.ts.map +1 -0
- package/lib/typescript/src/patch/index.d.ts +2 -0
- package/lib/typescript/src/patch/index.d.ts.map +1 -0
- package/{dist → lib/typescript/src}/patch/xhr.d.ts +1 -0
- package/lib/typescript/src/patch/xhr.d.ts.map +1 -0
- package/{dist → lib/typescript/src}/recorder/eventExporter.d.ts +2 -1
- package/lib/typescript/src/recorder/eventExporter.d.ts.map +1 -0
- package/{dist → lib/typescript/src}/recorder/gestureRecorder.d.ts +3 -2
- package/lib/typescript/src/recorder/gestureRecorder.d.ts.map +1 -0
- package/{dist → lib/typescript/src}/recorder/index.d.ts +3 -2
- package/lib/typescript/src/recorder/index.d.ts.map +1 -0
- package/{dist → lib/typescript/src}/recorder/navigationTracker.d.ts +2 -1
- package/lib/typescript/src/recorder/navigationTracker.d.ts.map +1 -0
- package/{dist → lib/typescript/src}/recorder/screenRecorder.d.ts +4 -4
- package/lib/typescript/src/recorder/screenRecorder.d.ts.map +1 -0
- package/{dist → lib/typescript/src}/services/api.service.d.ts +2 -1
- package/lib/typescript/src/services/api.service.d.ts.map +1 -0
- package/{dist → lib/typescript/src}/services/network.service.d.ts +1 -0
- package/lib/typescript/src/services/network.service.d.ts.map +1 -0
- package/{dist → lib/typescript/src}/services/screenMaskingService.d.ts +2 -1
- package/lib/typescript/src/services/screenMaskingService.d.ts.map +1 -0
- package/{dist → lib/typescript/src}/services/storage.service.d.ts +2 -1
- package/lib/typescript/src/services/storage.service.d.ts.map +1 -0
- package/{dist → lib/typescript/src}/session-recorder.d.ts +3 -2
- package/lib/typescript/src/session-recorder.d.ts.map +1 -0
- package/{dist → lib/typescript/src}/types/configs.d.ts +3 -2
- package/lib/typescript/src/types/configs.d.ts.map +1 -0
- package/{dist → lib/typescript/src}/types/index.d.ts +1 -0
- package/lib/typescript/src/types/index.d.ts.map +1 -0
- package/{dist → lib/typescript/src}/types/session-recorder.d.ts +3 -2
- package/lib/typescript/src/types/session-recorder.d.ts.map +1 -0
- package/{dist → lib/typescript/src}/types/session.d.ts +1 -0
- package/lib/typescript/src/types/session.d.ts.map +1 -0
- package/{dist → lib/typescript/src}/utils/app-metadata.d.ts +1 -0
- package/lib/typescript/src/utils/app-metadata.d.ts.map +1 -0
- package/{dist → lib/typescript/src}/utils/constants.optional.d.ts +1 -0
- package/lib/typescript/src/utils/constants.optional.d.ts.map +1 -0
- package/{dist → lib/typescript/src}/utils/constants.optional.expo.d.ts +1 -0
- package/lib/typescript/src/utils/constants.optional.expo.d.ts.map +1 -0
- package/{dist → lib/typescript/src}/utils/createStore.d.ts +1 -0
- package/lib/typescript/src/utils/createStore.d.ts.map +1 -0
- package/{dist → lib/typescript/src}/utils/index.d.ts +1 -0
- package/lib/typescript/src/utils/index.d.ts.map +1 -0
- package/{dist → lib/typescript/src}/utils/logger.d.ts +1 -0
- package/lib/typescript/src/utils/logger.d.ts.map +1 -0
- package/{dist → lib/typescript/src}/utils/platform.d.ts +2 -1
- package/lib/typescript/src/utils/platform.d.ts.map +1 -0
- package/{dist → lib/typescript/src}/utils/request-utils.d.ts +1 -0
- package/lib/typescript/src/utils/request-utils.d.ts.map +1 -0
- package/{dist → lib/typescript/src}/utils/rrweb-events.d.ts +2 -1
- package/lib/typescript/src/utils/rrweb-events.d.ts.map +1 -0
- package/{dist → lib/typescript/src}/utils/session.d.ts +1 -0
- package/lib/typescript/src/utils/session.d.ts.map +1 -0
- package/{dist → lib/typescript/src}/utils/shallowEqual.d.ts +1 -0
- package/lib/typescript/src/utils/shallowEqual.d.ts.map +1 -0
- package/{dist → lib/typescript/src}/utils/time.d.ts +1 -0
- package/lib/typescript/src/utils/time.d.ts.map +1 -0
- package/{dist → lib/typescript/src}/utils/type-utils.d.ts +1 -0
- package/lib/typescript/src/utils/type-utils.d.ts.map +1 -0
- package/{dist → lib/typescript/src}/version.d.ts +1 -0
- package/lib/typescript/src/version.d.ts.map +1 -0
- package/package.json +133 -44
- package/src/components/ScreenRecorderView/ScreenRecorderView.tsx +20 -0
- package/src/components/SessionRecorderWidget/ErrorBanner.tsx +58 -0
- package/src/components/SessionRecorderWidget/FinalPopover.tsx +96 -0
- package/src/components/SessionRecorderWidget/FloatingButton.tsx +176 -0
- package/src/components/SessionRecorderWidget/InitialPopover.tsx +167 -0
- package/src/components/SessionRecorderWidget/ModalContainer.tsx +189 -0
- package/src/components/SessionRecorderWidget/ModalHeader.tsx +24 -0
- package/src/components/SessionRecorderWidget/SessionRecorderWidget.tsx +136 -0
- package/src/components/SessionRecorderWidget/icons.tsx +52 -0
- package/{dist/components/SessionRecorderWidget/index.d.ts → src/components/SessionRecorderWidget/index.ts} +1 -0
- package/src/components/SessionRecorderWidget/styles.ts +169 -0
- package/src/components/index.ts +2 -0
- package/src/config/constants.ts +68 -0
- package/src/config/defaults.ts +101 -0
- package/src/config/index.ts +6 -0
- package/src/config/masking.ts +34 -0
- package/src/config/session-recorder.ts +59 -0
- package/src/config/validators.ts +31 -0
- package/src/config/widget.ts +38 -0
- package/src/context/SessionRecorderContext.tsx +138 -0
- package/src/context/SessionRecorderStore.ts +21 -0
- package/src/context/useSessionRecorderStore.ts +27 -0
- package/src/context/useStoreSelector.ts +34 -0
- package/src/index.ts +10 -0
- package/src/native/SessionRecorderNative.ts +164 -0
- package/src/native/index.ts +1 -0
- package/src/otel/helpers.ts +274 -0
- package/src/otel/index.ts +135 -0
- package/src/otel/instrumentations/index.ts +115 -0
- package/src/patch/index.ts +1 -0
- package/src/patch/xhr.ts +149 -0
- package/src/recorder/eventExporter.ts +155 -0
- package/src/recorder/gestureRecorder.ts +681 -0
- package/src/recorder/index.ts +190 -0
- package/src/recorder/navigationTracker.ts +245 -0
- package/src/recorder/screenRecorder.ts +549 -0
- package/src/services/api.service.ts +215 -0
- package/src/services/network.service.ts +182 -0
- package/src/services/screenMaskingService.ts +122 -0
- package/src/services/storage.service.ts +219 -0
- package/src/session-recorder.ts +591 -0
- package/src/types/configs.ts +96 -0
- package/src/types/expo-constants.d.ts +7 -0
- package/src/types/index.ts +29 -0
- package/src/types/session-recorder.ts +386 -0
- package/src/types/session.ts +65 -0
- package/src/utils/app-metadata.ts +31 -0
- package/src/utils/constants.optional.expo.ts +5 -0
- package/src/utils/constants.optional.ts +16 -0
- package/src/utils/createStore.ts +29 -0
- package/src/utils/index.ts +8 -0
- package/src/utils/logger.ts +216 -0
- package/src/utils/platform.ts +370 -0
- package/src/utils/request-utils.ts +61 -0
- package/src/utils/rrweb-events.ts +316 -0
- package/src/utils/session.ts +19 -0
- package/src/utils/shallowEqual.ts +14 -0
- package/src/utils/time.ts +17 -0
- package/src/utils/type-utils.ts +75 -0
- package/src/version.ts +1 -0
- package/REACT_NATIVE_SETUP.md +0 -91
- package/android/gradle/wrapper/gradle-wrapper.jar +0 -0
- package/android/gradle/wrapper/gradle-wrapper.properties +0 -7
- package/android/gradlew +0 -249
- package/android/gradlew.bat +0 -92
- package/copy-react-native-dist.sh +0 -56
- package/dist/components/ScreenRecorderView/ScreenRecorderView.d.ts +0 -5
- package/dist/components/ScreenRecorderView/ScreenRecorderView.js +0 -1
- package/dist/components/ScreenRecorderView/ScreenRecorderView.js.map +0 -1
- package/dist/components/ScreenRecorderView/index.js +0 -1
- package/dist/components/ScreenRecorderView/index.js.map +0 -1
- package/dist/components/SessionRecorderWidget/ErrorBanner.js +0 -1
- package/dist/components/SessionRecorderWidget/ErrorBanner.js.map +0 -1
- package/dist/components/SessionRecorderWidget/FinalPopover.js +0 -1
- package/dist/components/SessionRecorderWidget/FinalPopover.js.map +0 -1
- package/dist/components/SessionRecorderWidget/FloatingButton.js +0 -1
- package/dist/components/SessionRecorderWidget/FloatingButton.js.map +0 -1
- package/dist/components/SessionRecorderWidget/InitialPopover.js +0 -1
- package/dist/components/SessionRecorderWidget/InitialPopover.js.map +0 -1
- package/dist/components/SessionRecorderWidget/ModalContainer.js +0 -1
- package/dist/components/SessionRecorderWidget/ModalContainer.js.map +0 -1
- package/dist/components/SessionRecorderWidget/ModalHeader.js +0 -1
- package/dist/components/SessionRecorderWidget/ModalHeader.js.map +0 -1
- package/dist/components/SessionRecorderWidget/SessionRecorderWidget.js +0 -1
- package/dist/components/SessionRecorderWidget/SessionRecorderWidget.js.map +0 -1
- package/dist/components/SessionRecorderWidget/icons.js +0 -1
- package/dist/components/SessionRecorderWidget/icons.js.map +0 -1
- package/dist/components/SessionRecorderWidget/index.js +0 -1
- package/dist/components/SessionRecorderWidget/index.js.map +0 -1
- package/dist/components/SessionRecorderWidget/styles.js +0 -1
- package/dist/components/SessionRecorderWidget/styles.js.map +0 -1
- package/dist/components/index.js +0 -1
- package/dist/components/index.js.map +0 -1
- package/dist/config/constants.js +0 -1
- package/dist/config/constants.js.map +0 -1
- package/dist/config/defaults.js +0 -1
- package/dist/config/defaults.js.map +0 -1
- package/dist/config/index.js +0 -1
- package/dist/config/index.js.map +0 -1
- package/dist/config/masking.d.ts +0 -2
- package/dist/config/masking.js +0 -1
- package/dist/config/masking.js.map +0 -1
- package/dist/config/session-recorder.d.ts +0 -2
- package/dist/config/session-recorder.js +0 -1
- package/dist/config/session-recorder.js.map +0 -1
- package/dist/config/validators.js +0 -1
- package/dist/config/validators.js.map +0 -1
- package/dist/config/widget.js +0 -1
- package/dist/config/widget.js.map +0 -1
- package/dist/context/SessionRecorderContext.js +0 -1
- package/dist/context/SessionRecorderContext.js.map +0 -1
- package/dist/context/SessionRecorderStore.js +0 -1
- package/dist/context/SessionRecorderStore.js.map +0 -1
- package/dist/context/useSessionRecorderStore.js +0 -1
- package/dist/context/useSessionRecorderStore.js.map +0 -1
- package/dist/context/useStoreSelector.js +0 -1
- package/dist/context/useStoreSelector.js.map +0 -1
- package/dist/index.js +0 -1
- package/dist/index.js.map +0 -1
- package/dist/native/GestureRecorderNative.d.ts +0 -57
- package/dist/native/GestureRecorderNative.js +0 -1
- package/dist/native/GestureRecorderNative.js.map +0 -1
- package/dist/native/GestureRecorderNativeTurboSpec.d.ts +0 -31
- package/dist/native/GestureRecorderNativeTurboSpec.js +0 -1
- package/dist/native/GestureRecorderNativeTurboSpec.js.map +0 -1
- package/dist/native/SessionRecorderNative.js +0 -1
- package/dist/native/SessionRecorderNative.js.map +0 -1
- package/dist/native/SessionRecorderNativeTurboSpec.d.ts +0 -17
- package/dist/native/SessionRecorderNativeTurboSpec.js +0 -1
- package/dist/native/SessionRecorderNativeTurboSpec.js.map +0 -1
- package/dist/native/index.js +0 -1
- package/dist/native/index.js.map +0 -1
- package/dist/otel/helpers.js +0 -1
- package/dist/otel/helpers.js.map +0 -1
- package/dist/otel/index.js +0 -1
- package/dist/otel/index.js.map +0 -1
- package/dist/otel/instrumentations/index.js +0 -1
- package/dist/otel/instrumentations/index.js.map +0 -1
- package/dist/patch/index.d.ts +0 -1
- package/dist/patch/index.js +0 -1
- package/dist/patch/index.js.map +0 -1
- package/dist/patch/xhr.js +0 -1
- package/dist/patch/xhr.js.map +0 -1
- package/dist/recorder/eventExporter.js +0 -1
- package/dist/recorder/eventExporter.js.map +0 -1
- package/dist/recorder/gestureRecorder.js +0 -1
- package/dist/recorder/gestureRecorder.js.map +0 -1
- package/dist/recorder/index.js +0 -1
- package/dist/recorder/index.js.map +0 -1
- package/dist/recorder/navigationTracker.js +0 -1
- package/dist/recorder/navigationTracker.js.map +0 -1
- package/dist/recorder/screenRecorder.js +0 -1
- package/dist/recorder/screenRecorder.js.map +0 -1
- package/dist/services/api.service.js +0 -1
- package/dist/services/api.service.js.map +0 -1
- package/dist/services/network.service.js +0 -1
- package/dist/services/network.service.js.map +0 -1
- package/dist/services/screenMaskingService.js +0 -1
- package/dist/services/screenMaskingService.js.map +0 -1
- package/dist/services/storage.service.js +0 -1
- package/dist/services/storage.service.js.map +0 -1
- package/dist/session-recorder.js +0 -1
- package/dist/session-recorder.js.map +0 -1
- package/dist/types/configs.js +0 -1
- package/dist/types/configs.js.map +0 -1
- package/dist/types/index.js +0 -1
- package/dist/types/index.js.map +0 -1
- package/dist/types/session-recorder.js +0 -1
- package/dist/types/session-recorder.js.map +0 -1
- package/dist/types/session.js +0 -1
- package/dist/types/session.js.map +0 -1
- package/dist/utils/app-metadata.js +0 -1
- package/dist/utils/app-metadata.js.map +0 -1
- package/dist/utils/constants.optional.expo.js +0 -1
- package/dist/utils/constants.optional.expo.js.map +0 -1
- package/dist/utils/constants.optional.js +0 -1
- package/dist/utils/constants.optional.js.map +0 -1
- package/dist/utils/createStore.js +0 -1
- package/dist/utils/createStore.js.map +0 -1
- package/dist/utils/index.js +0 -1
- package/dist/utils/index.js.map +0 -1
- package/dist/utils/logger.js +0 -1
- package/dist/utils/logger.js.map +0 -1
- package/dist/utils/platform.js +0 -1
- package/dist/utils/platform.js.map +0 -1
- package/dist/utils/request-utils.js +0 -1
- package/dist/utils/request-utils.js.map +0 -1
- package/dist/utils/rrweb-events.js +0 -1
- package/dist/utils/rrweb-events.js.map +0 -1
- package/dist/utils/session.js +0 -1
- package/dist/utils/session.js.map +0 -1
- package/dist/utils/shallowEqual.js +0 -1
- package/dist/utils/shallowEqual.js.map +0 -1
- package/dist/utils/time.js +0 -1
- package/dist/utils/time.js.map +0 -1
- package/dist/utils/type-utils.js +0 -1
- package/dist/utils/type-utils.js.map +0 -1
- package/dist/version.js +0 -1
- package/dist/version.js.map +0 -1
- package/docs/AUTO_METADATA_DETECTION.md +0 -108
- package/react-native.config.js +0 -13
- /package/{dist/components/ScreenRecorderView/index.d.ts → src/components/ScreenRecorderView/index.ts} +0 -0
|
@@ -0,0 +1,591 @@
|
|
|
1
|
+
|
|
2
|
+
import { SessionType } from '@multiplayer-app/session-recorder-common'
|
|
3
|
+
import { Observable } from 'lib0/observable'
|
|
4
|
+
import { type eventWithTime } from '@rrweb/types'
|
|
5
|
+
|
|
6
|
+
import { TracerReactNativeSDK } from './otel'
|
|
7
|
+
import { RecorderReactNativeSDK } from './recorder'
|
|
8
|
+
import { logger } from './utils'
|
|
9
|
+
|
|
10
|
+
import {
|
|
11
|
+
SessionState,
|
|
12
|
+
type ISession,
|
|
13
|
+
type ISessionRecorder,
|
|
14
|
+
type SessionRecorderConfigs,
|
|
15
|
+
type SessionRecorderOptions,
|
|
16
|
+
type EventRecorder
|
|
17
|
+
} from './types'
|
|
18
|
+
import { getFormattedDate, isSessionActive, getNavigatorInfo } from './utils'
|
|
19
|
+
import { setMaxCapturingHttpPayloadSize, setShouldRecordHttpData } from './patch/xhr'
|
|
20
|
+
import { BASE_CONFIG, getSessionRecorderConfig } from './config'
|
|
21
|
+
|
|
22
|
+
import { StorageService } from './services/storage.service'
|
|
23
|
+
import { NetworkService } from './services/network.service'
|
|
24
|
+
import { ApiService, type StartSessionRequest, type StopSessionRequest } from './services/api.service'
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
type SessionRecorderEvents = 'state-change'
|
|
28
|
+
|
|
29
|
+
class SessionRecorder extends Observable<SessionRecorderEvents> implements ISessionRecorder, EventRecorder {
|
|
30
|
+
|
|
31
|
+
private _configs: SessionRecorderConfigs
|
|
32
|
+
private _apiService = new ApiService()
|
|
33
|
+
private _tracer = new TracerReactNativeSDK()
|
|
34
|
+
private _recorder = new RecorderReactNativeSDK()
|
|
35
|
+
private _storageService = StorageService.getInstance()
|
|
36
|
+
private _networkService = NetworkService.getInstance()
|
|
37
|
+
private _startRequestController: AbortController | null = null
|
|
38
|
+
|
|
39
|
+
// Whether the session recorder is initialized
|
|
40
|
+
private _isInitialized = false
|
|
41
|
+
get isInitialized(): boolean {
|
|
42
|
+
return this._isInitialized
|
|
43
|
+
}
|
|
44
|
+
set isInitialized(isInitialized: boolean) {
|
|
45
|
+
this._isInitialized = isInitialized
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// Session ID and state are stored in AsyncStorage
|
|
49
|
+
private _sessionId: string | null = null
|
|
50
|
+
get sessionId(): string | null {
|
|
51
|
+
return this._sessionId
|
|
52
|
+
}
|
|
53
|
+
set sessionId(sessionId: string | null) {
|
|
54
|
+
this._sessionId = sessionId
|
|
55
|
+
if (sessionId) {
|
|
56
|
+
this._storageService.saveSessionId(sessionId)
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
private _sessionType: SessionType = SessionType.PLAIN
|
|
61
|
+
get sessionType(): SessionType {
|
|
62
|
+
return this._sessionType
|
|
63
|
+
}
|
|
64
|
+
set sessionType(sessionType: SessionType) {
|
|
65
|
+
this._sessionType = sessionType
|
|
66
|
+
this._storageService.saveSessionType(sessionType)
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
get continuousRecording(): boolean {
|
|
70
|
+
return this.sessionType === SessionType.CONTINUOUS
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
private _sessionState: SessionState | null = null
|
|
74
|
+
get sessionState(): SessionState | null {
|
|
75
|
+
return this._sessionState || SessionState.stopped
|
|
76
|
+
}
|
|
77
|
+
set sessionState(state: SessionState | null) {
|
|
78
|
+
this._sessionState = state
|
|
79
|
+
this.emit('state-change', [state || SessionState.stopped, this.sessionType])
|
|
80
|
+
if (state) {
|
|
81
|
+
this._storageService.saveSessionState(state)
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
private _session: ISession | null = null
|
|
86
|
+
get session(): ISession | null {
|
|
87
|
+
return this._session
|
|
88
|
+
}
|
|
89
|
+
set session(session: ISession | null) {
|
|
90
|
+
this._session = session
|
|
91
|
+
if (session) {
|
|
92
|
+
this._storageService.saveSessionObject(session)
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
private _sessionAttributes: Record<string, any> | null = null
|
|
97
|
+
get sessionAttributes(): Record<string, any> {
|
|
98
|
+
return this._sessionAttributes || {}
|
|
99
|
+
}
|
|
100
|
+
set sessionAttributes(attributes: Record<string, any> | null) {
|
|
101
|
+
this._sessionAttributes = attributes
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Error message getter and setter
|
|
106
|
+
*/
|
|
107
|
+
public get error(): string {
|
|
108
|
+
return this._error || ''
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
public set error(v: string) {
|
|
112
|
+
this._error = v
|
|
113
|
+
}
|
|
114
|
+
private _error: string = ''
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* React Native doesn't have HTML elements, so we return null
|
|
118
|
+
*/
|
|
119
|
+
public get sessionWidgetButtonElement(): any {
|
|
120
|
+
return null
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
public get config(): SessionRecorderConfigs {
|
|
124
|
+
return this._configs
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Initialize debugger with default or custom configurations
|
|
128
|
+
*/
|
|
129
|
+
constructor() {
|
|
130
|
+
super()
|
|
131
|
+
this._configs = BASE_CONFIG
|
|
132
|
+
// Initialize with stored session data if available
|
|
133
|
+
StorageService.initialize()
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
private async _loadStoredSessionData(): Promise<void> {
|
|
137
|
+
try {
|
|
138
|
+
await StorageService.initialize()
|
|
139
|
+
const storedData = await this._storageService.getAllSessionData()
|
|
140
|
+
if (isSessionActive(storedData.sessionObject, storedData.sessionType)) {
|
|
141
|
+
this.session = storedData.sessionObject
|
|
142
|
+
this.sessionId = storedData.sessionId
|
|
143
|
+
this.sessionType = storedData.sessionType || SessionType.PLAIN
|
|
144
|
+
this.sessionState = storedData.sessionState
|
|
145
|
+
} else {
|
|
146
|
+
this.session = null
|
|
147
|
+
this.sessionId = null
|
|
148
|
+
this.sessionState = null
|
|
149
|
+
this.sessionType = SessionType.PLAIN
|
|
150
|
+
}
|
|
151
|
+
} catch (error) {
|
|
152
|
+
logger.error('SessionRecorder', 'Failed to load stored session data', error)
|
|
153
|
+
this.session = null
|
|
154
|
+
this.sessionId = null
|
|
155
|
+
this.sessionState = null
|
|
156
|
+
this.sessionType = SessionType.PLAIN
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Initialize the session debugger
|
|
162
|
+
* @param configs - custom configurations for session debugger
|
|
163
|
+
*/
|
|
164
|
+
public async init(configs: SessionRecorderOptions): Promise<void> {
|
|
165
|
+
if (this._isInitialized) return
|
|
166
|
+
this._isInitialized = true
|
|
167
|
+
this._configs = getSessionRecorderConfig({ ...this._configs, ...configs })
|
|
168
|
+
logger.configure(this._configs.logger)
|
|
169
|
+
await this._loadStoredSessionData()
|
|
170
|
+
setMaxCapturingHttpPayloadSize(this._configs.maxCapturingHttpPayloadSize)
|
|
171
|
+
setShouldRecordHttpData(!this._configs.captureBody, this._configs.captureHeaders)
|
|
172
|
+
|
|
173
|
+
this._tracer.init(this._configs)
|
|
174
|
+
this._recorder.init(this._configs)
|
|
175
|
+
this._apiService.init(this._configs)
|
|
176
|
+
await this._networkService.init()
|
|
177
|
+
this._setupNetworkCallbacks()
|
|
178
|
+
|
|
179
|
+
if (this.sessionId && (this.sessionState === SessionState.started || this.sessionState === SessionState.paused)) {
|
|
180
|
+
this._start()
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* Setup network state change callbacks
|
|
186
|
+
*/
|
|
187
|
+
private _setupNetworkCallbacks(): void {
|
|
188
|
+
this._networkService.addCallback((state) => {
|
|
189
|
+
if (!state.isConnected && this.sessionState === SessionState.started) {
|
|
190
|
+
logger.info('SessionRecorder', 'Network went offline - pausing session recording')
|
|
191
|
+
this.pause()
|
|
192
|
+
} else if (state.isConnected && this.sessionState === SessionState.paused) {
|
|
193
|
+
logger.info('SessionRecorder', 'Network came back online - resuming session recording')
|
|
194
|
+
this.resume()
|
|
195
|
+
}
|
|
196
|
+
})
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* Start a new session
|
|
201
|
+
* @param type - the type of session to start
|
|
202
|
+
* @param session - the session to start
|
|
203
|
+
*/
|
|
204
|
+
public async start(type: SessionType = SessionType.PLAIN, session?: ISession): Promise<void> {
|
|
205
|
+
this._checkOperation('start')
|
|
206
|
+
|
|
207
|
+
// Check if offline - don't start recording if offline
|
|
208
|
+
if (!this._networkService.isOnline()) {
|
|
209
|
+
logger.warn('SessionRecorder', 'Cannot start session recording - device is offline')
|
|
210
|
+
throw new Error('Cannot start session recording while offline')
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
// If continuous recording is disabled, force plain mode
|
|
214
|
+
if (type === SessionType.CONTINUOUS && !this._configs?.showContinuousRecording) {
|
|
215
|
+
type = SessionType.PLAIN
|
|
216
|
+
}
|
|
217
|
+
logger.info('SessionRecorder', 'Starting session with type:', type)
|
|
218
|
+
this.sessionType = type
|
|
219
|
+
this._startRequestController = new AbortController()
|
|
220
|
+
if (session) {
|
|
221
|
+
this._setupSessionAndStart(session, true)
|
|
222
|
+
} else {
|
|
223
|
+
await this._createSessionAndStart()
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* Stop the current session with an optional comment
|
|
229
|
+
* @param comment - user-provided comment to include in session session attributes
|
|
230
|
+
*/
|
|
231
|
+
public async stop(comment?: string): Promise<void> {
|
|
232
|
+
try {
|
|
233
|
+
this._checkOperation('stop')
|
|
234
|
+
this._stop()
|
|
235
|
+
if (this.continuousRecording) {
|
|
236
|
+
await this._apiService.stopContinuousDebugSession(this.sessionId!)
|
|
237
|
+
this.sessionType = SessionType.PLAIN
|
|
238
|
+
} else {
|
|
239
|
+
const request: StopSessionRequest = {
|
|
240
|
+
sessionAttributes: { comment },
|
|
241
|
+
stoppedAt: Date.now(),
|
|
242
|
+
}
|
|
243
|
+
await this._apiService.stopSession(this.sessionId!, request)
|
|
244
|
+
}
|
|
245
|
+
this._clearSession()
|
|
246
|
+
} catch (error: any) {
|
|
247
|
+
this.error = error.message
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
/**
|
|
252
|
+
* Pause the current session
|
|
253
|
+
*/
|
|
254
|
+
public async pause(): Promise<void> {
|
|
255
|
+
try {
|
|
256
|
+
this._checkOperation('pause')
|
|
257
|
+
this._pause()
|
|
258
|
+
} catch (error: any) {
|
|
259
|
+
this.error = error.message
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
/**
|
|
264
|
+
* Resume the current session
|
|
265
|
+
*/
|
|
266
|
+
public async resume(): Promise<void> {
|
|
267
|
+
try {
|
|
268
|
+
this._checkOperation('resume')
|
|
269
|
+
this._resume()
|
|
270
|
+
} catch (error: any) {
|
|
271
|
+
this.error = error.message
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
/**
|
|
276
|
+
* Cancel the current session
|
|
277
|
+
*/
|
|
278
|
+
public async cancel(): Promise<void> {
|
|
279
|
+
try {
|
|
280
|
+
this._checkOperation('cancel')
|
|
281
|
+
this._stop()
|
|
282
|
+
if (this.continuousRecording) {
|
|
283
|
+
await this._apiService.stopContinuousDebugSession(this.sessionId!)
|
|
284
|
+
this.sessionType = SessionType.PLAIN
|
|
285
|
+
} else {
|
|
286
|
+
await this._apiService.cancelSession(this.sessionId!)
|
|
287
|
+
}
|
|
288
|
+
this._clearSession()
|
|
289
|
+
} catch (error: any) {
|
|
290
|
+
this.error = error.message
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
/**
|
|
295
|
+
* Save the continuous recording session
|
|
296
|
+
*/
|
|
297
|
+
public async save(): Promise<any> {
|
|
298
|
+
try {
|
|
299
|
+
this._checkOperation('save')
|
|
300
|
+
if (!this.continuousRecording || !this._configs?.showContinuousRecording) {
|
|
301
|
+
return
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
const res = await this._apiService.saveContinuousDebugSession(
|
|
305
|
+
this.sessionId!,
|
|
306
|
+
{
|
|
307
|
+
sessionAttributes: this.sessionAttributes,
|
|
308
|
+
resourceAttributes: getNavigatorInfo(),
|
|
309
|
+
stoppedAt: Date.now(),
|
|
310
|
+
name: this.sessionAttributes.userName
|
|
311
|
+
? `${this.sessionAttributes.userName}'s session on ${getFormattedDate(
|
|
312
|
+
Date.now(),
|
|
313
|
+
{ month: 'short', day: 'numeric' },
|
|
314
|
+
)}`
|
|
315
|
+
: `Session on ${getFormattedDate(Date.now())}`,
|
|
316
|
+
},
|
|
317
|
+
)
|
|
318
|
+
|
|
319
|
+
return res
|
|
320
|
+
} catch (error: any) {
|
|
321
|
+
this.error = error.message
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
/**
|
|
326
|
+
* Set the session attributes
|
|
327
|
+
* @param attributes - the attributes to set
|
|
328
|
+
*/
|
|
329
|
+
public setSessionAttributes(attributes: Record<string, any>): void {
|
|
330
|
+
this._sessionAttributes = attributes
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
/**
|
|
334
|
+
* @description Check if session should be started/stopped automatically
|
|
335
|
+
* @param {ISession} [sessionPayload]
|
|
336
|
+
* @returns {Promise<void>}
|
|
337
|
+
*/
|
|
338
|
+
public async checkRemoteContinuousSession(
|
|
339
|
+
sessionPayload?: Omit<ISession, '_id' | 'shortId'>,
|
|
340
|
+
): Promise<void> {
|
|
341
|
+
this._checkOperation('autoStartRemoteContinuousSession')
|
|
342
|
+
if (!this._configs?.showContinuousRecording) {
|
|
343
|
+
return
|
|
344
|
+
}
|
|
345
|
+
const payload = {
|
|
346
|
+
sessionAttributes: {
|
|
347
|
+
...this.sessionAttributes,
|
|
348
|
+
...(sessionPayload?.sessionAttributes || {}),
|
|
349
|
+
},
|
|
350
|
+
resourceAttributes: {
|
|
351
|
+
...getNavigatorInfo(),
|
|
352
|
+
...(sessionPayload?.resourceAttributes || {}),
|
|
353
|
+
},
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
const { state } = await this._apiService.checkRemoteSession(payload)
|
|
357
|
+
|
|
358
|
+
if (state == 'START') {
|
|
359
|
+
if (this.sessionState !== SessionState.started) {
|
|
360
|
+
await this.start(SessionType.CONTINUOUS)
|
|
361
|
+
}
|
|
362
|
+
} else if (state == 'STOP') {
|
|
363
|
+
if (this.sessionState !== SessionState.stopped) {
|
|
364
|
+
await this.stop()
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
/**
|
|
370
|
+
* Create a new session and start it
|
|
371
|
+
*/
|
|
372
|
+
private async _createSessionAndStart(): Promise<void> {
|
|
373
|
+
const signal = this._startRequestController?.signal
|
|
374
|
+
try {
|
|
375
|
+
const payload = {
|
|
376
|
+
sessionAttributes: this.sessionAttributes,
|
|
377
|
+
resourceAttributes: getNavigatorInfo(),
|
|
378
|
+
name: this.sessionAttributes.userName
|
|
379
|
+
? `${this.sessionAttributes.userName}'s session on ${getFormattedDate(Date.now(), { month: 'short', day: 'numeric' })}`
|
|
380
|
+
: `Session on ${getFormattedDate(Date.now())}`,
|
|
381
|
+
}
|
|
382
|
+
const request: StartSessionRequest = !this.continuousRecording ?
|
|
383
|
+
payload : { debugSessionData: payload }
|
|
384
|
+
|
|
385
|
+
const session = this.continuousRecording
|
|
386
|
+
? await this._apiService.startContinuousDebugSession(request, signal)
|
|
387
|
+
: await this._apiService.startSession(request, signal)
|
|
388
|
+
|
|
389
|
+
if (session) {
|
|
390
|
+
session.sessionType = this.continuousRecording
|
|
391
|
+
? SessionType.CONTINUOUS
|
|
392
|
+
: SessionType.PLAIN
|
|
393
|
+
this._setupSessionAndStart(session, false)
|
|
394
|
+
}
|
|
395
|
+
} catch (error: any) {
|
|
396
|
+
this.error = error.message
|
|
397
|
+
logger.error('SessionRecorder', 'Error creating session:', error.message)
|
|
398
|
+
if (this.continuousRecording) {
|
|
399
|
+
this.sessionType = SessionType.PLAIN
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
/**
|
|
405
|
+
* Start tracing and recording for the session
|
|
406
|
+
*/
|
|
407
|
+
private _start(): void {
|
|
408
|
+
this.sessionState = SessionState.started
|
|
409
|
+
this.sessionType = this.sessionType
|
|
410
|
+
|
|
411
|
+
if (this.sessionId) {
|
|
412
|
+
this._tracer.start(this.sessionId, this.sessionType)
|
|
413
|
+
this._recorder.start(this.sessionId, this.sessionType)
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
/**
|
|
418
|
+
* Stop tracing and recording for the session
|
|
419
|
+
*/
|
|
420
|
+
private _stop(): void {
|
|
421
|
+
this.sessionState = SessionState.stopped
|
|
422
|
+
this._tracer.shutdown()
|
|
423
|
+
this._recorder.stop()
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
/**
|
|
427
|
+
* Pause the session tracing and recording
|
|
428
|
+
*/
|
|
429
|
+
private _pause(): void {
|
|
430
|
+
this._tracer.shutdown()
|
|
431
|
+
this._recorder.stop()
|
|
432
|
+
this.sessionState = SessionState.paused
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
/**
|
|
436
|
+
* Resume the session tracing and recording
|
|
437
|
+
*/
|
|
438
|
+
private _resume(): void {
|
|
439
|
+
if (this.sessionId) {
|
|
440
|
+
this._tracer.setSessionId(this.sessionId, this.sessionType)
|
|
441
|
+
this._recorder.start(this.sessionId, this.sessionType)
|
|
442
|
+
}
|
|
443
|
+
this.sessionState = SessionState.started
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
private _setupSessionAndStart(session: ISession, configureExporters: boolean = true): void {
|
|
447
|
+
if (configureExporters && session.tempApiKey) {
|
|
448
|
+
this._configs.apiKey = session.tempApiKey
|
|
449
|
+
this._tracer.setApiKey(session.tempApiKey)
|
|
450
|
+
this._recorder.setApiKey(session.tempApiKey)
|
|
451
|
+
this._apiService.setApiKey(session.tempApiKey)
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
this._setSession(session)
|
|
455
|
+
this._start()
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
/**
|
|
459
|
+
* Set the session ID in storage
|
|
460
|
+
* @param sessionId - the session ID to set or clear
|
|
461
|
+
*/
|
|
462
|
+
private _setSession(
|
|
463
|
+
session: ISession,
|
|
464
|
+
): void {
|
|
465
|
+
this.session = { ...session, createdAt: session.createdAt || new Date().toISOString() }
|
|
466
|
+
this.sessionId = session?.shortId || session?._id
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
private _clearSession(): void {
|
|
470
|
+
this.session = null
|
|
471
|
+
this.sessionId = null
|
|
472
|
+
this.sessionState = SessionState.stopped
|
|
473
|
+
this._storageService.clearSessionData()
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
/**
|
|
477
|
+
* Check the operation validity based on the session state and action
|
|
478
|
+
* @param action - action being checked ('init', 'start', 'stop', 'cancel', 'pause', 'resume')
|
|
479
|
+
*/
|
|
480
|
+
private _checkOperation(
|
|
481
|
+
action:
|
|
482
|
+
| 'init'
|
|
483
|
+
| 'start'
|
|
484
|
+
| 'stop'
|
|
485
|
+
| 'cancel'
|
|
486
|
+
| 'pause'
|
|
487
|
+
| 'resume'
|
|
488
|
+
| 'save'
|
|
489
|
+
| 'autoStartRemoteContinuousSession',
|
|
490
|
+
_payload?: any,
|
|
491
|
+
): void {
|
|
492
|
+
if (!this._isInitialized) {
|
|
493
|
+
throw new Error(
|
|
494
|
+
'Configuration not initialized. Call init() before performing any actions.',
|
|
495
|
+
)
|
|
496
|
+
}
|
|
497
|
+
switch (action) {
|
|
498
|
+
case 'start':
|
|
499
|
+
if (this.sessionState === SessionState.started) {
|
|
500
|
+
throw new Error('Session is already started.')
|
|
501
|
+
}
|
|
502
|
+
break
|
|
503
|
+
case 'stop':
|
|
504
|
+
if (this.sessionState !== SessionState.paused && this.sessionState !== SessionState.started) {
|
|
505
|
+
throw new Error('Cannot stop. Session is not currently started.')
|
|
506
|
+
}
|
|
507
|
+
break
|
|
508
|
+
case 'cancel':
|
|
509
|
+
if (this.sessionState === SessionState.stopped) {
|
|
510
|
+
throw new Error('Cannot cancel. Session has already been stopped.')
|
|
511
|
+
}
|
|
512
|
+
break
|
|
513
|
+
case 'pause':
|
|
514
|
+
if (this.sessionState !== SessionState.started) {
|
|
515
|
+
throw new Error('Cannot pause. Session is not running.')
|
|
516
|
+
}
|
|
517
|
+
break
|
|
518
|
+
case 'resume':
|
|
519
|
+
if (this.sessionState !== SessionState.paused) {
|
|
520
|
+
throw new Error('Cannot resume. Session is not paused.')
|
|
521
|
+
}
|
|
522
|
+
break
|
|
523
|
+
case 'save':
|
|
524
|
+
if (!this.continuousRecording) {
|
|
525
|
+
throw new Error('Cannot save continuous recording session. Continuous recording is not enabled.')
|
|
526
|
+
}
|
|
527
|
+
if (this.sessionState !== SessionState.started) {
|
|
528
|
+
throw new Error('Cannot save continuous recording session. Session is not started.')
|
|
529
|
+
}
|
|
530
|
+
break
|
|
531
|
+
case 'autoStartRemoteContinuousSession':
|
|
532
|
+
if (this.sessionState !== SessionState.stopped) {
|
|
533
|
+
throw new Error('Cannot start remote continuous session. Session is not stopped.')
|
|
534
|
+
}
|
|
535
|
+
break
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
// Session attributes
|
|
539
|
+
setSessionAttribute(key: string, value: any): void {
|
|
540
|
+
if (this._session) {
|
|
541
|
+
if (!this._session.sessionAttributes) {
|
|
542
|
+
this._session.sessionAttributes = {}
|
|
543
|
+
}
|
|
544
|
+
this._session.sessionAttributes[key] = value
|
|
545
|
+
this._session.updatedAt = new Date().toISOString()
|
|
546
|
+
}
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
/**
|
|
550
|
+
* Record a custom rrweb event
|
|
551
|
+
* Note: Screen capture and touch events are recorded automatically when session is started
|
|
552
|
+
* @param event - The rrweb event to record
|
|
553
|
+
*/
|
|
554
|
+
recordEvent(event: eventWithTime): void {
|
|
555
|
+
if (!this._isInitialized || this.sessionState !== SessionState.started) {
|
|
556
|
+
return
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
// Forward the event to the recorder SDK
|
|
560
|
+
this._recorder.recordEvent(event)
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
/**
|
|
564
|
+
* Set the viewshot ref for screen capture
|
|
565
|
+
* @param ref - React Native View ref for screen capture
|
|
566
|
+
*/
|
|
567
|
+
setViewShotRef(ref: any): void {
|
|
568
|
+
if (this._recorder) {
|
|
569
|
+
this._recorder.setViewShotRef(ref)
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
|
|
573
|
+
/**
|
|
574
|
+
* Set the navigation ref for navigation tracking
|
|
575
|
+
* @param ref - React Native Navigation ref for navigation tracking
|
|
576
|
+
*/
|
|
577
|
+
setNavigationRef(ref: any): void {
|
|
578
|
+
if (this._recorder) {
|
|
579
|
+
this._recorder.setNavigationRef(ref)
|
|
580
|
+
}
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
/**
|
|
584
|
+
* Cleanup resources and unsubscribe from network monitoring
|
|
585
|
+
*/
|
|
586
|
+
cleanup(): void {
|
|
587
|
+
this._networkService.cleanup()
|
|
588
|
+
}
|
|
589
|
+
}
|
|
590
|
+
|
|
591
|
+
export default new SessionRecorder()
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { type PropagateTraceHeaderCorsUrls } from '@opentelemetry/instrumentation-xml-http-request/build/src/types';
|
|
2
|
+
import { type MaskingOptions, type SessionRecorderOptions } from './session-recorder';
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Utility type that makes all properties required recursively
|
|
7
|
+
* Removes optional modifiers and undefined types from nested objects
|
|
8
|
+
*/
|
|
9
|
+
export type DeepRequired<T> =
|
|
10
|
+
T extends Function ? T :
|
|
11
|
+
T extends ReadonlyArray<infer U> ? Array<DeepRequired<NonNullable<U>>> :
|
|
12
|
+
T extends Array<infer U> ? Array<DeepRequired<NonNullable<U>>> :
|
|
13
|
+
T extends object ? { -readonly [K in keyof T]-?: DeepRequired<NonNullable<T[K]>> } :
|
|
14
|
+
NonNullable<T>;
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Fully resolved configuration interface
|
|
18
|
+
* All optional properties from SessionRecorderOptions are now required
|
|
19
|
+
*/
|
|
20
|
+
export interface SessionRecorderConfigs extends DeepRequired<SessionRecorderOptions> { }
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Base configuration interface with common properties
|
|
25
|
+
* Shared by all service configuration interfaces
|
|
26
|
+
*/
|
|
27
|
+
export interface BaseConfig {
|
|
28
|
+
/** API key for authentication */
|
|
29
|
+
apiKey: string
|
|
30
|
+
/** Base URL for the API calls */
|
|
31
|
+
apiBaseUrl: string
|
|
32
|
+
/** OTLP collector endpoint for traces */
|
|
33
|
+
exporterEndpoint: string
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Type for masking configuration used by the Tracer
|
|
38
|
+
* Contains only trace-related masking options
|
|
39
|
+
*/
|
|
40
|
+
export type TracerReactNativeMasking = Pick<MaskingOptions, 'isContentMaskingEnabled' | 'maskBody' | 'maskHeaders' | 'maskBodyFieldsList' | 'maskHeadersList' | 'headersToInclude' | 'headersToExclude'>
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Configuration interface for the Tracer class
|
|
44
|
+
* Contains all settings needed for OpenTelemetry tracing
|
|
45
|
+
*/
|
|
46
|
+
export interface TracerReactNativeConfig extends BaseConfig {
|
|
47
|
+
/** Application name */
|
|
48
|
+
application: string
|
|
49
|
+
/** Application version */
|
|
50
|
+
version: string
|
|
51
|
+
/** Environment (e.g., 'production', 'staging') */
|
|
52
|
+
environment: string
|
|
53
|
+
/** URLs to ignore during tracing */
|
|
54
|
+
ignoreUrls: Array<string | RegExp>
|
|
55
|
+
/** Trace ID ratio for sampling */
|
|
56
|
+
sampleTraceRatio: number
|
|
57
|
+
/** URLs for CORS trace header propagation */
|
|
58
|
+
propagateTraceHeaderCorsUrls: PropagateTraceHeaderCorsUrls
|
|
59
|
+
/** Whether to schematize document span payload */
|
|
60
|
+
schemifyDocSpanPayload: boolean
|
|
61
|
+
/** Maximum size for capturing HTTP payload */
|
|
62
|
+
maxCapturingHttpPayloadSize: number
|
|
63
|
+
/** If true, captures body in traces */
|
|
64
|
+
captureBody: boolean
|
|
65
|
+
/** If true, captures headers in traces */
|
|
66
|
+
captureHeaders: boolean
|
|
67
|
+
/** Configuration for masking sensitive data in session recordings */
|
|
68
|
+
masking: TracerReactNativeMasking
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Type for masking configuration used by the Recorder
|
|
73
|
+
* Contains only screen recording masking options
|
|
74
|
+
*/
|
|
75
|
+
export type RecorderMaskingConfig = Pick<MaskingOptions, 'maskTextInputs' | 'maskImages' | 'maskButtons' | 'maskLabels' | 'maskWebViews' | 'maskSandboxedViews'>
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Configuration interface for the Recorder class
|
|
79
|
+
* Contains settings for screen recording and gesture capture
|
|
80
|
+
*/
|
|
81
|
+
export interface RecorderConfig extends BaseConfig {
|
|
82
|
+
/** Whether to record gestures */
|
|
83
|
+
recordGestures?: boolean
|
|
84
|
+
/** Whether to record navigation */
|
|
85
|
+
recordNavigation?: boolean
|
|
86
|
+
/** Whether to record screen */
|
|
87
|
+
recordScreen?: boolean
|
|
88
|
+
/** Configuration for masking sensitive data in screen recordings */
|
|
89
|
+
masking?: RecorderMaskingConfig
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Configuration interface for the ApiService class
|
|
94
|
+
* Contains settings for API communication
|
|
95
|
+
*/
|
|
96
|
+
export interface ApiServiceConfig extends BaseConfig { }
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
// Ambient module to prevent TypeScript errors when expo-constants is not installed.
|
|
2
|
+
// In non-Expo projects, this module is never required at runtime because we import
|
|
3
|
+
// through an optional shim that resolves to undefined.
|
|
4
|
+
declare module 'expo-constants' {
|
|
5
|
+
const Constants: any
|
|
6
|
+
export default Constants
|
|
7
|
+
}
|