@multiplayer-app/session-recorder-react-native 0.0.1-beta.1 → 0.0.1-beta.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (167) hide show
  1. package/SessionRecorderNative.podspec +29 -0
  2. package/android/build.gradle +32 -0
  3. package/app.plugin.js +42 -0
  4. package/copy-react-native-dist.sh +4 -10
  5. package/dist/components/MaskableComponent.d.ts +22 -0
  6. package/dist/components/MaskableComponent.js +1 -0
  7. package/dist/components/MaskableComponent.js.map +1 -0
  8. package/dist/components/MaskableTextInput.d.ts +14 -0
  9. package/dist/components/MaskableTextInput.js +1 -0
  10. package/dist/components/MaskableTextInput.js.map +1 -0
  11. package/dist/components/SessionRecorderWidget/FinalPopover.d.ts +11 -0
  12. package/dist/components/SessionRecorderWidget/FinalPopover.js +1 -0
  13. package/dist/components/SessionRecorderWidget/FinalPopover.js.map +1 -0
  14. package/dist/components/SessionRecorderWidget/FloatingButton.d.ts +8 -0
  15. package/dist/components/SessionRecorderWidget/FloatingButton.js +1 -0
  16. package/dist/components/SessionRecorderWidget/FloatingButton.js.map +1 -0
  17. package/dist/components/SessionRecorderWidget/InitialPopover.d.ts +13 -0
  18. package/dist/components/SessionRecorderWidget/InitialPopover.js +1 -0
  19. package/dist/components/SessionRecorderWidget/InitialPopover.js.map +1 -0
  20. package/dist/components/SessionRecorderWidget/ModalContainer.d.ts +8 -0
  21. package/dist/components/SessionRecorderWidget/ModalContainer.js +1 -0
  22. package/dist/components/SessionRecorderWidget/ModalContainer.js.map +1 -0
  23. package/dist/components/SessionRecorderWidget/ModalHeader.d.ts +6 -0
  24. package/dist/components/SessionRecorderWidget/ModalHeader.js +1 -0
  25. package/dist/components/SessionRecorderWidget/ModalHeader.js.map +1 -0
  26. package/dist/components/SessionRecorderWidget/SessionRecorderWidget.d.ts +5 -0
  27. package/dist/components/SessionRecorderWidget/SessionRecorderWidget.js +1 -0
  28. package/dist/components/SessionRecorderWidget/SessionRecorderWidget.js.map +1 -0
  29. package/dist/components/SessionRecorderWidget/icons.d.ts +11 -0
  30. package/dist/components/SessionRecorderWidget/icons.js +1 -0
  31. package/dist/components/SessionRecorderWidget/icons.js.map +1 -0
  32. package/dist/components/SessionRecorderWidget/index.d.ts +2 -0
  33. package/dist/components/SessionRecorderWidget/index.js +1 -0
  34. package/dist/components/SessionRecorderWidget/index.js.map +1 -0
  35. package/dist/components/SessionRecorderWidget/styles.d.ts +145 -0
  36. package/dist/components/SessionRecorderWidget/styles.js +1 -0
  37. package/dist/components/SessionRecorderWidget/styles.js.map +1 -0
  38. package/dist/components/index.d.ts +2 -0
  39. package/dist/components/index.js +1 -1
  40. package/dist/components/index.js.map +1 -1
  41. package/dist/config/defaults.js +1 -1
  42. package/dist/config/defaults.js.map +1 -1
  43. package/dist/config/masking.js +1 -1
  44. package/dist/config/masking.js.map +1 -1
  45. package/dist/context/SessionRecorderContext.d.ts +5 -3
  46. package/dist/context/SessionRecorderContext.js +1 -1
  47. package/dist/context/SessionRecorderContext.js.map +1 -1
  48. package/dist/index.d.ts +0 -1
  49. package/dist/index.js +1 -1
  50. package/dist/index.js.map +1 -1
  51. package/dist/native/ScreenMasking.d.ts +21 -0
  52. package/dist/native/ScreenMasking.js +1 -0
  53. package/dist/native/ScreenMasking.js.map +1 -0
  54. package/dist/native/SessionRecorderNative.d.ts +21 -0
  55. package/dist/native/SessionRecorderNative.js +1 -0
  56. package/dist/native/SessionRecorderNative.js.map +1 -0
  57. package/dist/patch/xhr.js +1 -1
  58. package/dist/patch/xhr.js.map +1 -1
  59. package/dist/recorder/screenRecorder.d.ts +1 -0
  60. package/dist/recorder/screenRecorder.js +1 -1
  61. package/dist/recorder/screenRecorder.js.map +1 -1
  62. package/dist/recorder/screenshotManager.d.ts +10 -0
  63. package/dist/recorder/screenshotManager.js +1 -0
  64. package/dist/recorder/screenshotManager.js.map +1 -0
  65. package/dist/services/screenMaskingService.d.ts +39 -0
  66. package/dist/services/screenMaskingService.js +1 -0
  67. package/dist/services/screenMaskingService.js.map +1 -0
  68. package/dist/services/storage.service.d.ts +18 -2
  69. package/dist/services/storage.service.js +1 -1
  70. package/dist/services/storage.service.js.map +1 -1
  71. package/dist/session-recorder.d.ts +2 -1
  72. package/dist/session-recorder.js +1 -1
  73. package/dist/session-recorder.js.map +1 -1
  74. package/dist/types/session-recorder.d.ts +6 -0
  75. package/dist/types/session-recorder.js.map +1 -1
  76. package/dist/utils/componentRegistry.d.ts +64 -0
  77. package/dist/utils/componentRegistry.js +1 -0
  78. package/dist/utils/componentRegistry.js.map +1 -0
  79. package/dist/utils/nativeModuleTest.d.ts +8 -0
  80. package/dist/utils/nativeModuleTest.js +1 -0
  81. package/dist/utils/nativeModuleTest.js.map +1 -0
  82. package/dist/utils/platform.d.ts +3 -0
  83. package/dist/utils/reactNativeHierarchyExtractor.d.ts +38 -0
  84. package/dist/utils/reactNativeHierarchyExtractor.js +1 -0
  85. package/dist/utils/reactNativeHierarchyExtractor.js.map +1 -0
  86. package/dist/utils/screenshotMasker.d.ts +96 -0
  87. package/dist/utils/screenshotMasker.js +1 -0
  88. package/dist/utils/screenshotMasker.js.map +1 -0
  89. package/dist/utils/viewHierarchyTracker.d.ts +89 -0
  90. package/dist/utils/viewHierarchyTracker.js +1 -0
  91. package/dist/utils/viewHierarchyTracker.js.map +1 -0
  92. package/docs/NATIVE_MODULE_SETUP.md +177 -0
  93. package/ios/SessionRecorderNative.m +17 -0
  94. package/ios/SessionRecorderNative.podspec +26 -0
  95. package/ios/SessionRecorderNative.swift +205 -0
  96. package/package.json +22 -7
  97. package/plugin/package.json +20 -0
  98. package/plugin/src/index.js +42 -0
  99. package/react-native.config.js +15 -0
  100. package/RRWEB_INTEGRATION.md +0 -336
  101. package/VIEWSHOT_INTEGRATION_TEST.md +0 -123
  102. package/babel.config.js +0 -13
  103. package/dist/components/GestureCaptureWrapper.d.ts +0 -6
  104. package/dist/components/GestureCaptureWrapper.js +0 -1
  105. package/dist/components/GestureCaptureWrapper.js.map +0 -1
  106. package/dist/expo.d.ts +0 -7
  107. package/dist/expo.js +0 -1
  108. package/dist/expo.js.map +0 -1
  109. package/dist/otel/instrumentations/gestureInstrumentation.d.ts +0 -15
  110. package/dist/otel/instrumentations/gestureInstrumentation.js +0 -1
  111. package/dist/otel/instrumentations/gestureInstrumentation.js.map +0 -1
  112. package/dist/otel/instrumentations/reactNativeInstrumentation.d.ts +0 -8
  113. package/dist/otel/instrumentations/reactNativeInstrumentation.js +0 -1
  114. package/dist/otel/instrumentations/reactNativeInstrumentation.js.map +0 -1
  115. package/dist/otel/instrumentations/reactNavigationInstrumentation.d.ts +0 -13
  116. package/dist/otel/instrumentations/reactNavigationInstrumentation.js +0 -1
  117. package/dist/otel/instrumentations/reactNavigationInstrumentation.js.map +0 -1
  118. package/dist/recorder/gestureHandlerRecorder.d.ts +0 -19
  119. package/dist/recorder/gestureHandlerRecorder.js +0 -1
  120. package/dist/recorder/gestureHandlerRecorder.js.map +0 -1
  121. package/dist/types/rrweb.d.ts +0 -118
  122. package/dist/types/rrweb.js +0 -1
  123. package/dist/types/rrweb.js.map +0 -1
  124. package/docs/AUTO_METADATA_DETECTION.md +0 -108
  125. package/scripts/generate-app-metadata.js +0 -173
  126. package/src/components/GestureCaptureWrapper/GestureCaptureWrapper.tsx +0 -86
  127. package/src/components/GestureCaptureWrapper/index.ts +0 -1
  128. package/src/components/ScreenRecorderView/ScreenRecorderView.tsx +0 -72
  129. package/src/components/ScreenRecorderView/index.ts +0 -1
  130. package/src/components/index.ts +0 -1
  131. package/src/config/constants.ts +0 -60
  132. package/src/config/defaults.ts +0 -82
  133. package/src/config/index.ts +0 -6
  134. package/src/config/masking.ts +0 -27
  135. package/src/config/session-recorder.ts +0 -55
  136. package/src/config/validators.ts +0 -31
  137. package/src/context/SessionRecorderContext.tsx +0 -75
  138. package/src/expo.ts +0 -11
  139. package/src/index.ts +0 -17
  140. package/src/otel/helpers.ts +0 -275
  141. package/src/otel/index.ts +0 -138
  142. package/src/otel/instrumentations/index.ts +0 -115
  143. package/src/patch/index.ts +0 -1
  144. package/src/patch/xhr.ts +0 -142
  145. package/src/recorder/eventExporter.ts +0 -141
  146. package/src/recorder/gestureRecorder.ts +0 -498
  147. package/src/recorder/index.ts +0 -179
  148. package/src/recorder/navigationTracker.ts +0 -449
  149. package/src/recorder/screenRecorder.ts +0 -498
  150. package/src/services/api.service.ts +0 -203
  151. package/src/services/storage.service.ts +0 -158
  152. package/src/session-recorder.ts +0 -600
  153. package/src/types/expo.d.ts +0 -23
  154. package/src/types/index.ts +0 -28
  155. package/src/types/session-recorder.ts +0 -423
  156. package/src/types/session.ts +0 -65
  157. package/src/utils/app-metadata.ts +0 -31
  158. package/src/utils/index.ts +0 -8
  159. package/src/utils/logger.ts +0 -225
  160. package/src/utils/platform.ts +0 -384
  161. package/src/utils/request-utils.ts +0 -61
  162. package/src/utils/rrweb-events.ts +0 -309
  163. package/src/utils/session.ts +0 -18
  164. package/src/utils/time.ts +0 -17
  165. package/src/utils/type-utils.ts +0 -75
  166. package/src/version.ts +0 -1
  167. package/tsconfig.json +0 -24
package/src/otel/index.ts DELETED
@@ -1,138 +0,0 @@
1
- import { resourceFromAttributes } from '@opentelemetry/resources'
2
- import { W3CTraceContextPropagator } from '@opentelemetry/core'
3
- import { BatchSpanProcessor } from '@opentelemetry/sdk-trace-base'
4
- import * as SemanticAttributes from '@opentelemetry/semantic-conventions'
5
- import { registerInstrumentations } from '@opentelemetry/instrumentation'
6
- import {
7
- SessionType,
8
- ATTR_MULTIPLAYER_SESSION_ID,
9
- SessionRecorderIdGenerator,
10
- SessionRecorderTraceIdRatioBasedSampler,
11
- SessionRecorderBrowserTraceExporter,
12
- } from '@multiplayer-app/session-recorder-common'
13
- import { TracerReactNativeConfig } from '../types'
14
- import { getInstrumentations } from './instrumentations'
15
- import { getExporterEndpoint } from './helpers'
16
-
17
- import { getPlatformAttributes } from '../utils/platform'
18
- import { WebTracerProvider } from '@opentelemetry/sdk-trace-web'
19
-
20
-
21
-
22
-
23
- export class TracerReactNativeSDK {
24
- private tracerProvider?: WebTracerProvider
25
- private config?: TracerReactNativeConfig
26
-
27
- private sessionId = ''
28
- private idGenerator?: SessionRecorderIdGenerator
29
- private exporter?: any
30
- private isInitialized = false
31
-
32
- constructor() { }
33
-
34
- private _setSessionId(
35
- sessionId: string,
36
- sessionType: SessionType = SessionType.PLAIN,
37
- ) {
38
- this.sessionId = sessionId
39
- this.idGenerator?.setSessionId(sessionId, sessionType)
40
- }
41
-
42
- init(options: TracerReactNativeConfig): void {
43
- this.config = options
44
-
45
- const { application, version, environment } = this.config
46
-
47
- this.idGenerator = new SessionRecorderIdGenerator()
48
-
49
- this.exporter = new SessionRecorderBrowserTraceExporter({
50
- apiKey: options.apiKey,
51
- url: getExporterEndpoint(options.exporterEndpoint),
52
- usePostMessageFallback: options.usePostMessageFallback,
53
- })
54
-
55
- this.tracerProvider = new WebTracerProvider({
56
- resource: resourceFromAttributes({
57
- [SemanticAttributes.SEMRESATTRS_SERVICE_NAME]: application,
58
- [SemanticAttributes.SEMRESATTRS_SERVICE_VERSION]: version,
59
- [SemanticAttributes.SEMRESATTRS_DEPLOYMENT_ENVIRONMENT]: environment,
60
- ...getPlatformAttributes(),
61
- }),
62
- idGenerator: this.idGenerator,
63
- sampler: new SessionRecorderTraceIdRatioBasedSampler(this.config.sampleTraceRatio || 0.15),
64
- spanProcessors: [
65
- this._getSpanSessionIdProcessor(),
66
- new BatchSpanProcessor(this.exporter),
67
- ],
68
- })
69
-
70
- this.tracerProvider.register({
71
- propagator: new W3CTraceContextPropagator(),
72
- })
73
-
74
- // Register instrumentations
75
- registerInstrumentations({
76
- tracerProvider: this.tracerProvider,
77
- instrumentations: getInstrumentations(this.config),
78
- })
79
-
80
- this.isInitialized = true
81
- }
82
-
83
- private _getSpanSessionIdProcessor() {
84
- return {
85
- onStart: (span: any) => {
86
- if (this.sessionId) {
87
- span.setAttribute(ATTR_MULTIPLAYER_SESSION_ID, this.sessionId)
88
- }
89
- // Add React Native specific attributes
90
- span.setAttribute('platform', 'react-native')
91
- span.setAttribute('timestamp', Date.now())
92
- },
93
- onEnd: () => { },
94
- shutdown: () => Promise.resolve(),
95
- forceFlush: () => Promise.resolve(),
96
- }
97
- }
98
-
99
- start(sessionId: string, sessionType: SessionType): void {
100
- if (!this.tracerProvider) {
101
- throw new Error(
102
- 'Configuration not initialized. Call init() before start().',
103
- )
104
- }
105
-
106
- this._setSessionId(sessionId, sessionType)
107
- }
108
-
109
- stop(): void {
110
- if (!this.tracerProvider) {
111
- throw new Error(
112
- 'Configuration not initialized. Call init() before start().',
113
- )
114
- }
115
-
116
- this._setSessionId('')
117
- }
118
-
119
- setApiKey(apiKey: string): void {
120
- if (!this.exporter) {
121
- throw new Error(
122
- 'Configuration not initialized. Call init() before setApiKey().',
123
- )
124
- }
125
-
126
- this.exporter.setApiKey?.(apiKey)
127
- }
128
-
129
- setSessionId(sessionId: string, sessionType: SessionType): void {
130
- this._setSessionId(sessionId, sessionType)
131
- }
132
-
133
- // Shutdown (React Native specific)
134
- shutdown(): Promise<void> {
135
- this.isInitialized = false
136
- return Promise.resolve()
137
- }
138
- }
@@ -1,115 +0,0 @@
1
- import { FetchInstrumentation } from '@opentelemetry/instrumentation-fetch'
2
- import { XMLHttpRequestInstrumentation } from '@opentelemetry/instrumentation-xml-http-request'
3
-
4
- import { logger } from '../../utils'
5
- import { OTEL_IGNORE_URLS } from '../../config'
6
- import { TracerReactNativeConfig } from '../../types'
7
- import { extractResponseBody, headersToObject, processHttpPayload } from '../helpers'
8
-
9
- export function getInstrumentations(config: TracerReactNativeConfig) {
10
-
11
- const instrumentations = []
12
-
13
- // Fetch instrumentation
14
- try {
15
- instrumentations.push(
16
- new FetchInstrumentation({
17
- clearTimingResources: false,
18
- ignoreUrls: [
19
- ...OTEL_IGNORE_URLS,
20
- ...(config.ignoreUrls || []),
21
- ],
22
- propagateTraceHeaderCorsUrls: config.propagateTraceHeaderCorsUrls,
23
- applyCustomAttributesOnSpan: async (span, request, response) => {
24
- if (!config) return
25
-
26
- const { captureBody, captureHeaders } = config
27
-
28
- try {
29
- if (!captureBody && !captureHeaders) {
30
- return
31
- }
32
-
33
- const requestBody = request.body
34
- const requestHeaders = headersToObject(request.headers)
35
- const responseHeaders = headersToObject(response instanceof Response ? response.headers : undefined)
36
-
37
- let responseBody: string | null = null
38
- if (response instanceof Response && response.body) {
39
- responseBody = await extractResponseBody(response)
40
- }
41
-
42
- const payload = {
43
- requestBody,
44
- responseBody,
45
- requestHeaders,
46
- responseHeaders,
47
- }
48
- processHttpPayload(payload, config, span)
49
- } catch (error) {
50
- // eslint-disable-next-line
51
- logger.error('DEBUGGER_LIB', 'Failed to capture fetch payload', error)
52
- }
53
- },
54
- })
55
- )
56
- } catch (error) {
57
- logger.warn('DEBUGGER_LIB', 'Fetch instrumentation not available', error)
58
- }
59
-
60
- // XMLHttpRequest instrumentation
61
- try {
62
- instrumentations.push(
63
- new XMLHttpRequestInstrumentation({
64
- clearTimingResources: false,
65
- ignoreUrls: [
66
- ...OTEL_IGNORE_URLS,
67
- ...(config.ignoreUrls || []),
68
- ],
69
- propagateTraceHeaderCorsUrls: config.propagateTraceHeaderCorsUrls,
70
- applyCustomAttributesOnSpan: (span, xhr) => {
71
- if (!config) return
72
-
73
- const { captureBody, captureHeaders } = config
74
-
75
- try {
76
- if (!captureBody && !captureHeaders) {
77
- return
78
- }
79
-
80
- // @ts-ignore
81
- const requestBody = xhr.networkRequest.requestBody
82
- // @ts-ignore
83
- const responseBody = xhr.networkRequest.responseBody
84
- // @ts-ignore
85
- const requestHeaders = xhr.networkRequest.requestHeaders || {}
86
- // @ts-ignore
87
- const responseHeaders = xhr.networkRequest.responseHeaders || {}
88
-
89
- const payload = {
90
- requestBody,
91
- responseBody,
92
- requestHeaders,
93
- responseHeaders,
94
- }
95
- processHttpPayload(payload, config, span)
96
- } catch (error) {
97
- // eslint-disable-next-line
98
- logger.error('DEBUGGER_LIB', 'Failed to capture xml-http payload', error)
99
- }
100
- },
101
- })
102
- )
103
- } catch (error) {
104
- logger.warn('DEBUGGER_LIB', 'XMLHttpRequest instrumentation not available', error)
105
- }
106
-
107
- // Custom React Native instrumentations
108
- // try {
109
- // instrumentations.push(new ReactNativeInstrumentation())
110
- // } catch (error) {
111
- // console.warn('React Native instrumentation not available:', error)
112
- // }
113
-
114
- return instrumentations
115
- }
@@ -1 +0,0 @@
1
- import './xhr'
package/src/patch/xhr.ts DELETED
@@ -1,142 +0,0 @@
1
- import {
2
-
3
- isFormData,
4
- isNullish,
5
- isObject,
6
- isString,
7
- } from '../utils/type-utils'
8
- import { formDataToQuery } from '../utils/request-utils'
9
- import { DEFAULT_MAX_HTTP_CAPTURING_PAYLOAD_SIZE } from '../config'
10
-
11
- let recordRequestHeaders = true
12
- let recordResponseHeaders = true
13
- const shouldRecordBody = true
14
- let maxCapturingHttpPayloadSize = DEFAULT_MAX_HTTP_CAPTURING_PAYLOAD_SIZE
15
-
16
- export const setMaxCapturingHttpPayloadSize = (_maxCapturingHttpPayloadSize: number) => {
17
- maxCapturingHttpPayloadSize = _maxCapturingHttpPayloadSize
18
- }
19
-
20
- export const setShouldRecordHttpData = (shouldRecordBody: boolean, shouldRecordHeaders: boolean) => {
21
- recordRequestHeaders = shouldRecordHeaders
22
- recordResponseHeaders = shouldRecordHeaders
23
- // eslint-disable-next-line
24
- shouldRecordBody = shouldRecordBody
25
- }
26
-
27
- function _tryReadXHRBody({
28
- body,
29
- url,
30
- }: {
31
- body: any | null | undefined
32
- url: string | URL | RequestInfo
33
- }): string | null {
34
- if (isNullish(body)) {
35
- return null
36
- }
37
-
38
- if (isString(body)) {
39
- return body
40
- }
41
-
42
-
43
- if (isFormData(body)) {
44
- return formDataToQuery(body)
45
- }
46
-
47
- if (isObject(body)) {
48
- try {
49
- return JSON.stringify(body)
50
- } catch {
51
- return '[XHR] Failed to stringify response object'
52
- }
53
- }
54
-
55
- return `[XHR] Cannot read body of type ${Object.prototype.toString.call(body)}`
56
- }
57
-
58
- (function (xhr) {
59
- const originalOpen = XMLHttpRequest.prototype.open
60
-
61
- xhr.open = function (
62
- method: string,
63
- url: string | URL,
64
- async = true,
65
- username?: string | null,
66
- password?: string | null,
67
- ) {
68
- const xhr = this as XMLHttpRequest
69
- const networkRequest: {
70
- requestHeaders?: any,
71
- requestBody?: any,
72
- responseHeaders?: any,
73
- responseBody?: any,
74
- } = {}
75
-
76
-
77
- // @ts-ignore
78
- const requestHeaders: Record<string, string> = {}
79
- const originalSetRequestHeader = xhr.setRequestHeader.bind(xhr)
80
- xhr.setRequestHeader = (header: string, value: string) => {
81
- requestHeaders[header] = value
82
- return originalSetRequestHeader(header, value)
83
- }
84
- if (recordRequestHeaders) {
85
- networkRequest.requestHeaders = requestHeaders
86
- }
87
-
88
- const originalSend = xhr.send.bind(xhr)
89
- xhr.send = (body) => {
90
- if (shouldRecordBody) {
91
- const requestBody = _tryReadXHRBody({ body, url })
92
-
93
- if (
94
- requestBody?.length
95
- && requestBody.length <= maxCapturingHttpPayloadSize
96
- ) {
97
- networkRequest.requestBody = requestBody
98
- }
99
- }
100
- return originalSend(body)
101
- }
102
-
103
- xhr.addEventListener('readystatechange', () => {
104
- if (xhr.readyState !== xhr.DONE) {
105
- return
106
- }
107
-
108
-
109
- // @ts-ignore
110
- const responseHeaders: Record<string, string> = {}
111
- const rawHeaders = xhr.getAllResponseHeaders()
112
- const headers = rawHeaders.trim().split(/[\r\n]+/)
113
- headers.forEach((line) => {
114
- const parts = line.split(': ')
115
- const header = parts.shift()
116
- const value = parts.join(': ')
117
- if (header) {
118
- responseHeaders[header] = value
119
- }
120
- })
121
- if (recordResponseHeaders) {
122
- networkRequest.responseHeaders = responseHeaders
123
- }
124
- if (shouldRecordBody) {
125
- const responseBody = _tryReadXHRBody({ body: xhr.response, url })
126
-
127
- if (
128
- responseBody?.length
129
- && responseBody.length <= maxCapturingHttpPayloadSize
130
- ) {
131
- networkRequest.responseBody = responseBody
132
- }
133
- }
134
- })
135
-
136
-
137
- // @ts-ignore
138
- xhr.networkRequest = networkRequest
139
-
140
- originalOpen.call(xhr, method, url as string, async, username, password)
141
- }
142
- })(XMLHttpRequest.prototype)
@@ -1,141 +0,0 @@
1
- import io, { Socket } from 'socket.io-client'
2
-
3
- import { ISession } from '../types'
4
- import { logger } from '../utils'
5
-
6
- import {
7
- SESSION_ADD_EVENT,
8
- SESSION_AUTO_CREATED,
9
- SESSION_STOPPED_EVENT,
10
- SESSION_SUBSCRIBE_EVENT,
11
- SESSION_UNSUBSCRIBE_EVENT,
12
- } from '../config'
13
-
14
- const MAX_RECONNECTION_ATTEMPTS = 2
15
-
16
- export class EventExporter {
17
- private socket: Socket | null = null
18
- private queue: any[] = []
19
- private isConnecting: boolean = false
20
- private isConnected: boolean = false
21
- private attempts: number = 0
22
- private sessionId: string | null = null
23
-
24
- constructor(private options: { socketUrl: string, apiKey: string }) { }
25
-
26
- private init(): void {
27
- if (this.isConnecting || this.isConnected) return
28
- this.attempts++
29
- this.isConnecting = true
30
- this.socket = io(this.options.socketUrl, {
31
- path: '/v0/radar/ws',
32
- auth: {
33
- 'x-api-key': this.options.apiKey,
34
- },
35
- reconnectionAttempts: 2,
36
- transports: ['websocket'],
37
- })
38
-
39
- // this.socket.on('connect', () => {
40
- // this.isConnecting = false
41
- // this.isConnected = true
42
- // this.usePostMessage = false
43
- // this.flushQueue()
44
- // })
45
-
46
- this.socket.on('ready', () => {
47
- this.isConnecting = false
48
- this.isConnected = true
49
- logger.info('EventExporter', 'Connected to server')
50
- this.flushQueue()
51
- })
52
-
53
- this.socket.on('disconnect', (err: any) => {
54
- this.isConnecting = false
55
- this.isConnected = false
56
- logger.info('EventExporter', 'Disconnected from server')
57
- })
58
-
59
- this.socket.on('connect_error', (err: any) => {
60
- this.isConnecting = false
61
- this.isConnected = false
62
- this.checkReconnectionAttempts()
63
- logger.error('EventExporter', 'Error connecting to server', err)
64
- })
65
-
66
- this.socket.on(SESSION_STOPPED_EVENT, (data: any) => {
67
-
68
- this.unsubscribeFromSession()
69
- })
70
-
71
- this.socket.on(SESSION_AUTO_CREATED, (data: any) => {
72
-
73
- })
74
- }
75
-
76
- private checkReconnectionAttempts(): void {
77
- if (this.attempts >= MAX_RECONNECTION_ATTEMPTS) {
78
-
79
- this.flushQueue()
80
- }
81
- }
82
-
83
-
84
- private flushQueue(): void {
85
- while (this.queue.length > 0 && (this.socket?.connected)) {
86
- const event = this.queue.shift()
87
- if (!event) continue
88
-
89
- if (this.socket?.connected) {
90
- this.socket.emit(event.name, event.data)
91
- }
92
- }
93
- }
94
-
95
- private unsubscribeFromSession() {
96
- const payload = {
97
- debugSessionId: this.sessionId,
98
- }
99
- if (this.socket?.connected) {
100
- this.socket.emit(SESSION_UNSUBSCRIBE_EVENT, payload)
101
- }
102
- }
103
-
104
- public send(event: any): void {
105
- if (this.socket?.connected) {
106
- this.socket.emit(SESSION_ADD_EVENT, event)
107
- } else {
108
- this.queue.push({ data: event, name: SESSION_ADD_EVENT })
109
- this.init()
110
- }
111
- }
112
-
113
- public subscribeToSession(session: ISession): void {
114
- this.sessionId = session.shortId || session._id
115
- const payload = {
116
- projectId: session.project,
117
- workspaceId: session.workspace,
118
- debugSessionId: this.sessionId,
119
- sessionType: session.creationType,
120
- }
121
- if (this.socket?.connected) {
122
- this.socket.emit(SESSION_SUBSCRIBE_EVENT, payload)
123
- } else {
124
- this.queue.push({ data: payload, name: SESSION_SUBSCRIBE_EVENT })
125
- this.init()
126
- }
127
- }
128
-
129
- public close(): void {
130
- if (this.socket?.connected) {
131
- setTimeout(() => {
132
- this.unsubscribeFromSession()
133
- this.attempts = 0
134
- this.isConnected = false
135
- this.isConnecting = false
136
- this.socket?.disconnect()
137
- this.socket = null
138
- }, 500)
139
- }
140
- }
141
- }