@dreamhorizonorg/pulse-react-native 0.0.3 → 0.0.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/android/build.gradle +1 -1
- package/android/src/main/java/com/pulsereactnativeotel/Pulse.kt +4 -0
- package/android/src/main/java/com/pulsereactnativeotel/PulseReactNativeOtelModule.kt +5 -0
- package/ios/PulseReactNativeOtel.mm +124 -63
- package/lib/module/NativePulseReactNativeOtel.js.map +1 -1
- package/lib/module/config.js +46 -4
- package/lib/module/config.js.map +1 -1
- package/lib/module/errorBoundary.js +4 -1
- package/lib/module/errorBoundary.js.map +1 -1
- package/lib/module/errorHandler.js +5 -1
- package/lib/module/errorHandler.js.map +1 -1
- package/lib/module/events.js +2 -2
- package/lib/module/events.js.map +1 -1
- package/lib/module/index.js +2 -1
- package/lib/module/index.js.map +1 -1
- package/lib/module/navigation/index.js +11 -0
- package/lib/module/navigation/index.js.map +1 -1
- package/lib/module/navigation/screen-interactive.js +4 -0
- package/lib/module/navigation/screen-interactive.js.map +1 -1
- package/lib/module/network-interceptor/initialization.js +13 -1
- package/lib/module/network-interceptor/initialization.js.map +1 -1
- package/lib/module/network-interceptor/request-tracker-xhr.js +15 -2
- package/lib/module/network-interceptor/request-tracker-xhr.js.map +1 -1
- package/lib/module/trace.js +16 -10
- package/lib/module/trace.js.map +1 -1
- package/lib/module/user.js +4 -3
- package/lib/module/user.js.map +1 -1
- package/lib/typescript/plugin/src/types.d.ts +6 -0
- package/lib/typescript/plugin/src/types.d.ts.map +1 -1
- package/lib/typescript/plugin/src/utils.d.ts +2 -0
- package/lib/typescript/plugin/src/utils.d.ts.map +1 -1
- package/lib/typescript/plugin/src/withAndroidPulse.d.ts.map +1 -1
- package/lib/typescript/src/NativePulseReactNativeOtel.d.ts +2 -0
- package/lib/typescript/src/NativePulseReactNativeOtel.d.ts.map +1 -1
- package/lib/typescript/src/config.d.ts +5 -1
- package/lib/typescript/src/config.d.ts.map +1 -1
- package/lib/typescript/src/errorBoundary.d.ts.map +1 -1
- package/lib/typescript/src/errorHandler.d.ts +1 -0
- package/lib/typescript/src/errorHandler.d.ts.map +1 -1
- package/lib/typescript/src/events.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts +2 -1
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/navigation/index.d.ts +1 -0
- package/lib/typescript/src/navigation/index.d.ts.map +1 -1
- package/lib/typescript/src/navigation/screen-interactive.d.ts.map +1 -1
- package/lib/typescript/src/network-interceptor/initialization.d.ts +1 -0
- package/lib/typescript/src/network-interceptor/initialization.d.ts.map +1 -1
- package/lib/typescript/src/network-interceptor/request-tracker-xhr.d.ts +5 -1
- package/lib/typescript/src/network-interceptor/request-tracker-xhr.d.ts.map +1 -1
- package/lib/typescript/src/trace.d.ts.map +1 -1
- package/lib/typescript/src/user.d.ts.map +1 -1
- package/package.json +1 -1
- package/plugin/build/types.d.ts +6 -0
- package/plugin/build/utils.d.ts +2 -0
- package/plugin/build/utils.js +6 -2
- package/plugin/build/withAndroidPulse.js +3 -1
- package/src/NativePulseReactNativeOtel.ts +3 -0
- package/src/config.ts +53 -3
- package/src/errorBoundary.tsx +4 -1
- package/src/errorHandler.ts +6 -1
- package/src/events.ts +6 -2
- package/src/index.tsx +2 -1
- package/src/navigation/index.ts +13 -0
- package/src/navigation/screen-interactive.ts +4 -0
- package/src/network-interceptor/initialization.ts +14 -1
- package/src/network-interceptor/request-tracker-xhr.ts +16 -3
- package/src/trace.ts +17 -10
- package/src/user.ts +4 -3
package/src/config.ts
CHANGED
|
@@ -1,11 +1,15 @@
|
|
|
1
|
-
import { setupErrorHandler } from './errorHandler';
|
|
1
|
+
import { setupErrorHandler, uninstallErrorHandler } from './errorHandler';
|
|
2
2
|
import { isSupportedPlatform } from './initialization';
|
|
3
3
|
import {
|
|
4
4
|
createReactNavigationIntegration,
|
|
5
|
+
uninstallNavigationIntegration,
|
|
5
6
|
type ReactNavigationIntegration,
|
|
6
7
|
type NavigationIntegrationOptions,
|
|
7
8
|
} from './navigation';
|
|
8
|
-
import {
|
|
9
|
+
import {
|
|
10
|
+
initializeNetworkInterceptor,
|
|
11
|
+
uninstallNetworkInterceptor,
|
|
12
|
+
} from './network-interceptor/initialization';
|
|
9
13
|
import PulseReactNativeOtel from './NativePulseReactNativeOtel';
|
|
10
14
|
import type { PulseFeatureConfig } from './pulse.interface';
|
|
11
15
|
import { PULSE_FEATURE_NAMES } from './pulse.constants';
|
|
@@ -34,12 +38,27 @@ const defaultConfig: Required<PulseConfig> = {
|
|
|
34
38
|
|
|
35
39
|
let currentConfig: PulseConfig = { ...defaultConfig };
|
|
36
40
|
|
|
41
|
+
/** After shutdown, start() and initialize are no-ops; re-initialization is not supported. */
|
|
42
|
+
let isShutdown = false;
|
|
43
|
+
|
|
44
|
+
/** True only after start() has been called at least once. Integrations (e.g. navigation) are no-ops until then. */
|
|
45
|
+
let isStarted = false;
|
|
46
|
+
|
|
37
47
|
// Cache for features from remote SDK config
|
|
38
48
|
let cachedFeatures: PulseFeatureConfig;
|
|
39
49
|
|
|
50
|
+
export function getIsShutdown(): boolean {
|
|
51
|
+
return isShutdown;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/** True only after start() has been called at least once. Public APIs (trackEvent, reportException, startSpan, etc.) no-op until then. */
|
|
55
|
+
export function getIsStarted(): boolean {
|
|
56
|
+
return isStarted;
|
|
57
|
+
}
|
|
58
|
+
|
|
40
59
|
/**
|
|
41
60
|
* Gets all features from the remote SDK config.
|
|
42
|
-
* @returns Record of feature names to their enabled status, or null if config not available
|
|
61
|
+
* @returns Record of feature names to their enabled status, or null if config not available or start() not called
|
|
43
62
|
*/
|
|
44
63
|
export function getFeaturesFromRemoteConfig(): PulseFeatureConfig {
|
|
45
64
|
if (cachedFeatures !== undefined) {
|
|
@@ -93,7 +112,14 @@ function resolveNavigationState(
|
|
|
93
112
|
|
|
94
113
|
export function start(options?: PulseConfig): void {
|
|
95
114
|
if (!isSupportedPlatform()) return;
|
|
115
|
+
if (isShutdown) {
|
|
116
|
+
console.log(
|
|
117
|
+
'[Pulse] SDK has been shut down. Pulse.start() is a no-op; re-initialization is not supported.'
|
|
118
|
+
);
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
96
121
|
|
|
122
|
+
isStarted = true;
|
|
97
123
|
const features = getFeaturesFromRemoteConfig();
|
|
98
124
|
const config: PulseConfig = {
|
|
99
125
|
autoDetectExceptions: resolveFeatureState(
|
|
@@ -119,6 +145,18 @@ export function start(options?: PulseConfig): void {
|
|
|
119
145
|
configure(config);
|
|
120
146
|
}
|
|
121
147
|
|
|
148
|
+
export function shutdown(): void {
|
|
149
|
+
if (isShutdown) {
|
|
150
|
+
console.warn('[Pulse] SDK already shut down.');
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
uninstallErrorHandler();
|
|
154
|
+
uninstallNetworkInterceptor();
|
|
155
|
+
uninstallNavigationIntegration();
|
|
156
|
+
PulseReactNativeOtel.shutdown();
|
|
157
|
+
isShutdown = true;
|
|
158
|
+
}
|
|
159
|
+
|
|
122
160
|
export function createNavigationIntegrationWithConfig(
|
|
123
161
|
options?: NavigationIntegrationOptions
|
|
124
162
|
): ReactNavigationIntegration {
|
|
@@ -128,6 +166,18 @@ export function createNavigationIntegrationWithConfig(
|
|
|
128
166
|
markContentReady: () => {},
|
|
129
167
|
};
|
|
130
168
|
}
|
|
169
|
+
if (!isStarted) {
|
|
170
|
+
return {
|
|
171
|
+
registerNavigationContainer: (_: unknown) => () => {},
|
|
172
|
+
markContentReady: () => {},
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
if (isShutdown) {
|
|
176
|
+
return {
|
|
177
|
+
registerNavigationContainer: (_: unknown) => () => {},
|
|
178
|
+
markContentReady: () => {},
|
|
179
|
+
};
|
|
180
|
+
}
|
|
131
181
|
if (!currentConfig.autoDetectNavigation) {
|
|
132
182
|
console.warn(
|
|
133
183
|
'[Pulse Navigation] auto-detection disabled via Pulse.start; createNavigationIntegration() returning no-op.'
|
package/src/errorBoundary.tsx
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import { Pulse } from './index';
|
|
3
|
+
import { getIsShutdown } from './config';
|
|
3
4
|
|
|
4
5
|
export const UNKNOWN_COMPONENT = 'unknown';
|
|
5
6
|
const COMPONENT_STACK_UNAVAILABLE = '<component stack unavailable>';
|
|
@@ -46,7 +47,9 @@ export class ErrorBoundary extends React.Component<
|
|
|
46
47
|
|
|
47
48
|
const errorToReport =
|
|
48
49
|
error instanceof Error ? error : new Error(String(error));
|
|
49
|
-
|
|
50
|
+
if (!getIsShutdown()) {
|
|
51
|
+
Pulse.reportException(errorToReport, !handled);
|
|
52
|
+
}
|
|
50
53
|
|
|
51
54
|
if (onError) {
|
|
52
55
|
onError(error, componentStack);
|
package/src/errorHandler.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import PulseReactNativeOtel from './NativePulseReactNativeOtel';
|
|
2
|
+
import { getIsShutdown, getIsStarted } from './config';
|
|
2
3
|
import { mergeWithGlobalAttributes } from './globalAttributes';
|
|
3
4
|
import { isSupportedPlatform } from './initialization';
|
|
4
5
|
import { extractErrorDetails } from './utility';
|
|
@@ -68,7 +69,7 @@ export function reportException(
|
|
|
68
69
|
isFatal: boolean = false,
|
|
69
70
|
attributes?: PulseAttributes
|
|
70
71
|
): void {
|
|
71
|
-
if (!isSupportedPlatform()) {
|
|
72
|
+
if (!isSupportedPlatform() || !getIsStarted() || getIsShutdown()) {
|
|
72
73
|
return;
|
|
73
74
|
}
|
|
74
75
|
|
|
@@ -160,6 +161,10 @@ function disableErrorHandler(): void {
|
|
|
160
161
|
handlingFatal = false;
|
|
161
162
|
}
|
|
162
163
|
|
|
164
|
+
export function uninstallErrorHandler(): void {
|
|
165
|
+
disableErrorHandler();
|
|
166
|
+
}
|
|
167
|
+
|
|
163
168
|
export function setupErrorHandler(enableErrorHandler: boolean): void {
|
|
164
169
|
if (enableErrorHandler) {
|
|
165
170
|
initializeErrorHandler();
|
package/src/events.ts
CHANGED
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
import PulseReactNativeOtel from './NativePulseReactNativeOtel';
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
getFeaturesFromRemoteConfig,
|
|
4
|
+
getIsShutdown,
|
|
5
|
+
getIsStarted,
|
|
6
|
+
} from './config';
|
|
3
7
|
import { mergeWithGlobalAttributes } from './globalAttributes';
|
|
4
8
|
import { isSupportedPlatform } from './initialization';
|
|
5
9
|
import type { PulseAttributes } from './pulse.interface';
|
|
6
10
|
|
|
7
11
|
export function trackEvent(event: string, attributes?: PulseAttributes): void {
|
|
8
|
-
if (!isSupportedPlatform()) {
|
|
12
|
+
if (!isSupportedPlatform() || !getIsStarted() || getIsShutdown()) {
|
|
9
13
|
return;
|
|
10
14
|
}
|
|
11
15
|
const features = getFeaturesFromRemoteConfig();
|
package/src/index.tsx
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { startSpan, trackSpan } from './trace';
|
|
2
2
|
import { reportException } from './errorHandler';
|
|
3
3
|
import { trackEvent } from './events';
|
|
4
|
-
import { start } from './config';
|
|
4
|
+
import { start, shutdown } from './config';
|
|
5
5
|
import { isInitialized } from './initialization';
|
|
6
6
|
import { setGlobalAttribute } from './globalAttributes';
|
|
7
7
|
import { setUserId, setUserProperty, setUserProperties } from './user';
|
|
@@ -22,6 +22,7 @@ export type { ErrorBoundaryProps, FallbackRender } from './errorBoundary';
|
|
|
22
22
|
export { SpanStatusCode } from './trace';
|
|
23
23
|
export const Pulse = {
|
|
24
24
|
start,
|
|
25
|
+
shutdown,
|
|
25
26
|
isInitialized,
|
|
26
27
|
useNavigationTracking,
|
|
27
28
|
markContentReady,
|
package/src/navigation/index.ts
CHANGED
|
@@ -37,6 +37,15 @@ import {
|
|
|
37
37
|
export type { NavigationRoute, NavigationIntegrationOptions };
|
|
38
38
|
export { DEFAULT_NAVIGATION_OPTIONS } from './navigation.interface';
|
|
39
39
|
|
|
40
|
+
let currentNavigationUnregister: (() => void) | null = null;
|
|
41
|
+
|
|
42
|
+
export function uninstallNavigationIntegration(): void {
|
|
43
|
+
if (currentNavigationUnregister) {
|
|
44
|
+
currentNavigationUnregister();
|
|
45
|
+
currentNavigationUnregister = null;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
40
49
|
export interface ReactNavigationIntegration {
|
|
41
50
|
registerNavigationContainer: (
|
|
42
51
|
maybeNavigationContainer: unknown
|
|
@@ -270,6 +279,9 @@ export function createReactNavigationIntegration(
|
|
|
270
279
|
}
|
|
271
280
|
navigationContainer = undefined;
|
|
272
281
|
isInitialized = false;
|
|
282
|
+
if (currentNavigationUnregister === unmountCleanup) {
|
|
283
|
+
currentNavigationUnregister = null;
|
|
284
|
+
}
|
|
273
285
|
|
|
274
286
|
clearGlobalMarkContentReady(
|
|
275
287
|
updatedInteractiveTracker.markContentReady
|
|
@@ -304,6 +316,7 @@ export function createReactNavigationIntegration(
|
|
|
304
316
|
);
|
|
305
317
|
isInitialized = true;
|
|
306
318
|
|
|
319
|
+
currentNavigationUnregister = unmountCleanup;
|
|
307
320
|
return unmountCleanup;
|
|
308
321
|
} catch (error) {
|
|
309
322
|
console.error(
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Pulse, type Span } from '../index';
|
|
2
|
+
import { getIsStarted } from '../config';
|
|
2
3
|
import { Platform } from 'react-native';
|
|
3
4
|
import { SPAN_NAMES, ATTRIBUTE_KEYS, PULSE_TYPES } from '../pulse.constants';
|
|
4
5
|
import { discardSpan } from '../trace';
|
|
@@ -131,6 +132,9 @@ export function createScreenInteractiveTracker(
|
|
|
131
132
|
}
|
|
132
133
|
|
|
133
134
|
export function markContentReady(): void {
|
|
135
|
+
if (!getIsStarted()) {
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
134
138
|
if (globalMarkContentReady) {
|
|
135
139
|
globalMarkContentReady();
|
|
136
140
|
} else {
|
|
@@ -4,6 +4,7 @@ import type { NetworkHeaderConfig } from '../config';
|
|
|
4
4
|
export { normalizeHeaderName, shouldCaptureHeader } from './header-helper';
|
|
5
5
|
|
|
6
6
|
let isInitialized = false;
|
|
7
|
+
let uninstallXmlHttpRequestTracker: (() => void) | null = null;
|
|
7
8
|
let headerConfig: NetworkHeaderConfig = {
|
|
8
9
|
requestHeaders: [],
|
|
9
10
|
responseHeaders: [],
|
|
@@ -35,7 +36,8 @@ export function initializeNetworkInterceptor(
|
|
|
35
36
|
// In react-native, we are intercepting XMLHttpRequest only, since axios and fetch both use it internally.
|
|
36
37
|
// See: https://github.com/facebook/react-native/blob/main/packages/react-native/Libraries/Network/fetch.js
|
|
37
38
|
if (typeof XMLHttpRequest !== 'undefined') {
|
|
38
|
-
createXmlHttpRequestTracker(XMLHttpRequest);
|
|
39
|
+
const result = createXmlHttpRequestTracker(XMLHttpRequest);
|
|
40
|
+
uninstallXmlHttpRequestTracker = result.uninstall;
|
|
39
41
|
} else {
|
|
40
42
|
console.warn('[Pulse] XMLHttpRequest is not available');
|
|
41
43
|
}
|
|
@@ -47,3 +49,14 @@ export function initializeNetworkInterceptor(
|
|
|
47
49
|
}
|
|
48
50
|
|
|
49
51
|
export const isNetworkInterceptorInitialized = (): boolean => isInitialized;
|
|
52
|
+
|
|
53
|
+
export function uninstallNetworkInterceptor(): void {
|
|
54
|
+
if (!isInitialized) {
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
if (uninstallXmlHttpRequestTracker) {
|
|
58
|
+
uninstallXmlHttpRequestTracker();
|
|
59
|
+
uninstallXmlHttpRequestTracker = null;
|
|
60
|
+
}
|
|
61
|
+
isInitialized = false;
|
|
62
|
+
}
|
|
@@ -18,12 +18,17 @@ type ReadyStateChangeHandler = (this: XMLHttpRequest, ev: Event) => any;
|
|
|
18
18
|
|
|
19
19
|
let isXHRIntercepted = false;
|
|
20
20
|
|
|
21
|
+
export interface XmlHttpRequestTrackerResult {
|
|
22
|
+
requestTracker: RequestTracker;
|
|
23
|
+
uninstall: () => void;
|
|
24
|
+
}
|
|
25
|
+
|
|
21
26
|
function createXmlHttpRequestTracker(
|
|
22
27
|
xhr: typeof XMLHttpRequest
|
|
23
|
-
):
|
|
28
|
+
): XmlHttpRequestTrackerResult {
|
|
24
29
|
if (isXHRIntercepted) {
|
|
25
30
|
console.warn('[Pulse] XMLHttpRequest already intercepted');
|
|
26
|
-
return new RequestTracker();
|
|
31
|
+
return { requestTracker: new RequestTracker(), uninstall: () => {} };
|
|
27
32
|
}
|
|
28
33
|
|
|
29
34
|
const requestTracker = new RequestTracker();
|
|
@@ -192,7 +197,15 @@ function createXmlHttpRequestTracker(
|
|
|
192
197
|
originalSend.call(this, body);
|
|
193
198
|
};
|
|
194
199
|
|
|
195
|
-
|
|
200
|
+
const uninstall = (): void => {
|
|
201
|
+
if (!isXHRIntercepted) return;
|
|
202
|
+
xhr.prototype.open = originalOpen;
|
|
203
|
+
xhr.prototype.setRequestHeader = originalSetRequestHeader;
|
|
204
|
+
xhr.prototype.send = originalSend;
|
|
205
|
+
isXHRIntercepted = false;
|
|
206
|
+
};
|
|
207
|
+
|
|
208
|
+
return { requestTracker, uninstall };
|
|
196
209
|
}
|
|
197
210
|
|
|
198
211
|
export default createXmlHttpRequestTracker;
|
package/src/trace.ts
CHANGED
|
@@ -1,9 +1,18 @@
|
|
|
1
1
|
import PulseReactNativeOtel from './NativePulseReactNativeOtel';
|
|
2
|
+
import { getIsShutdown, getIsStarted } from './config';
|
|
2
3
|
import { isSupportedPlatform } from './initialization';
|
|
3
4
|
import { mergeWithGlobalAttributes } from './globalAttributes';
|
|
4
5
|
import { extractErrorDetails } from './utility';
|
|
5
6
|
import type { PulseAttributes } from './pulse.interface';
|
|
6
7
|
|
|
8
|
+
const noopSpan: Span = {
|
|
9
|
+
end: (_statusCode?: SpanStatusCode) => {},
|
|
10
|
+
addEvent: (_eventName: string, _eventAttributes?: PulseAttributes) => {},
|
|
11
|
+
setAttributes: (_attributes?: PulseAttributes) => {},
|
|
12
|
+
recordException: (_error: Error, _attributes?: PulseAttributes) => {},
|
|
13
|
+
spanId: undefined,
|
|
14
|
+
};
|
|
15
|
+
|
|
7
16
|
/**
|
|
8
17
|
* Options for starting a span.
|
|
9
18
|
* @param attributes - Attributes to set on the span.
|
|
@@ -30,14 +39,8 @@ export type Span = {
|
|
|
30
39
|
};
|
|
31
40
|
|
|
32
41
|
export function startSpan(name: string, options?: SpanOptions): Span {
|
|
33
|
-
if (!isSupportedPlatform()) {
|
|
34
|
-
return
|
|
35
|
-
end: (_statusCode?: SpanStatusCode) => {},
|
|
36
|
-
addEvent: (_eventName: string, _eventAttributes?: PulseAttributes) => {},
|
|
37
|
-
setAttributes: (_attributes?: PulseAttributes) => {},
|
|
38
|
-
recordException: (_error: Error, _attributes?: PulseAttributes) => {},
|
|
39
|
-
spanId: undefined,
|
|
40
|
-
};
|
|
42
|
+
if (!isSupportedPlatform() || !getIsStarted() || getIsShutdown()) {
|
|
43
|
+
return noopSpan;
|
|
41
44
|
}
|
|
42
45
|
|
|
43
46
|
const mergedAttributes = mergeWithGlobalAttributes(options?.attributes || {});
|
|
@@ -69,7 +72,7 @@ export function trackSpan<T>(
|
|
|
69
72
|
options: SpanOptions,
|
|
70
73
|
fn: () => T | Promise<T>
|
|
71
74
|
): T | Promise<T> {
|
|
72
|
-
if (!isSupportedPlatform()) {
|
|
75
|
+
if (!isSupportedPlatform() || !getIsStarted() || getIsShutdown()) {
|
|
73
76
|
return fn();
|
|
74
77
|
}
|
|
75
78
|
|
|
@@ -94,11 +97,12 @@ export function trackSpan<T>(
|
|
|
94
97
|
}
|
|
95
98
|
|
|
96
99
|
function endSpan(spanId: string, statusCode?: SpanStatusCode): void {
|
|
100
|
+
if (getIsShutdown()) return;
|
|
97
101
|
PulseReactNativeOtel.endSpan(spanId, statusCode);
|
|
98
102
|
}
|
|
99
103
|
|
|
100
104
|
export function discardSpan(spanId: string): void {
|
|
101
|
-
if (!isSupportedPlatform()) {
|
|
105
|
+
if (!isSupportedPlatform() || !getIsStarted() || getIsShutdown()) {
|
|
102
106
|
return;
|
|
103
107
|
}
|
|
104
108
|
PulseReactNativeOtel.discardSpan(spanId);
|
|
@@ -109,14 +113,17 @@ function addSpanEvent(
|
|
|
109
113
|
name: string,
|
|
110
114
|
attributes?: PulseAttributes
|
|
111
115
|
): void {
|
|
116
|
+
if (getIsShutdown()) return;
|
|
112
117
|
PulseReactNativeOtel.addSpanEvent(spanId, name, attributes || undefined);
|
|
113
118
|
}
|
|
114
119
|
|
|
115
120
|
function setSpanAttributes(spanId: string, attributes?: PulseAttributes): void {
|
|
121
|
+
if (getIsShutdown()) return;
|
|
116
122
|
PulseReactNativeOtel.setSpanAttributes(spanId, attributes || undefined);
|
|
117
123
|
}
|
|
118
124
|
|
|
119
125
|
function recordSpanException(error: Error, attributes?: PulseAttributes): void {
|
|
126
|
+
if (getIsShutdown()) return;
|
|
120
127
|
const { message, stackTrace, errorType } = extractErrorDetails(error);
|
|
121
128
|
const observedTimeMs = Date.now();
|
|
122
129
|
const mergedAttributes = mergeWithGlobalAttributes(attributes || {});
|
package/src/user.ts
CHANGED
|
@@ -1,23 +1,24 @@
|
|
|
1
1
|
import PulseReactNativeOtel from './NativePulseReactNativeOtel';
|
|
2
|
+
import { getIsShutdown } from './config';
|
|
2
3
|
import { isSupportedPlatform } from './initialization';
|
|
3
4
|
import type { PulseAttributes } from './pulse.interface';
|
|
4
5
|
|
|
5
6
|
export function setUserId(id: string | null): void {
|
|
6
|
-
if (!isSupportedPlatform()) {
|
|
7
|
+
if (!isSupportedPlatform() || getIsShutdown()) {
|
|
7
8
|
return;
|
|
8
9
|
}
|
|
9
10
|
PulseReactNativeOtel.setUserId(id);
|
|
10
11
|
}
|
|
11
12
|
|
|
12
13
|
export function setUserProperty(name: string, value: string | null): void {
|
|
13
|
-
if (!isSupportedPlatform()) {
|
|
14
|
+
if (!isSupportedPlatform() || getIsShutdown()) {
|
|
14
15
|
return;
|
|
15
16
|
}
|
|
16
17
|
PulseReactNativeOtel.setUserProperty(name, value);
|
|
17
18
|
}
|
|
18
19
|
|
|
19
20
|
export function setUserProperties(properties: PulseAttributes): void {
|
|
20
|
-
if (!isSupportedPlatform()) {
|
|
21
|
+
if (!isSupportedPlatform() || getIsShutdown()) {
|
|
21
22
|
return;
|
|
22
23
|
}
|
|
23
24
|
PulseReactNativeOtel.setUserProperties(properties);
|