@kubesense/kubesense-browser-rum 1.0.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.
- package/LICENSE +201 -0
- package/README.md +34 -0
- package/bundle/chunks/profiler-b64730a2109c3ddbc539-kubesense-rum.js +1 -0
- package/bundle/chunks/recorder-9ae532a18bac5f4280da-kubesense-rum.js +1 -0
- package/bundle/kubesense-rum.js +1 -0
- package/cjs/boot/isBrowserSupported.d.ts +4 -0
- package/cjs/boot/isBrowserSupported.js +17 -0
- package/cjs/boot/isBrowserSupported.js.map +1 -0
- package/cjs/boot/lazyLoadProfiler.d.ts +4 -0
- package/cjs/boot/lazyLoadProfiler.js +54 -0
- package/cjs/boot/lazyLoadProfiler.js.map +1 -0
- package/cjs/boot/lazyLoadRecorder.d.ts +4 -0
- package/cjs/boot/lazyLoadRecorder.js +54 -0
- package/cjs/boot/lazyLoadRecorder.js.map +1 -0
- package/cjs/boot/postStartStrategy.d.ts +33 -0
- package/cjs/boot/postStartStrategy.js +98 -0
- package/cjs/boot/postStartStrategy.js.map +1 -0
- package/cjs/boot/preStartStrategy.d.ts +6 -0
- package/cjs/boot/preStartStrategy.js +24 -0
- package/cjs/boot/preStartStrategy.js.map +1 -0
- package/cjs/boot/profilerApi.d.ts +2 -0
- package/cjs/boot/profilerApi.js +53 -0
- package/cjs/boot/profilerApi.js.map +1 -0
- package/cjs/boot/recorderApi.d.ts +4 -0
- package/cjs/boot/recorderApi.js +73 -0
- package/cjs/boot/recorderApi.js.map +1 -0
- package/cjs/boot/startRecording.d.ts +6 -0
- package/cjs/boot/startRecording.js +45 -0
- package/cjs/boot/startRecording.js.map +1 -0
- package/cjs/domain/deflate/deflateEncoder.d.ts +3 -0
- package/cjs/domain/deflate/deflateEncoder.js +110 -0
- package/cjs/domain/deflate/deflateEncoder.js.map +1 -0
- package/cjs/domain/deflate/deflateWorker.d.ts +30 -0
- package/cjs/domain/deflate/deflateWorker.js +104 -0
- package/cjs/domain/deflate/deflateWorker.js.map +1 -0
- package/cjs/domain/deflate/index.d.ts +3 -0
- package/cjs/domain/deflate/index.js +10 -0
- package/cjs/domain/deflate/index.js.map +1 -0
- package/cjs/domain/getSessionReplayLink.d.ts +2 -0
- package/cjs/domain/getSessionReplayLink.js +35 -0
- package/cjs/domain/getSessionReplayLink.js.map +1 -0
- package/cjs/domain/profiling/profiler.d.ts +7 -0
- package/cjs/domain/profiling/profiler.js +244 -0
- package/cjs/domain/profiling/profiler.js.map +1 -0
- package/cjs/domain/profiling/profilingContext.d.ts +6 -0
- package/cjs/domain/profiling/profilingContext.js +28 -0
- package/cjs/domain/profiling/profilingContext.js.map +1 -0
- package/cjs/domain/profiling/profilingSupported.d.ts +1 -0
- package/cjs/domain/profiling/profilingSupported.js +11 -0
- package/cjs/domain/profiling/profilingSupported.js.map +1 -0
- package/cjs/domain/profiling/test-utils/mockedTrace.d.ts +3 -0
- package/cjs/domain/profiling/test-utils/mockedTrace.js +57 -0
- package/cjs/domain/profiling/test-utils/mockedTrace.js.map +1 -0
- package/cjs/domain/profiling/transport/assembly.d.ts +21 -0
- package/cjs/domain/profiling/transport/assembly.js +45 -0
- package/cjs/domain/profiling/transport/assembly.js.map +1 -0
- package/cjs/domain/profiling/transport/buildProfileEventAttributes.d.ts +25 -0
- package/cjs/domain/profiling/transport/buildProfileEventAttributes.js +50 -0
- package/cjs/domain/profiling/transport/buildProfileEventAttributes.js.map +1 -0
- package/cjs/domain/profiling/types/index.d.ts +2 -0
- package/cjs/domain/profiling/types/index.js +3 -0
- package/cjs/domain/profiling/types/index.js.map +1 -0
- package/cjs/domain/profiling/types/profilerApi.types.d.ts +58 -0
- package/cjs/domain/profiling/types/profilerApi.types.js +5 -0
- package/cjs/domain/profiling/types/profilerApi.types.js.map +1 -0
- package/cjs/domain/profiling/types/rumProfiler.types.d.ts +72 -0
- package/cjs/domain/profiling/types/rumProfiler.types.js +3 -0
- package/cjs/domain/profiling/types/rumProfiler.types.js.map +1 -0
- package/cjs/domain/profiling/utils/getCustomOrDefaultViewName.d.ts +1 -0
- package/cjs/domain/profiling/utils/getCustomOrDefaultViewName.js +7 -0
- package/cjs/domain/profiling/utils/getCustomOrDefaultViewName.js.map +1 -0
- package/cjs/domain/profiling/utils/getDefaultViewName.d.ts +1 -0
- package/cjs/domain/profiling/utils/getDefaultViewName.js +14 -0
- package/cjs/domain/profiling/utils/getDefaultViewName.js.map +1 -0
- package/cjs/domain/profiling/utils/getNumberOfSamples.d.ts +7 -0
- package/cjs/domain/profiling/utils/getNumberOfSamples.js +18 -0
- package/cjs/domain/profiling/utils/getNumberOfSamples.js.map +1 -0
- package/cjs/domain/record/assembly.d.ts +2 -0
- package/cjs/domain/record/assembly.js +16 -0
- package/cjs/domain/record/assembly.js.map +1 -0
- package/cjs/domain/record/elementsScrollPositions.d.ts +10 -0
- package/cjs/domain/record/elementsScrollPositions.js +23 -0
- package/cjs/domain/record/elementsScrollPositions.js.map +1 -0
- package/cjs/domain/record/eventIds.d.ts +4 -0
- package/cjs/domain/record/eventIds.js +16 -0
- package/cjs/domain/record/eventIds.js.map +1 -0
- package/cjs/domain/record/eventsUtils.d.ts +2 -0
- package/cjs/domain/record/eventsUtils.js +15 -0
- package/cjs/domain/record/eventsUtils.js.map +1 -0
- package/cjs/domain/record/index.d.ts +7 -0
- package/cjs/domain/record/index.js +17 -0
- package/cjs/domain/record/index.js.map +1 -0
- package/cjs/domain/record/internalApi.d.ts +22 -0
- package/cjs/domain/record/internalApi.js +57 -0
- package/cjs/domain/record/internalApi.js.map +1 -0
- package/cjs/domain/record/mutationBatch.d.ts +12 -0
- package/cjs/domain/record/mutationBatch.js +44 -0
- package/cjs/domain/record/mutationBatch.js.map +1 -0
- package/cjs/domain/record/nodeIds.d.ts +15 -0
- package/cjs/domain/record/nodeIds.js +32 -0
- package/cjs/domain/record/nodeIds.js.map +1 -0
- package/cjs/domain/record/record.d.ts +16 -0
- package/cjs/domain/record/record.js +90 -0
- package/cjs/domain/record/record.js.map +1 -0
- package/cjs/domain/record/record.types.d.ts +4 -0
- package/cjs/domain/record/record.types.js +3 -0
- package/cjs/domain/record/record.types.js.map +1 -0
- package/cjs/domain/record/recordingScope.d.ts +19 -0
- package/cjs/domain/record/recordingScope.js +13 -0
- package/cjs/domain/record/recordingScope.js.map +1 -0
- package/cjs/domain/record/serialization/index.d.ts +8 -0
- package/cjs/domain/record/serialization/index.js +18 -0
- package/cjs/domain/record/serialization/index.js.map +1 -0
- package/cjs/domain/record/serialization/serialization.types.d.ts +28 -0
- package/cjs/domain/record/serialization/serialization.types.js +3 -0
- package/cjs/domain/record/serialization/serialization.types.js.map +1 -0
- package/cjs/domain/record/serialization/serializationStats.d.ts +12 -0
- package/cjs/domain/record/serialization/serializationStats.js +32 -0
- package/cjs/domain/record/serialization/serializationStats.js.map +1 -0
- package/cjs/domain/record/serialization/serializationTransaction.d.ts +45 -0
- package/cjs/domain/record/serialization/serializationTransaction.js +38 -0
- package/cjs/domain/record/serialization/serializationTransaction.js.map +1 -0
- package/cjs/domain/record/serialization/serializationUtils.d.ts +18 -0
- package/cjs/domain/record/serialization/serializationUtils.js +88 -0
- package/cjs/domain/record/serialization/serializationUtils.js.map +1 -0
- package/cjs/domain/record/serialization/serializeAttribute.d.ts +4 -0
- package/cjs/domain/record/serialization/serializeAttribute.js +42 -0
- package/cjs/domain/record/serialization/serializeAttribute.js.map +1 -0
- package/cjs/domain/record/serialization/serializeAttributes.d.ts +7 -0
- package/cjs/domain/record/serialization/serializeAttributes.js +167 -0
- package/cjs/domain/record/serialization/serializeAttributes.js.map +1 -0
- package/cjs/domain/record/serialization/serializeDocument.d.ts +3 -0
- package/cjs/domain/record/serialization/serializeDocument.js +11 -0
- package/cjs/domain/record/serialization/serializeDocument.js.map +1 -0
- package/cjs/domain/record/serialization/serializeNode.d.ts +7 -0
- package/cjs/domain/record/serialization/serializeNode.js +154 -0
- package/cjs/domain/record/serialization/serializeNode.js.map +1 -0
- package/cjs/domain/record/serialization/serializeStyleSheets.d.ts +2 -0
- package/cjs/domain/record/serialization/serializeStyleSheets.js +19 -0
- package/cjs/domain/record/serialization/serializeStyleSheets.js.map +1 -0
- package/cjs/domain/record/shadowRootsController.d.ts +11 -0
- package/cjs/domain/record/shadowRootsController.js +45 -0
- package/cjs/domain/record/shadowRootsController.js.map +1 -0
- package/cjs/domain/record/startFullSnapshots.d.ts +9 -0
- package/cjs/domain/record/startFullSnapshots.js +59 -0
- package/cjs/domain/record/startFullSnapshots.js.map +1 -0
- package/cjs/domain/record/trackers/index.d.ts +12 -0
- package/cjs/domain/record/trackers/index.js +27 -0
- package/cjs/domain/record/trackers/index.js.map +1 -0
- package/cjs/domain/record/trackers/trackFocus.d.ts +5 -0
- package/cjs/domain/record/trackers/trackFocus.js +15 -0
- package/cjs/domain/record/trackers/trackFocus.js.map +1 -0
- package/cjs/domain/record/trackers/trackFrustration.d.ts +7 -0
- package/cjs/domain/record/trackers/trackFrustration.js +31 -0
- package/cjs/domain/record/trackers/trackFrustration.js.map +1 -0
- package/cjs/domain/record/trackers/trackInput.d.ts +4 -0
- package/cjs/domain/record/trackers/trackInput.js +104 -0
- package/cjs/domain/record/trackers/trackInput.js.map +1 -0
- package/cjs/domain/record/trackers/trackMediaInteraction.d.ts +5 -0
- package/cjs/domain/record/trackers/trackMediaInteraction.js +29 -0
- package/cjs/domain/record/trackers/trackMediaInteraction.js.map +1 -0
- package/cjs/domain/record/trackers/trackMouseInteraction.d.ts +5 -0
- package/cjs/domain/record/trackers/trackMouseInteraction.js +59 -0
- package/cjs/domain/record/trackers/trackMouseInteraction.js.map +1 -0
- package/cjs/domain/record/trackers/trackMove.d.ts +9 -0
- package/cjs/domain/record/trackers/trackMove.js +55 -0
- package/cjs/domain/record/trackers/trackMove.js.map +1 -0
- package/cjs/domain/record/trackers/trackMutation.d.ts +11 -0
- package/cjs/domain/record/trackers/trackMutation.js +270 -0
- package/cjs/domain/record/trackers/trackMutation.js.map +1 -0
- package/cjs/domain/record/trackers/trackScroll.d.ts +5 -0
- package/cjs/domain/record/trackers/trackScroll.js +48 -0
- package/cjs/domain/record/trackers/trackScroll.js.map +1 -0
- package/cjs/domain/record/trackers/trackStyleSheet.d.ts +6 -0
- package/cjs/domain/record/trackers/trackStyleSheet.js +89 -0
- package/cjs/domain/record/trackers/trackStyleSheet.js.map +1 -0
- package/cjs/domain/record/trackers/trackViewEnd.d.ts +5 -0
- package/cjs/domain/record/trackers/trackViewEnd.js +20 -0
- package/cjs/domain/record/trackers/trackViewEnd.js.map +1 -0
- package/cjs/domain/record/trackers/trackViewportResize.d.ts +6 -0
- package/cjs/domain/record/trackers/trackViewportResize.js +46 -0
- package/cjs/domain/record/trackers/trackViewportResize.js.map +1 -0
- package/cjs/domain/record/trackers/tracker.types.d.ts +3 -0
- package/cjs/domain/record/trackers/tracker.types.js +3 -0
- package/cjs/domain/record/trackers/tracker.types.js.map +1 -0
- package/cjs/domain/record/viewports.d.ts +20 -0
- package/cjs/domain/record/viewports.js +60 -0
- package/cjs/domain/record/viewports.js.map +1 -0
- package/cjs/domain/replayStats.d.ts +8 -0
- package/cjs/domain/replayStats.js +60 -0
- package/cjs/domain/replayStats.js.map +1 -0
- package/cjs/domain/scriptLoadingError.d.ts +6 -0
- package/cjs/domain/scriptLoadingError.js +26 -0
- package/cjs/domain/scriptLoadingError.js.map +1 -0
- package/cjs/domain/segmentCollection/buildReplayPayload.d.ts +15 -0
- package/cjs/domain/segmentCollection/buildReplayPayload.js +26 -0
- package/cjs/domain/segmentCollection/buildReplayPayload.js.map +1 -0
- package/cjs/domain/segmentCollection/index.d.ts +4 -0
- package/cjs/domain/segmentCollection/index.js +11 -0
- package/cjs/domain/segmentCollection/index.js.map +1 -0
- package/cjs/domain/segmentCollection/segment.d.ts +16 -0
- package/cjs/domain/segmentCollection/segment.js +82 -0
- package/cjs/domain/segmentCollection/segment.js.map +1 -0
- package/cjs/domain/segmentCollection/segmentCollection.d.ts +31 -0
- package/cjs/domain/segmentCollection/segmentCollection.js +113 -0
- package/cjs/domain/segmentCollection/segmentCollection.js.map +1 -0
- package/cjs/domain/segmentCollection/startSegmentTelemetry.d.ts +6 -0
- package/cjs/domain/segmentCollection/startSegmentTelemetry.js +47 -0
- package/cjs/domain/segmentCollection/startSegmentTelemetry.js.map +1 -0
- package/cjs/domain/startRecordBridge.d.ts +5 -0
- package/cjs/domain/startRecordBridge.js +17 -0
- package/cjs/domain/startRecordBridge.js.map +1 -0
- package/cjs/domain/startRecorderInitTelemetry.d.ts +15 -0
- package/cjs/domain/startRecorderInitTelemetry.js +55 -0
- package/cjs/domain/startRecorderInitTelemetry.js.map +1 -0
- package/cjs/entries/internal.d.ts +11 -0
- package/cjs/entries/internal.js +28 -0
- package/cjs/entries/internal.js.map +1 -0
- package/cjs/entries/internalSynthetics.d.ts +2 -0
- package/cjs/entries/internalSynthetics.js +27 -0
- package/cjs/entries/internalSynthetics.js.map +1 -0
- package/cjs/entries/main.d.ts +23 -0
- package/cjs/entries/main.js +35 -0
- package/cjs/entries/main.js.map +1 -0
- package/cjs/types/index.d.ts +2 -0
- package/cjs/types/index.js +18 -0
- package/cjs/types/index.js.map +1 -0
- package/cjs/types/sessionReplay.d.ts +703 -0
- package/cjs/types/sessionReplay.js +7 -0
- package/cjs/types/sessionReplay.js.map +1 -0
- package/cjs/types/sessionReplayConstants.d.ts +49 -0
- package/cjs/types/sessionReplayConstants.js +49 -0
- package/cjs/types/sessionReplayConstants.js.map +1 -0
- package/esm/boot/isBrowserSupported.d.ts +4 -0
- package/esm/boot/isBrowserSupported.js +14 -0
- package/esm/boot/isBrowserSupported.js.map +1 -0
- package/esm/boot/lazyLoadProfiler.d.ts +4 -0
- package/esm/boot/lazyLoadProfiler.js +18 -0
- package/esm/boot/lazyLoadProfiler.js.map +1 -0
- package/esm/boot/lazyLoadRecorder.d.ts +4 -0
- package/esm/boot/lazyLoadRecorder.js +18 -0
- package/esm/boot/lazyLoadRecorder.js.map +1 -0
- package/esm/boot/postStartStrategy.d.ts +33 -0
- package/esm/boot/postStartStrategy.js +95 -0
- package/esm/boot/postStartStrategy.js.map +1 -0
- package/esm/boot/preStartStrategy.d.ts +6 -0
- package/esm/boot/preStartStrategy.js +21 -0
- package/esm/boot/preStartStrategy.js.map +1 -0
- package/esm/boot/profilerApi.d.ts +2 -0
- package/esm/boot/profilerApi.js +50 -0
- package/esm/boot/profilerApi.js.map +1 -0
- package/esm/boot/recorderApi.d.ts +4 -0
- package/esm/boot/recorderApi.js +70 -0
- package/esm/boot/recorderApi.js.map +1 -0
- package/esm/boot/startRecording.d.ts +6 -0
- package/esm/boot/startRecording.js +42 -0
- package/esm/boot/startRecording.js.map +1 -0
- package/esm/domain/deflate/deflateEncoder.d.ts +3 -0
- package/esm/domain/deflate/deflateEncoder.js +107 -0
- package/esm/domain/deflate/deflateEncoder.js.map +1 -0
- package/esm/domain/deflate/deflateWorker.d.ts +30 -0
- package/esm/domain/deflate/deflateWorker.js +97 -0
- package/esm/domain/deflate/deflateWorker.js.map +1 -0
- package/esm/domain/deflate/index.d.ts +3 -0
- package/esm/domain/deflate/index.js +3 -0
- package/esm/domain/deflate/index.js.map +1 -0
- package/esm/domain/getSessionReplayLink.d.ts +2 -0
- package/esm/domain/getSessionReplayLink.js +32 -0
- package/esm/domain/getSessionReplayLink.js.map +1 -0
- package/esm/domain/profiling/profiler.d.ts +7 -0
- package/esm/domain/profiling/profiler.js +240 -0
- package/esm/domain/profiling/profiler.js.map +1 -0
- package/esm/domain/profiling/profilingContext.d.ts +6 -0
- package/esm/domain/profiling/profilingContext.js +25 -0
- package/esm/domain/profiling/profilingContext.js.map +1 -0
- package/esm/domain/profiling/profilingSupported.d.ts +1 -0
- package/esm/domain/profiling/profilingSupported.js +8 -0
- package/esm/domain/profiling/profilingSupported.js.map +1 -0
- package/esm/domain/profiling/test-utils/mockedTrace.d.ts +3 -0
- package/esm/domain/profiling/test-utils/mockedTrace.js +54 -0
- package/esm/domain/profiling/test-utils/mockedTrace.js.map +1 -0
- package/esm/domain/profiling/transport/assembly.d.ts +21 -0
- package/esm/domain/profiling/transport/assembly.js +42 -0
- package/esm/domain/profiling/transport/assembly.js.map +1 -0
- package/esm/domain/profiling/transport/buildProfileEventAttributes.d.ts +25 -0
- package/esm/domain/profiling/transport/buildProfileEventAttributes.js +47 -0
- package/esm/domain/profiling/transport/buildProfileEventAttributes.js.map +1 -0
- package/esm/domain/profiling/types/index.d.ts +2 -0
- package/esm/domain/profiling/types/index.js +2 -0
- package/esm/domain/profiling/types/index.js.map +1 -0
- package/esm/domain/profiling/types/profilerApi.types.d.ts +58 -0
- package/esm/domain/profiling/types/profilerApi.types.js +4 -0
- package/esm/domain/profiling/types/profilerApi.types.js.map +1 -0
- package/esm/domain/profiling/types/rumProfiler.types.d.ts +72 -0
- package/esm/domain/profiling/types/rumProfiler.types.js +2 -0
- package/esm/domain/profiling/types/rumProfiler.types.js.map +1 -0
- package/esm/domain/profiling/utils/getCustomOrDefaultViewName.d.ts +1 -0
- package/esm/domain/profiling/utils/getCustomOrDefaultViewName.js +3 -0
- package/esm/domain/profiling/utils/getCustomOrDefaultViewName.js.map +1 -0
- package/esm/domain/profiling/utils/getDefaultViewName.d.ts +1 -0
- package/esm/domain/profiling/utils/getDefaultViewName.js +11 -0
- package/esm/domain/profiling/utils/getDefaultViewName.js.map +1 -0
- package/esm/domain/profiling/utils/getNumberOfSamples.d.ts +7 -0
- package/esm/domain/profiling/utils/getNumberOfSamples.js +15 -0
- package/esm/domain/profiling/utils/getNumberOfSamples.js.map +1 -0
- package/esm/domain/record/assembly.d.ts +2 -0
- package/esm/domain/record/assembly.js +13 -0
- package/esm/domain/record/assembly.js.map +1 -0
- package/esm/domain/record/elementsScrollPositions.d.ts +10 -0
- package/esm/domain/record/elementsScrollPositions.js +20 -0
- package/esm/domain/record/elementsScrollPositions.js.map +1 -0
- package/esm/domain/record/eventIds.d.ts +4 -0
- package/esm/domain/record/eventIds.js +13 -0
- package/esm/domain/record/eventIds.js.map +1 -0
- package/esm/domain/record/eventsUtils.d.ts +2 -0
- package/esm/domain/record/eventsUtils.js +11 -0
- package/esm/domain/record/eventsUtils.js.map +1 -0
- package/esm/domain/record/index.d.ts +7 -0
- package/esm/domain/record/index.js +6 -0
- package/esm/domain/record/index.js.map +1 -0
- package/esm/domain/record/internalApi.d.ts +22 -0
- package/esm/domain/record/internalApi.js +53 -0
- package/esm/domain/record/internalApi.js.map +1 -0
- package/esm/domain/record/mutationBatch.d.ts +12 -0
- package/esm/domain/record/mutationBatch.js +40 -0
- package/esm/domain/record/mutationBatch.js.map +1 -0
- package/esm/domain/record/nodeIds.d.ts +15 -0
- package/esm/domain/record/nodeIds.js +29 -0
- package/esm/domain/record/nodeIds.js.map +1 -0
- package/esm/domain/record/record.d.ts +16 -0
- package/esm/domain/record/record.js +54 -0
- package/esm/domain/record/record.js.map +1 -0
- package/esm/domain/record/record.types.d.ts +4 -0
- package/esm/domain/record/record.types.js +2 -0
- package/esm/domain/record/record.types.js.map +1 -0
- package/esm/domain/record/recordingScope.d.ts +19 -0
- package/esm/domain/record/recordingScope.js +10 -0
- package/esm/domain/record/recordingScope.js.map +1 -0
- package/esm/domain/record/serialization/index.d.ts +8 -0
- package/esm/domain/record/serialization/index.js +7 -0
- package/esm/domain/record/serialization/index.js.map +1 -0
- package/esm/domain/record/serialization/serialization.types.d.ts +28 -0
- package/esm/domain/record/serialization/serialization.types.js +2 -0
- package/esm/domain/record/serialization/serialization.types.js.map +1 -0
- package/esm/domain/record/serialization/serializationStats.d.ts +12 -0
- package/esm/domain/record/serialization/serializationStats.js +27 -0
- package/esm/domain/record/serialization/serializationStats.js.map +1 -0
- package/esm/domain/record/serialization/serializationTransaction.d.ts +45 -0
- package/esm/domain/record/serialization/serializationTransaction.js +35 -0
- package/esm/domain/record/serialization/serializationTransaction.js.map +1 -0
- package/esm/domain/record/serialization/serializationUtils.d.ts +18 -0
- package/esm/domain/record/serialization/serializationUtils.js +80 -0
- package/esm/domain/record/serialization/serializationUtils.js.map +1 -0
- package/esm/domain/record/serialization/serializeAttribute.d.ts +4 -0
- package/esm/domain/record/serialization/serializeAttribute.js +38 -0
- package/esm/domain/record/serialization/serializeAttribute.js.map +1 -0
- package/esm/domain/record/serialization/serializeAttributes.d.ts +7 -0
- package/esm/domain/record/serialization/serializeAttributes.js +161 -0
- package/esm/domain/record/serialization/serializeAttributes.js.map +1 -0
- package/esm/domain/record/serialization/serializeDocument.d.ts +3 -0
- package/esm/domain/record/serialization/serializeDocument.js +8 -0
- package/esm/domain/record/serialization/serializeDocument.js.map +1 -0
- package/esm/domain/record/serialization/serializeNode.d.ts +7 -0
- package/esm/domain/record/serialization/serializeNode.js +149 -0
- package/esm/domain/record/serialization/serializeNode.js.map +1 -0
- package/esm/domain/record/serialization/serializeStyleSheets.d.ts +2 -0
- package/esm/domain/record/serialization/serializeStyleSheets.js +16 -0
- package/esm/domain/record/serialization/serializeStyleSheets.js.map +1 -0
- package/esm/domain/record/shadowRootsController.d.ts +11 -0
- package/esm/domain/record/shadowRootsController.js +41 -0
- package/esm/domain/record/shadowRootsController.js.map +1 -0
- package/esm/domain/record/startFullSnapshots.d.ts +9 -0
- package/esm/domain/record/startFullSnapshots.js +55 -0
- package/esm/domain/record/startFullSnapshots.js.map +1 -0
- package/esm/domain/record/trackers/index.d.ts +12 -0
- package/esm/domain/record/trackers/index.js +12 -0
- package/esm/domain/record/trackers/index.js.map +1 -0
- package/esm/domain/record/trackers/trackFocus.d.ts +5 -0
- package/esm/domain/record/trackers/trackFocus.js +12 -0
- package/esm/domain/record/trackers/trackFocus.js.map +1 -0
- package/esm/domain/record/trackers/trackFrustration.d.ts +7 -0
- package/esm/domain/record/trackers/trackFrustration.js +28 -0
- package/esm/domain/record/trackers/trackFrustration.js.map +1 -0
- package/esm/domain/record/trackers/trackInput.d.ts +4 -0
- package/esm/domain/record/trackers/trackInput.js +101 -0
- package/esm/domain/record/trackers/trackInput.js.map +1 -0
- package/esm/domain/record/trackers/trackMediaInteraction.d.ts +5 -0
- package/esm/domain/record/trackers/trackMediaInteraction.js +26 -0
- package/esm/domain/record/trackers/trackMediaInteraction.js.map +1 -0
- package/esm/domain/record/trackers/trackMouseInteraction.d.ts +5 -0
- package/esm/domain/record/trackers/trackMouseInteraction.js +56 -0
- package/esm/domain/record/trackers/trackMouseInteraction.js.map +1 -0
- package/esm/domain/record/trackers/trackMove.d.ts +9 -0
- package/esm/domain/record/trackers/trackMove.js +51 -0
- package/esm/domain/record/trackers/trackMove.js.map +1 -0
- package/esm/domain/record/trackers/trackMutation.d.ts +11 -0
- package/esm/domain/record/trackers/trackMutation.js +266 -0
- package/esm/domain/record/trackers/trackMutation.js.map +1 -0
- package/esm/domain/record/trackers/trackScroll.d.ts +5 -0
- package/esm/domain/record/trackers/trackScroll.js +45 -0
- package/esm/domain/record/trackers/trackScroll.js.map +1 -0
- package/esm/domain/record/trackers/trackStyleSheet.d.ts +6 -0
- package/esm/domain/record/trackers/trackStyleSheet.js +85 -0
- package/esm/domain/record/trackers/trackStyleSheet.js.map +1 -0
- package/esm/domain/record/trackers/trackViewEnd.d.ts +5 -0
- package/esm/domain/record/trackers/trackViewEnd.js +17 -0
- package/esm/domain/record/trackers/trackViewEnd.js.map +1 -0
- package/esm/domain/record/trackers/trackViewportResize.d.ts +6 -0
- package/esm/domain/record/trackers/trackViewportResize.js +42 -0
- package/esm/domain/record/trackers/trackViewportResize.js.map +1 -0
- package/esm/domain/record/trackers/tracker.types.d.ts +3 -0
- package/esm/domain/record/trackers/tracker.types.js +2 -0
- package/esm/domain/record/trackers/tracker.types.js.map +1 -0
- package/esm/domain/record/viewports.d.ts +20 -0
- package/esm/domain/record/viewports.js +55 -0
- package/esm/domain/record/viewports.js.map +1 -0
- package/esm/domain/replayStats.d.ts +8 -0
- package/esm/domain/replayStats.js +51 -0
- package/esm/domain/replayStats.js.map +1 -0
- package/esm/domain/scriptLoadingError.d.ts +6 -0
- package/esm/domain/scriptLoadingError.js +23 -0
- package/esm/domain/scriptLoadingError.js.map +1 -0
- package/esm/domain/segmentCollection/buildReplayPayload.d.ts +15 -0
- package/esm/domain/segmentCollection/buildReplayPayload.js +23 -0
- package/esm/domain/segmentCollection/buildReplayPayload.js.map +1 -0
- package/esm/domain/segmentCollection/index.d.ts +4 -0
- package/esm/domain/segmentCollection/index.js +4 -0
- package/esm/domain/segmentCollection/index.js.map +1 -0
- package/esm/domain/segmentCollection/segment.d.ts +16 -0
- package/esm/domain/segmentCollection/segment.js +46 -0
- package/esm/domain/segmentCollection/segment.js.map +1 -0
- package/esm/domain/segmentCollection/segmentCollection.d.ts +31 -0
- package/esm/domain/segmentCollection/segmentCollection.js +106 -0
- package/esm/domain/segmentCollection/segmentCollection.js.map +1 -0
- package/esm/domain/segmentCollection/startSegmentTelemetry.d.ts +6 -0
- package/esm/domain/segmentCollection/startSegmentTelemetry.js +44 -0
- package/esm/domain/segmentCollection/startSegmentTelemetry.js.map +1 -0
- package/esm/domain/startRecordBridge.d.ts +5 -0
- package/esm/domain/startRecordBridge.js +14 -0
- package/esm/domain/startRecordBridge.js.map +1 -0
- package/esm/domain/startRecorderInitTelemetry.d.ts +15 -0
- package/esm/domain/startRecorderInitTelemetry.js +52 -0
- package/esm/domain/startRecorderInitTelemetry.js.map +1 -0
- package/esm/entries/internal.d.ts +11 -0
- package/esm/entries/internal.js +4 -0
- package/esm/entries/internal.js.map +1 -0
- package/esm/entries/internalSynthetics.d.ts +2 -0
- package/esm/entries/internalSynthetics.js +23 -0
- package/esm/entries/internalSynthetics.js.map +1 -0
- package/esm/entries/main.d.ts +23 -0
- package/esm/entries/main.js +31 -0
- package/esm/entries/main.js.map +1 -0
- package/esm/types/index.d.ts +2 -0
- package/esm/types/index.js +2 -0
- package/esm/types/index.js.map +1 -0
- package/esm/types/sessionReplay.d.ts +703 -0
- package/esm/types/sessionReplay.js +6 -0
- package/esm/types/sessionReplay.js.map +1 -0
- package/esm/types/sessionReplayConstants.d.ts +49 -0
- package/esm/types/sessionReplayConstants.js +46 -0
- package/esm/types/sessionReplayConstants.js.map +1 -0
- package/internal/package.json +6 -0
- package/internal-synthetics/package.json +6 -0
- package/package.json +40 -0
- package/src/boot/isBrowserSupported.ts +14 -0
- package/src/boot/lazyLoadProfiler.ts +21 -0
- package/src/boot/lazyLoadRecorder.ts +21 -0
- package/src/boot/postStartStrategy.ts +176 -0
- package/src/boot/preStartStrategy.ts +34 -0
- package/src/boot/profilerApi.ts +86 -0
- package/src/boot/recorderApi.ts +124 -0
- package/src/boot/startRecording.ts +70 -0
- package/src/domain/deflate/deflateEncoder.ts +144 -0
- package/src/domain/deflate/deflateWorker.ts +157 -0
- package/src/domain/deflate/index.ts +8 -0
- package/src/domain/getSessionReplayLink.ts +40 -0
- package/src/domain/profiling/profiler.ts +338 -0
- package/src/domain/profiling/profilingContext.ts +34 -0
- package/src/domain/profiling/profilingSupported.ts +10 -0
- package/src/domain/profiling/test-utils/mockedTrace.ts +58 -0
- package/src/domain/profiling/transport/assembly.ts +78 -0
- package/src/domain/profiling/transport/buildProfileEventAttributes.ts +66 -0
- package/src/domain/profiling/types/index.ts +2 -0
- package/src/domain/profiling/types/profilerApi.types.ts +87 -0
- package/src/domain/profiling/types/rumProfiler.types.ts +81 -0
- package/src/domain/profiling/utils/getCustomOrDefaultViewName.ts +4 -0
- package/src/domain/profiling/utils/getDefaultViewName.ts +12 -0
- package/src/domain/profiling/utils/getNumberOfSamples.ts +16 -0
- package/src/domain/record/assembly.ts +17 -0
- package/src/domain/record/elementsScrollPositions.ts +28 -0
- package/src/domain/record/eventIds.ts +17 -0
- package/src/domain/record/eventsUtils.ts +12 -0
- package/src/domain/record/index.ts +7 -0
- package/src/domain/record/internalApi.ts +88 -0
- package/src/domain/record/mutationBatch.ts +47 -0
- package/src/domain/record/nodeIds.ts +46 -0
- package/src/domain/record/record.ts +98 -0
- package/src/domain/record/record.types.ts +5 -0
- package/src/domain/record/recordingScope.ts +36 -0
- package/src/domain/record/serialization/index.ts +8 -0
- package/src/domain/record/serialization/serialization.types.ts +43 -0
- package/src/domain/record/serialization/serializationStats.ts +43 -0
- package/src/domain/record/serialization/serializationTransaction.ts +94 -0
- package/src/domain/record/serialization/serializationUtils.ts +103 -0
- package/src/domain/record/serialization/serializeAttribute.ts +55 -0
- package/src/domain/record/serialization/serializeAttributes.ts +194 -0
- package/src/domain/record/serialization/serializeDocument.ts +13 -0
- package/src/domain/record/serialization/serializeNode.ts +229 -0
- package/src/domain/record/serialization/serializeStyleSheets.ts +18 -0
- package/src/domain/record/shadowRootsController.ts +62 -0
- package/src/domain/record/startFullSnapshots.ts +84 -0
- package/src/domain/record/trackers/index.ts +12 -0
- package/src/domain/record/trackers/trackFocus.ts +16 -0
- package/src/domain/record/trackers/trackFrustration.ts +41 -0
- package/src/domain/record/trackers/trackInput.ts +128 -0
- package/src/domain/record/trackers/trackMediaInteraction.ts +43 -0
- package/src/domain/record/trackers/trackMouseInteraction.ts +74 -0
- package/src/domain/record/trackers/trackMove.ts +78 -0
- package/src/domain/record/trackers/trackMutation.ts +399 -0
- package/src/domain/record/trackers/trackScroll.ts +61 -0
- package/src/domain/record/trackers/trackStyleSheet.ts +117 -0
- package/src/domain/record/trackers/trackViewEnd.ts +27 -0
- package/src/domain/record/trackers/trackViewportResize.ts +69 -0
- package/src/domain/record/trackers/tracker.types.ts +3 -0
- package/src/domain/record/viewports.ts +68 -0
- package/src/domain/replayStats.ts +61 -0
- package/src/domain/scriptLoadingError.ts +36 -0
- package/src/domain/segmentCollection/buildReplayPayload.ts +52 -0
- package/src/domain/segmentCollection/index.ts +4 -0
- package/src/domain/segmentCollection/segment.ts +78 -0
- package/src/domain/segmentCollection/segmentCollection.ts +200 -0
- package/src/domain/segmentCollection/startSegmentTelemetry.ts +82 -0
- package/src/domain/startRecordBridge.ts +17 -0
- package/src/domain/startRecorderInitTelemetry.ts +90 -0
- package/src/entries/internal.ts +18 -0
- package/src/entries/internalSynthetics.ts +24 -0
- package/src/entries/main.ts +95 -0
- package/src/types/index.ts +2 -0
- package/src/types/sessionReplay.ts +734 -0
- package/src/types/sessionReplayConstants.ts +86 -0
|
@@ -0,0 +1,338 @@
|
|
|
1
|
+
import type { Encoder } from '@kubesense/kubesense-browser-core'
|
|
2
|
+
import {
|
|
3
|
+
addEventListener,
|
|
4
|
+
clearTimeout,
|
|
5
|
+
setTimeout,
|
|
6
|
+
DOM_EVENT,
|
|
7
|
+
monitorError,
|
|
8
|
+
display,
|
|
9
|
+
getGlobalObject,
|
|
10
|
+
clocksOrigin,
|
|
11
|
+
clocksNow,
|
|
12
|
+
elapsed,
|
|
13
|
+
DeflateEncoderStreamId,
|
|
14
|
+
} from '@kubesense/kubesense-browser-core'
|
|
15
|
+
|
|
16
|
+
import type {
|
|
17
|
+
LifeCycle,
|
|
18
|
+
LongTaskContexts,
|
|
19
|
+
RumConfiguration,
|
|
20
|
+
RumSessionManager,
|
|
21
|
+
TransportPayload,
|
|
22
|
+
ViewHistory,
|
|
23
|
+
} from '@kubesense/kubesense-browser-rum-core'
|
|
24
|
+
import { createFormDataTransport, LifeCycleEventType } from '@kubesense/kubesense-browser-rum-core'
|
|
25
|
+
import type {
|
|
26
|
+
RumProfilerTrace,
|
|
27
|
+
RumProfilerInstance,
|
|
28
|
+
Profiler,
|
|
29
|
+
RUMProfiler,
|
|
30
|
+
RUMProfilerConfiguration,
|
|
31
|
+
RumProfilerStoppedInstance,
|
|
32
|
+
RumViewEntry,
|
|
33
|
+
} from './types'
|
|
34
|
+
import { getNumberOfSamples } from './utils/getNumberOfSamples'
|
|
35
|
+
import type { ProfilingContextManager } from './profilingContext'
|
|
36
|
+
import { getCustomOrDefaultViewName } from './utils/getCustomOrDefaultViewName'
|
|
37
|
+
import { assembleProfilingPayload } from './transport/assembly'
|
|
38
|
+
|
|
39
|
+
export const DEFAULT_RUM_PROFILER_CONFIGURATION: RUMProfilerConfiguration = {
|
|
40
|
+
sampleIntervalMs: 10, // Sample stack trace every 10ms
|
|
41
|
+
collectIntervalMs: 60000, // Collect data every minute
|
|
42
|
+
minProfileDurationMs: 5000, // Require at least 5 seconds of profile data to reduce noise and cost
|
|
43
|
+
minNumberOfSamples: 50, // Require at least 50 samples (~500 ms) to report a profile to reduce noise and cost
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export function createRumProfiler(
|
|
47
|
+
configuration: RumConfiguration,
|
|
48
|
+
lifeCycle: LifeCycle,
|
|
49
|
+
session: RumSessionManager,
|
|
50
|
+
profilingContextManager: ProfilingContextManager,
|
|
51
|
+
longTaskContexts: LongTaskContexts,
|
|
52
|
+
createEncoder: (streamId: DeflateEncoderStreamId) => Encoder,
|
|
53
|
+
viewHistory: ViewHistory,
|
|
54
|
+
profilerConfiguration: RUMProfilerConfiguration = DEFAULT_RUM_PROFILER_CONFIGURATION
|
|
55
|
+
): RUMProfiler {
|
|
56
|
+
const transport = createFormDataTransport(configuration, lifeCycle, createEncoder, DeflateEncoderStreamId.PROFILING)
|
|
57
|
+
|
|
58
|
+
let lastViewEntry: RumViewEntry | undefined
|
|
59
|
+
|
|
60
|
+
// Global clean-up tasks for listeners that are not specific to a profiler instance (eg. visibility change, before unload)
|
|
61
|
+
const globalCleanupTasks: Array<() => void> = []
|
|
62
|
+
|
|
63
|
+
let instance: RumProfilerInstance = { state: 'stopped', stateReason: 'initializing' }
|
|
64
|
+
|
|
65
|
+
// Stops the profiler when session expires
|
|
66
|
+
lifeCycle.subscribe(LifeCycleEventType.SESSION_EXPIRED, () => {
|
|
67
|
+
stopProfiling('session-expired').catch(monitorError)
|
|
68
|
+
})
|
|
69
|
+
|
|
70
|
+
// Start the profiler again when session is renewed
|
|
71
|
+
lifeCycle.subscribe(LifeCycleEventType.SESSION_RENEWED, () => {
|
|
72
|
+
if (instance.state === 'stopped' && instance.stateReason === 'session-expired') {
|
|
73
|
+
start() // Only restart the profiler if it was stopped due to session expiration. Avoid restarting the profiler if it was stopped manually by the user.
|
|
74
|
+
}
|
|
75
|
+
})
|
|
76
|
+
|
|
77
|
+
// Public API to start the profiler.
|
|
78
|
+
function start(): void {
|
|
79
|
+
if (instance.state === 'running') {
|
|
80
|
+
return
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const viewEntry = viewHistory.findView()
|
|
84
|
+
|
|
85
|
+
// Add initial view
|
|
86
|
+
// Note: `viewEntry.name` is only filled when users use manual view creation via `startView` method.
|
|
87
|
+
lastViewEntry = viewEntry
|
|
88
|
+
? {
|
|
89
|
+
startClocks: viewEntry.startClocks,
|
|
90
|
+
viewId: viewEntry.id,
|
|
91
|
+
viewName: getCustomOrDefaultViewName(viewEntry.name, document.location.pathname),
|
|
92
|
+
}
|
|
93
|
+
: undefined
|
|
94
|
+
|
|
95
|
+
// Add global clean-up tasks for listeners that are not specific to a profiler instance (eg. visibility change, before unload)
|
|
96
|
+
globalCleanupTasks.push(
|
|
97
|
+
addEventListener(configuration, window, DOM_EVENT.VISIBILITY_CHANGE, handleVisibilityChange).stop,
|
|
98
|
+
addEventListener(configuration, window, DOM_EVENT.BEFORE_UNLOAD, handleBeforeUnload).stop
|
|
99
|
+
)
|
|
100
|
+
|
|
101
|
+
// Start profiler instance
|
|
102
|
+
startNextProfilerInstance()
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// Public API to manually stop the profiler.
|
|
106
|
+
async function stop() {
|
|
107
|
+
await stopProfiling('stopped-by-user')
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
async function stopProfiling(reason: RumProfilerStoppedInstance['stateReason']) {
|
|
111
|
+
// Stop current profiler instance
|
|
112
|
+
await stopProfilerInstance(reason)
|
|
113
|
+
|
|
114
|
+
// Cleanup global listeners
|
|
115
|
+
globalCleanupTasks.forEach((task) => task())
|
|
116
|
+
|
|
117
|
+
// Update Profiling status once the Profiler has been stopped.
|
|
118
|
+
profilingContextManager.set({ status: 'stopped', error_reason: undefined })
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Whenever a new Profiler instance is started, we need to add event listeners to surroundings (RUM Events, Long Tasks, etc) to enrich the Profiler data.
|
|
123
|
+
* If the instance is already running, we can keep the same event listeners.
|
|
124
|
+
*/
|
|
125
|
+
function addEventListeners(existingInstance: RumProfilerInstance) {
|
|
126
|
+
if (existingInstance.state === 'running') {
|
|
127
|
+
// Instance is already running, so we can keep same event listeners.
|
|
128
|
+
return {
|
|
129
|
+
cleanupTasks: existingInstance.cleanupTasks,
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// Store clean-up tasks for this instance (tasks to be executed when the Profiler is stopped or paused.)
|
|
134
|
+
const cleanupTasks = []
|
|
135
|
+
|
|
136
|
+
// Whenever the View is updated, we add a views entry to the profiler instance.
|
|
137
|
+
const viewUpdatedSubscription = lifeCycle.subscribe(LifeCycleEventType.VIEW_CREATED, (view) => {
|
|
138
|
+
const viewEntry = {
|
|
139
|
+
viewId: view.id,
|
|
140
|
+
// Note: `viewName` is only filled when users use manual view creation via `startView` method.
|
|
141
|
+
viewName: getCustomOrDefaultViewName(view.name, document.location.pathname),
|
|
142
|
+
startClocks: view.startClocks,
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
collectViewEntry(viewEntry)
|
|
146
|
+
|
|
147
|
+
// Update last view entry
|
|
148
|
+
lastViewEntry = viewEntry
|
|
149
|
+
})
|
|
150
|
+
cleanupTasks.push(viewUpdatedSubscription.unsubscribe)
|
|
151
|
+
|
|
152
|
+
return {
|
|
153
|
+
cleanupTasks,
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
function startNextProfilerInstance(): void {
|
|
158
|
+
// These APIs might be unavailable in some browsers
|
|
159
|
+
const globalThisProfiler: Profiler | undefined = getGlobalObject<any>().Profiler
|
|
160
|
+
|
|
161
|
+
if (!globalThisProfiler) {
|
|
162
|
+
profilingContextManager.set({ status: 'error', error_reason: 'not-supported-by-browser' })
|
|
163
|
+
throw new Error('RUM Profiler is not supported in this browser.')
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// Don't wait for data collection to start next instance
|
|
167
|
+
collectProfilerInstance(instance).catch(monitorError)
|
|
168
|
+
|
|
169
|
+
const { cleanupTasks } = addEventListeners(instance)
|
|
170
|
+
|
|
171
|
+
let profiler: Profiler
|
|
172
|
+
try {
|
|
173
|
+
// We have to create new Profiler each time we start a new instance
|
|
174
|
+
profiler = new globalThisProfiler({
|
|
175
|
+
sampleInterval: profilerConfiguration.sampleIntervalMs,
|
|
176
|
+
// Keep buffer size at 1.5 times of minimum required to collect data for a profiling instance
|
|
177
|
+
maxBufferSize: Math.round(
|
|
178
|
+
(profilerConfiguration.collectIntervalMs * 1.5) / profilerConfiguration.sampleIntervalMs
|
|
179
|
+
),
|
|
180
|
+
})
|
|
181
|
+
} catch (e) {
|
|
182
|
+
if (e instanceof Error && e.message.includes('disabled by Document Policy')) {
|
|
183
|
+
// Missing Response Header (`js-profiling`) that is required to enable the profiler.
|
|
184
|
+
// We should suggest the user to enable the Response Header in their server configuration.
|
|
185
|
+
display.warn(
|
|
186
|
+
'[KUBESENSE_SDK] Profiler startup failed. Ensure your server includes the `Document-Policy: js-profiling` response header when serving HTML pages.',
|
|
187
|
+
e
|
|
188
|
+
)
|
|
189
|
+
profilingContextManager.set({ status: 'error', error_reason: 'missing-document-policy-header' })
|
|
190
|
+
} else {
|
|
191
|
+
profilingContextManager.set({ status: 'error', error_reason: 'unexpected-exception' })
|
|
192
|
+
}
|
|
193
|
+
return
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
profilingContextManager.set({ status: 'running', error_reason: undefined })
|
|
197
|
+
|
|
198
|
+
// Kick-off the new instance
|
|
199
|
+
instance = {
|
|
200
|
+
state: 'running',
|
|
201
|
+
startClocks: clocksNow(),
|
|
202
|
+
profiler,
|
|
203
|
+
timeoutId: setTimeout(startNextProfilerInstance, profilerConfiguration.collectIntervalMs),
|
|
204
|
+
views: [],
|
|
205
|
+
cleanupTasks,
|
|
206
|
+
longTasks: [],
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
// Add last view entry
|
|
210
|
+
collectViewEntry(lastViewEntry)
|
|
211
|
+
|
|
212
|
+
// Add event handler case we overflow the buffer
|
|
213
|
+
profiler.addEventListener('samplebufferfull', handleSampleBufferFull)
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
async function collectProfilerInstance(lastInstance: RumProfilerInstance) {
|
|
217
|
+
if (lastInstance.state !== 'running') {
|
|
218
|
+
return
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
// Cleanup instance
|
|
222
|
+
clearTimeout(lastInstance.timeoutId)
|
|
223
|
+
lastInstance.profiler.removeEventListener('samplebufferfull', handleSampleBufferFull)
|
|
224
|
+
|
|
225
|
+
// Store instance data snapshot in local variables to use in async callback
|
|
226
|
+
const { startClocks, views } = lastInstance
|
|
227
|
+
|
|
228
|
+
// Stop current profiler to get trace
|
|
229
|
+
await lastInstance.profiler
|
|
230
|
+
.stop()
|
|
231
|
+
.then((trace) => {
|
|
232
|
+
const endClocks = clocksNow()
|
|
233
|
+
const longTasks = longTaskContexts.findLongTasks(startClocks.relative)
|
|
234
|
+
const isBelowDurationThreshold =
|
|
235
|
+
elapsed(startClocks.timeStamp, endClocks.timeStamp) < profilerConfiguration.minProfileDurationMs
|
|
236
|
+
const isBelowSampleThreshold = getNumberOfSamples(trace.samples) < profilerConfiguration.minNumberOfSamples
|
|
237
|
+
|
|
238
|
+
if (longTasks.length === 0 && (isBelowDurationThreshold || isBelowSampleThreshold)) {
|
|
239
|
+
// Skip very short profiles to reduce noise and cost, but keep them if they contain long tasks.
|
|
240
|
+
return
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
handleProfilerTrace(
|
|
244
|
+
// Enrich trace with time and instance data
|
|
245
|
+
Object.assign(trace, {
|
|
246
|
+
startClocks,
|
|
247
|
+
endClocks,
|
|
248
|
+
clocksOrigin: clocksOrigin(),
|
|
249
|
+
longTasks,
|
|
250
|
+
views,
|
|
251
|
+
sampleInterval: profilerConfiguration.sampleIntervalMs,
|
|
252
|
+
})
|
|
253
|
+
)
|
|
254
|
+
})
|
|
255
|
+
.catch(monitorError)
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
async function stopProfilerInstance(stateReason: RumProfilerStoppedInstance['stateReason']) {
|
|
259
|
+
if (instance.state !== 'running') {
|
|
260
|
+
return
|
|
261
|
+
}
|
|
262
|
+
await onPauseOrStopProfilerInstance()
|
|
263
|
+
instance = { state: 'stopped', stateReason }
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
async function pauseProfilerInstance() {
|
|
267
|
+
if (instance.state !== 'running') {
|
|
268
|
+
return
|
|
269
|
+
}
|
|
270
|
+
await onPauseOrStopProfilerInstance()
|
|
271
|
+
instance = { state: 'paused' }
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
async function onPauseOrStopProfilerInstance() {
|
|
275
|
+
if (instance.state !== 'running') {
|
|
276
|
+
return
|
|
277
|
+
}
|
|
278
|
+
// Cleanup tasks
|
|
279
|
+
instance.cleanupTasks.forEach((cleanupTask) => cleanupTask())
|
|
280
|
+
|
|
281
|
+
await collectProfilerInstance(instance)
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
function collectViewEntry(viewEntry: RumViewEntry | undefined): void {
|
|
285
|
+
if (instance.state !== 'running' || !viewEntry) {
|
|
286
|
+
return
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
// Add entry to views
|
|
290
|
+
instance.views.push(viewEntry)
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
function handleProfilerTrace(trace: RumProfilerTrace): void {
|
|
294
|
+
// Find current session to assign it to the Profile.
|
|
295
|
+
const sessionId = session.findTrackedSession()?.id
|
|
296
|
+
const payload = assembleProfilingPayload(trace, configuration, sessionId)
|
|
297
|
+
|
|
298
|
+
void transport.send(payload as unknown as TransportPayload)
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
function handleSampleBufferFull(): void {
|
|
302
|
+
startNextProfilerInstance()
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
function handleVisibilityChange(): void {
|
|
306
|
+
if (document.visibilityState === 'hidden' && instance.state === 'running') {
|
|
307
|
+
// Pause when tab is hidden. We use paused state to distinguish between
|
|
308
|
+
// paused by visibility change and stopped by user.
|
|
309
|
+
// If profiler is paused by the visibility change, we should resume when
|
|
310
|
+
// tab becomes visible again. That's not the case when user stops the profiler.
|
|
311
|
+
pauseProfilerInstance().catch(monitorError)
|
|
312
|
+
} else if (document.visibilityState === 'visible' && instance.state === 'paused') {
|
|
313
|
+
// Resume when tab becomes visible again
|
|
314
|
+
startNextProfilerInstance()
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
function handleBeforeUnload(): void {
|
|
319
|
+
// `unload` can in some cases be triggered while the page is still active (link to a different protocol like mailto:).
|
|
320
|
+
// We can immediately flush (by starting a new profiler instance) to make sure we receive the data, and at the same time keep the profiler active.
|
|
321
|
+
// In case of the regular unload, the profiler will be shut down anyway.
|
|
322
|
+
startNextProfilerInstance()
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
function isStopped() {
|
|
326
|
+
return instance.state === 'stopped'
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
function isRunning() {
|
|
330
|
+
return instance.state === 'running'
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
function isPaused() {
|
|
334
|
+
return instance.state === 'paused'
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
return { start, stop, isStopped, isRunning, isPaused }
|
|
338
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { HookNames, SKIPPED } from '@kubesense/kubesense-browser-core'
|
|
2
|
+
import type { Hooks, ProfilingInternalContextSchema } from '@kubesense/kubesense-browser-rum-core'
|
|
3
|
+
import { RumEventType } from '@kubesense/kubesense-browser-rum-core'
|
|
4
|
+
|
|
5
|
+
export interface ProfilingContextManager {
|
|
6
|
+
set: (next: ProfilingInternalContextSchema) => void
|
|
7
|
+
get: () => ProfilingInternalContextSchema | undefined
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export function startProfilingContext(hooks: Hooks): ProfilingContextManager {
|
|
11
|
+
let currentContext: ProfilingInternalContextSchema = {
|
|
12
|
+
status: 'starting',
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
hooks.register(HookNames.Assemble, ({ eventType }) => {
|
|
16
|
+
if (eventType !== RumEventType.VIEW && eventType !== RumEventType.LONG_TASK) {
|
|
17
|
+
return SKIPPED
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
return {
|
|
21
|
+
type: eventType,
|
|
22
|
+
_kubesense: {
|
|
23
|
+
profiling: currentContext,
|
|
24
|
+
},
|
|
25
|
+
}
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
return {
|
|
29
|
+
get: () => currentContext,
|
|
30
|
+
set: (newContext: ProfilingInternalContextSchema) => {
|
|
31
|
+
currentContext = newContext
|
|
32
|
+
},
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { getGlobalObject } from '@kubesense/kubesense-browser-core'
|
|
2
|
+
import type { Profiler } from './types'
|
|
3
|
+
|
|
4
|
+
export function isProfilingSupported(): boolean {
|
|
5
|
+
const globalThis = getGlobalObject()
|
|
6
|
+
|
|
7
|
+
// This API might be unavailable in some browsers
|
|
8
|
+
const globalThisProfiler: Profiler | undefined = (globalThis as any).Profiler
|
|
9
|
+
return globalThisProfiler !== undefined
|
|
10
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import type { ProfilerTrace } from '../types'
|
|
2
|
+
|
|
3
|
+
const generateFiftyRandomSamples = () => {
|
|
4
|
+
const samples = []
|
|
5
|
+
for (let i = 0; i < 50; i++) {
|
|
6
|
+
samples.push({
|
|
7
|
+
timestamp: i,
|
|
8
|
+
stackId: i % 3,
|
|
9
|
+
})
|
|
10
|
+
}
|
|
11
|
+
return samples
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
// eslint-disable-next-line local-rules/disallow-side-effects
|
|
15
|
+
const randomSamples = generateFiftyRandomSamples()
|
|
16
|
+
|
|
17
|
+
export const mockedEmptyTrace: ProfilerTrace = {
|
|
18
|
+
resources: [],
|
|
19
|
+
frames: [],
|
|
20
|
+
stacks: [],
|
|
21
|
+
samples: [],
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export const mockedTrace: ProfilerTrace = {
|
|
25
|
+
resources: ['resource1', 'resource2', 'resource3'],
|
|
26
|
+
frames: [
|
|
27
|
+
{
|
|
28
|
+
name: 'frame-0',
|
|
29
|
+
line: 1,
|
|
30
|
+
column: 1,
|
|
31
|
+
resourceId: 0,
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
name: 'frame-1',
|
|
35
|
+
line: 2,
|
|
36
|
+
column: 2,
|
|
37
|
+
resourceId: 1,
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
name: 'frame-2',
|
|
41
|
+
line: 3,
|
|
42
|
+
column: 3,
|
|
43
|
+
resourceId: 2,
|
|
44
|
+
},
|
|
45
|
+
],
|
|
46
|
+
stacks: [
|
|
47
|
+
{
|
|
48
|
+
frameId: 0,
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
frameId: 1,
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
frameId: 2,
|
|
55
|
+
},
|
|
56
|
+
],
|
|
57
|
+
samples: randomSamples,
|
|
58
|
+
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { buildTags, currentDrift } from '@kubesense/kubesense-browser-core'
|
|
2
|
+
import type { RumConfiguration } from '@kubesense/kubesense-browser-rum-core'
|
|
3
|
+
import type { RumProfilerTrace } from '../types'
|
|
4
|
+
import { buildProfileEventAttributes } from './buildProfileEventAttributes'
|
|
5
|
+
import type { ProfileEventAttributes } from './buildProfileEventAttributes'
|
|
6
|
+
|
|
7
|
+
export interface ProfileEvent extends ProfileEventAttributes {
|
|
8
|
+
attachments: string[]
|
|
9
|
+
start: string // ISO date
|
|
10
|
+
end: string // ISO date
|
|
11
|
+
family: 'chrome'
|
|
12
|
+
runtime: 'chrome'
|
|
13
|
+
format: 'json'
|
|
14
|
+
version: 4
|
|
15
|
+
tags_profiler: string
|
|
16
|
+
_kubesense: {
|
|
17
|
+
clock_drift: number
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface ProfileEventPayload {
|
|
22
|
+
event: ProfileEvent
|
|
23
|
+
'wall-time.json': RumProfilerTrace
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export function assembleProfilingPayload(
|
|
27
|
+
profilerTrace: RumProfilerTrace,
|
|
28
|
+
configuration: RumConfiguration,
|
|
29
|
+
sessionId: string | undefined
|
|
30
|
+
): ProfileEventPayload {
|
|
31
|
+
const event = buildProfileEvent(profilerTrace, configuration, sessionId)
|
|
32
|
+
|
|
33
|
+
return {
|
|
34
|
+
event,
|
|
35
|
+
'wall-time.json': profilerTrace,
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function buildProfileEvent(
|
|
40
|
+
profilerTrace: RumProfilerTrace,
|
|
41
|
+
configuration: RumConfiguration,
|
|
42
|
+
sessionId: string | undefined
|
|
43
|
+
): ProfileEvent {
|
|
44
|
+
const tags = buildTags(configuration) // TODO: get that from the tagContext hook
|
|
45
|
+
const profileAttributes = buildProfileEventAttributes(profilerTrace, configuration.applicationId, sessionId)
|
|
46
|
+
const profileEventTags = buildProfileEventTags(tags)
|
|
47
|
+
|
|
48
|
+
const profileEvent: ProfileEvent = {
|
|
49
|
+
...profileAttributes,
|
|
50
|
+
attachments: ['wall-time.json'],
|
|
51
|
+
start: new Date(profilerTrace.startClocks.timeStamp).toISOString(),
|
|
52
|
+
end: new Date(profilerTrace.endClocks.timeStamp).toISOString(),
|
|
53
|
+
family: 'chrome',
|
|
54
|
+
runtime: 'chrome',
|
|
55
|
+
format: 'json',
|
|
56
|
+
version: 4, // Ingestion event version (not the version application tag)
|
|
57
|
+
tags_profiler: profileEventTags.join(','),
|
|
58
|
+
_kubesense: {
|
|
59
|
+
clock_drift: currentDrift(),
|
|
60
|
+
},
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
return profileEvent
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Builds tags for the Profile Event.
|
|
68
|
+
*
|
|
69
|
+
* @param tags - RUM tags
|
|
70
|
+
* @returns Combined tags for the Profile Event.
|
|
71
|
+
*/
|
|
72
|
+
function buildProfileEventTags(tags: string[]): string[] {
|
|
73
|
+
// Tags already contains the common tags for all events. (service, env, version, etc.)
|
|
74
|
+
// Here we are adding some specific-to-profiling tags.
|
|
75
|
+
const profileEventTags = tags.concat(['language:javascript', 'runtime:chrome', 'family:chrome', 'host:browser'])
|
|
76
|
+
|
|
77
|
+
return profileEventTags
|
|
78
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import type { RumProfilerTrace, RumViewEntry } from '../types'
|
|
2
|
+
|
|
3
|
+
export interface ProfileEventAttributes {
|
|
4
|
+
application: { id: string }
|
|
5
|
+
session?: { id: string }
|
|
6
|
+
view?: { id: string[]; name: string[] }
|
|
7
|
+
long_task?: { id: string[] }
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Builds attributes for the Profile Event.
|
|
12
|
+
*
|
|
13
|
+
* @param profilerTrace - Profiler trace
|
|
14
|
+
* @param applicationId - application id.
|
|
15
|
+
* @param sessionId - session id.
|
|
16
|
+
* @returns Additional attributes.
|
|
17
|
+
*/
|
|
18
|
+
export function buildProfileEventAttributes(
|
|
19
|
+
profilerTrace: RumProfilerTrace,
|
|
20
|
+
applicationId: string,
|
|
21
|
+
sessionId: string | undefined
|
|
22
|
+
): ProfileEventAttributes {
|
|
23
|
+
const attributes: ProfileEventAttributes = {
|
|
24
|
+
application: {
|
|
25
|
+
id: applicationId,
|
|
26
|
+
},
|
|
27
|
+
}
|
|
28
|
+
if (sessionId) {
|
|
29
|
+
attributes.session = {
|
|
30
|
+
id: sessionId,
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// Extract view ids and names from the profiler trace and add them as attributes of the profile event.
|
|
35
|
+
// This will be used to filter the profiles by @view.id and/or @view.name.
|
|
36
|
+
const { ids, names } = extractViewIdsAndNames(profilerTrace.views)
|
|
37
|
+
|
|
38
|
+
if (ids.length) {
|
|
39
|
+
attributes.view = {
|
|
40
|
+
id: ids,
|
|
41
|
+
name: names,
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
const longTaskIds: string[] = profilerTrace.longTasks.map((longTask) => longTask.id).filter((id) => id !== undefined)
|
|
45
|
+
|
|
46
|
+
if (longTaskIds.length) {
|
|
47
|
+
attributes.long_task = { id: longTaskIds }
|
|
48
|
+
}
|
|
49
|
+
return attributes
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function extractViewIdsAndNames(views: RumViewEntry[]): { ids: string[]; names: string[] } {
|
|
53
|
+
const result: { ids: string[]; names: string[] } = { ids: [], names: [] }
|
|
54
|
+
for (const view of views) {
|
|
55
|
+
result.ids.push(view.viewId)
|
|
56
|
+
|
|
57
|
+
if (view.viewName) {
|
|
58
|
+
result.names.push(view.viewName)
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// Remove duplicates
|
|
63
|
+
result.names = Array.from(new Set(result.names))
|
|
64
|
+
|
|
65
|
+
return result
|
|
66
|
+
}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
// Define types for the new Profiler API
|
|
2
|
+
// https://wicg.github.io/js-self-profiling/
|
|
3
|
+
|
|
4
|
+
export interface ProfilerFrame {
|
|
5
|
+
/** A function instance name. */
|
|
6
|
+
readonly name: string
|
|
7
|
+
/** Index in the trace.resources array. */
|
|
8
|
+
readonly resourceId?: number
|
|
9
|
+
/** 1-based index of the line. */
|
|
10
|
+
readonly line?: number
|
|
11
|
+
/** 1-based index of the column. */
|
|
12
|
+
readonly column?: number
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export interface ProfilerStack {
|
|
16
|
+
/** Index in the trace.stacks array. */
|
|
17
|
+
readonly parentId?: number
|
|
18
|
+
/** Index in the trace.frames array. */
|
|
19
|
+
readonly frameId: number
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export interface ProfilerSample {
|
|
23
|
+
/** High resolution time relative to the profiling session's time origin. */
|
|
24
|
+
readonly timestamp: number
|
|
25
|
+
/** Index in the trace.stacks array. */
|
|
26
|
+
readonly stackId?: number
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export type ProfilerResource = string
|
|
30
|
+
|
|
31
|
+
export interface ProfilerTrace {
|
|
32
|
+
/** An array of profiler resources. */
|
|
33
|
+
readonly resources: ProfilerResource[]
|
|
34
|
+
/** An array of profiler frames. */
|
|
35
|
+
readonly frames: ProfilerFrame[]
|
|
36
|
+
/** An array of profiler stacks. */
|
|
37
|
+
readonly stacks: ProfilerStack[]
|
|
38
|
+
/** An array of profiler samples. */
|
|
39
|
+
readonly samples: ProfilerSample[]
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export interface ProfilerInitOptions {
|
|
43
|
+
/** Sample interval in ms. */
|
|
44
|
+
readonly sampleInterval: number
|
|
45
|
+
/** Max buffer size in number of samples. */
|
|
46
|
+
readonly maxBufferSize: number
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export interface Profiler extends EventTarget {
|
|
50
|
+
/** Sample interval in ms. */
|
|
51
|
+
readonly sampleInterval: number
|
|
52
|
+
/** True if profiler is stopped. */
|
|
53
|
+
readonly stopped: boolean
|
|
54
|
+
|
|
55
|
+
// eslint-disable-next-line @typescript-eslint/no-misused-new
|
|
56
|
+
new (options: ProfilerInitOptions): Profiler
|
|
57
|
+
stop(): Promise<ProfilerTrace>
|
|
58
|
+
|
|
59
|
+
addEventListener<K extends keyof ProfilerEventMap>(
|
|
60
|
+
type: K,
|
|
61
|
+
listener: (this: typeof globalThis, ev: ProfilerEventMap[K]) => any,
|
|
62
|
+
options?: boolean | AddEventListenerOptions
|
|
63
|
+
): void
|
|
64
|
+
addEventListener(
|
|
65
|
+
type: string,
|
|
66
|
+
listener: EventListenerOrEventListenerObject,
|
|
67
|
+
options?: boolean | AddEventListenerOptions
|
|
68
|
+
): void
|
|
69
|
+
removeEventListener<K extends keyof ProfilerEventMap>(
|
|
70
|
+
type: K,
|
|
71
|
+
listener: (this: typeof globalThis, ev: ProfilerEventMap[K]) => any,
|
|
72
|
+
options?: boolean | EventListenerOptions
|
|
73
|
+
): void
|
|
74
|
+
removeEventListener(
|
|
75
|
+
type: string,
|
|
76
|
+
listener: EventListenerOrEventListenerObject,
|
|
77
|
+
options?: boolean | EventListenerOptions
|
|
78
|
+
): void
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
interface ProfilerEventMap {
|
|
82
|
+
samplebufferfull: SampleBufferFullEvent
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export interface SampleBufferFullEvent extends Event {
|
|
86
|
+
readonly target: Profiler
|
|
87
|
+
}
|