@safaricom-mxl/web-sdk 0.0.14 → 0.0.15
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/dist/api-logs/api/LogAPI/LogAPI.cjs.map +1 -1
- package/dist/api-logs/api/LogAPI/LogAPI.js.map +1 -1
- package/dist/api-logs/logAPI.cjs.map +1 -1
- package/dist/api-logs/logAPI.js.map +1 -1
- package/dist/api-logs/manager/NoOpLogManager/NoOpLogManager.cjs.map +1 -1
- package/dist/api-logs/manager/NoOpLogManager/NoOpLogManager.js.map +1 -1
- package/dist/api-logs/manager/ProxyLogManager/ProxyLogManager.cjs.map +1 -1
- package/dist/api-logs/manager/ProxyLogManager/ProxyLogManager.js.map +1 -1
- package/dist/api-page/api/PageAPI/PageAPI.cjs.map +1 -1
- package/dist/api-page/api/PageAPI/PageAPI.js.map +1 -1
- package/dist/api-page/manager/NoOpPageManager/NoOpPageManager.cjs.map +1 -1
- package/dist/api-page/manager/NoOpPageManager/NoOpPageManager.js.map +1 -1
- package/dist/api-page/manager/ProxyPageManager/ProxyPageManager.cjs.map +1 -1
- package/dist/api-page/manager/ProxyPageManager/ProxyPageManager.js.map +1 -1
- package/dist/api-page/pageAPI.cjs.map +1 -1
- package/dist/api-page/pageAPI.js.map +1 -1
- package/dist/api-sessions/api/SessionAPI/SessionAPI.cjs.map +1 -1
- package/dist/api-sessions/api/SessionAPI/SessionAPI.d.cts.map +1 -1
- package/dist/api-sessions/api/SessionAPI/SessionAPI.d.ts.map +1 -1
- package/dist/api-sessions/api/SessionAPI/SessionAPI.js.map +1 -1
- package/dist/api-sessions/manager/NoOpSpanSessionManager/NoOpSpanSessionManager.cjs.map +1 -1
- package/dist/api-sessions/manager/NoOpSpanSessionManager/NoOpSpanSessionManager.js.map +1 -1
- package/dist/api-sessions/manager/ProxySpanSessionManager/ProxySpanSessionManager.cjs.map +1 -1
- package/dist/api-sessions/manager/ProxySpanSessionManager/ProxySpanSessionManager.js.map +1 -1
- package/dist/api-sessions/sessionAPI.cjs.map +1 -1
- package/dist/api-sessions/sessionAPI.js.map +1 -1
- package/dist/api-traces/api/TraceAPI/TraceAPI.cjs.map +1 -1
- package/dist/api-traces/api/TraceAPI/TraceAPI.js.map +1 -1
- package/dist/api-traces/manager/NoOpTraceManager/NoOpTraceManager.cjs.map +1 -1
- package/dist/api-traces/manager/NoOpTraceManager/NoOpTraceManager.js.map +1 -1
- package/dist/api-traces/manager/NoOpTraceManager/NonRecordingExtendedSpan.cjs.map +1 -1
- package/dist/api-traces/manager/NoOpTraceManager/NonRecordingExtendedSpan.d.cts.map +1 -1
- package/dist/api-traces/manager/NoOpTraceManager/NonRecordingExtendedSpan.d.ts.map +1 -1
- package/dist/api-traces/manager/NoOpTraceManager/NonRecordingExtendedSpan.js.map +1 -1
- package/dist/api-traces/manager/ProxyTraceManager/ProxyTraceManager.cjs.map +1 -1
- package/dist/api-traces/manager/ProxyTraceManager/ProxyTraceManager.js.map +1 -1
- package/dist/api-traces/traceAPI.cjs.map +1 -1
- package/dist/api-traces/traceAPI.js.map +1 -1
- package/dist/api-users/api/UserAPI/UserAPI.cjs.map +1 -1
- package/dist/api-users/api/UserAPI/UserAPI.js.map +1 -1
- package/dist/api-users/manager/NoOpUserManager/NoOpUserManager.cjs.map +1 -1
- package/dist/api-users/manager/NoOpUserManager/NoOpUserManager.js.map +1 -1
- package/dist/api-users/manager/ProxyUserManager/ProxyUserManager.cjs.map +1 -1
- package/dist/api-users/manager/ProxyUserManager/ProxyUserManager.js.map +1 -1
- package/dist/api-users/userAPI.cjs.map +1 -1
- package/dist/api-users/userAPI.js.map +1 -1
- package/dist/common/attributes.cjs.map +1 -1
- package/dist/common/attributes.js.map +1 -1
- package/dist/exporters/MXLLogExporter/MXLLogExporter.cjs.map +1 -1
- package/dist/exporters/MXLLogExporter/MXLLogExporter.js.map +1 -1
- package/dist/exporters/MXLLogExporter/OTLPFetchLogExporter.cjs.map +1 -1
- package/dist/exporters/MXLLogExporter/OTLPFetchLogExporter.js.map +1 -1
- package/dist/exporters/MXLLogExporter/utils.cjs.map +1 -1
- package/dist/exporters/MXLLogExporter/utils.js.map +1 -1
- package/dist/exporters/MXLTraceExporter/MXLTraceExporter.cjs.map +1 -1
- package/dist/exporters/MXLTraceExporter/MXLTraceExporter.js.map +1 -1
- package/dist/exporters/MXLTraceExporter/OTLPFetchTraceExporter.cjs.map +1 -1
- package/dist/exporters/MXLTraceExporter/OTLPFetchTraceExporter.js.map +1 -1
- package/dist/exporters/MXLTraceExporter/utils.cjs.map +1 -1
- package/dist/exporters/MXLTraceExporter/utils.js.map +1 -1
- package/dist/exporters/otlpBrowserFetchExportDelegate.cjs.map +1 -1
- package/dist/exporters/otlpBrowserFetchExportDelegate.d.cts.map +1 -1
- package/dist/exporters/otlpBrowserFetchExportDelegate.d.ts.map +1 -1
- package/dist/exporters/otlpBrowserFetchExportDelegate.js.map +1 -1
- package/dist/instrumentations/MXLInstrumentationBase/MXLInstrumentationBase.cjs.map +1 -1
- package/dist/instrumentations/MXLInstrumentationBase/MXLInstrumentationBase.js.map +1 -1
- package/dist/instrumentations/clicks/ClicksInstrumentation/ClicksInstrumentation.cjs.map +1 -1
- package/dist/instrumentations/clicks/ClicksInstrumentation/ClicksInstrumentation.js.map +1 -1
- package/dist/instrumentations/document-load/DocumentLoadInstrumentation/DocumentLoadInstrumentation.cjs.map +1 -1
- package/dist/instrumentations/document-load/DocumentLoadInstrumentation/DocumentLoadInstrumentation.d.cts.map +1 -1
- package/dist/instrumentations/document-load/DocumentLoadInstrumentation/DocumentLoadInstrumentation.d.ts.map +1 -1
- package/dist/instrumentations/document-load/DocumentLoadInstrumentation/DocumentLoadInstrumentation.js.map +1 -1
- package/dist/instrumentations/document-load/DocumentLoadInstrumentation/utils.cjs.map +1 -1
- package/dist/instrumentations/document-load/DocumentLoadInstrumentation/utils.js.map +1 -1
- package/dist/instrumentations/element-timing/ElementTimingInstrumentation/ElementTimingInstrumentation.cjs.map +1 -1
- package/dist/instrumentations/element-timing/ElementTimingInstrumentation/ElementTimingInstrumentation.js.map +1 -1
- package/dist/instrumentations/empty-root/EmptyRootInstrumentation/EmptyRootInstrumentation.cjs.map +1 -1
- package/dist/instrumentations/empty-root/EmptyRootInstrumentation/EmptyRootInstrumentation.js.map +1 -1
- package/dist/instrumentations/exceptions/GlobalExceptionInstrumentation/GlobalExceptionInstrumentation.cjs.map +1 -1
- package/dist/instrumentations/exceptions/GlobalExceptionInstrumentation/GlobalExceptionInstrumentation.js.map +1 -1
- package/dist/instrumentations/exceptions/react/MXLErrorBoundary/MXLErrorBoundary.cjs.map +1 -1
- package/dist/instrumentations/exceptions/react/MXLErrorBoundary/MXLErrorBoundary.js.map +1 -1
- package/dist/instrumentations/fetch/MXLFetchInstrumentation/MXLFetchInstrumentation.cjs.map +1 -1
- package/dist/instrumentations/fetch/MXLFetchInstrumentation/MXLFetchInstrumentation.js.map +1 -1
- package/dist/instrumentations/loaf/LoafInstrumentation/LoafInstrumentation.cjs.map +1 -1
- package/dist/instrumentations/loaf/LoafInstrumentation/LoafInstrumentation.js.map +1 -1
- package/dist/instrumentations/navigation/NavigationInstrumentation/NavigationInstrumentation.cjs.map +1 -1
- package/dist/instrumentations/navigation/NavigationInstrumentation/NavigationInstrumentation.js.map +1 -1
- package/dist/instrumentations/navigation/NavigationInstrumentation/instance.cjs.map +1 -1
- package/dist/instrumentations/navigation/NavigationInstrumentation/instance.js.map +1 -1
- package/dist/instrumentations/navigation/NavigationInstrumentation/react/createReactRouterNavigationInstrumentation.cjs.map +1 -1
- package/dist/instrumentations/navigation/NavigationInstrumentation/react/createReactRouterNavigationInstrumentation.js.map +1 -1
- package/dist/instrumentations/navigation/NavigationInstrumentation/react/reactRouterV5/withMXLRoutingLegacy.cjs.map +1 -1
- package/dist/instrumentations/navigation/NavigationInstrumentation/react/reactRouterV5/withMXLRoutingLegacy.d.cts.map +1 -1
- package/dist/instrumentations/navigation/NavigationInstrumentation/react/reactRouterV5/withMXLRoutingLegacy.d.ts.map +1 -1
- package/dist/instrumentations/navigation/NavigationInstrumentation/react/reactRouterV5/withMXLRoutingLegacy.js.map +1 -1
- package/dist/instrumentations/navigation/NavigationInstrumentation/react/reactRouterV6Data/listenToRouterChanges.cjs.map +1 -1
- package/dist/instrumentations/navigation/NavigationInstrumentation/react/reactRouterV6Data/listenToRouterChanges.js.map +1 -1
- package/dist/instrumentations/navigation/NavigationInstrumentation/react/reactRouterV6Declarative/withMXLRouting.cjs.map +1 -1
- package/dist/instrumentations/navigation/NavigationInstrumentation/react/reactRouterV6Declarative/withMXLRouting.js.map +1 -1
- package/dist/instrumentations/server-timing/ServerTimingInstrumentation/ServerTimingInstrumentation.cjs.map +1 -1
- package/dist/instrumentations/server-timing/ServerTimingInstrumentation/ServerTimingInstrumentation.js.map +1 -1
- package/dist/instrumentations/session/SpanSessionBrowserActivityInstrumentation/SpanSessionBrowserActivityInstrumentation.cjs.map +1 -1
- package/dist/instrumentations/session/SpanSessionBrowserActivityInstrumentation/SpanSessionBrowserActivityInstrumentation.js.map +1 -1
- package/dist/instrumentations/session/SpanSessionOnLoadInstrumentation/SpanSessionOnLoadInstrumentation.cjs.map +1 -1
- package/dist/instrumentations/session/SpanSessionOnLoadInstrumentation/SpanSessionOnLoadInstrumentation.js.map +1 -1
- package/dist/instrumentations/session/SpanSessionTimeoutInstrumentation/SpanSessionTimeoutInstrumentation.cjs.map +1 -1
- package/dist/instrumentations/session/SpanSessionTimeoutInstrumentation/SpanSessionTimeoutInstrumentation.js.map +1 -1
- package/dist/instrumentations/session/SpanSessionVisibilityInstrumentation/SpanSessionVisibilityInstrumentation.cjs.map +1 -1
- package/dist/instrumentations/session/SpanSessionVisibilityInstrumentation/SpanSessionVisibilityInstrumentation.js.map +1 -1
- package/dist/instrumentations/user-timing/UserTimingInstrumentation/UserTimingInstrumentation.cjs.map +1 -1
- package/dist/instrumentations/user-timing/UserTimingInstrumentation/UserTimingInstrumentation.js.map +1 -1
- package/dist/instrumentations/web-vitals/WebVitalsInstrumentation/WebVitalsInstrumentation.cjs.map +1 -1
- package/dist/instrumentations/web-vitals/WebVitalsInstrumentation/WebVitalsInstrumentation.d.cts.map +1 -1
- package/dist/instrumentations/web-vitals/WebVitalsInstrumentation/WebVitalsInstrumentation.d.ts.map +1 -1
- package/dist/instrumentations/web-vitals/WebVitalsInstrumentation/WebVitalsInstrumentation.js.map +1 -1
- package/dist/instrumentations/xhr/MXLXHRInstrumentation/MXLXHRInstrumentation.cjs.map +1 -1
- package/dist/instrumentations/xhr/MXLXHRInstrumentation/MXLXHRInstrumentation.js.map +1 -1
- package/dist/managers/MXLConfigManager/MXLDynamicConfigManager.cjs +1 -1
- package/dist/managers/MXLConfigManager/MXLDynamicConfigManager.cjs.map +1 -1
- package/dist/managers/MXLConfigManager/MXLDynamicConfigManager.d.cts.map +1 -1
- package/dist/managers/MXLConfigManager/MXLDynamicConfigManager.d.ts.map +1 -1
- package/dist/managers/MXLConfigManager/MXLDynamicConfigManager.js +1 -1
- package/dist/managers/MXLConfigManager/MXLDynamicConfigManager.js.map +1 -1
- package/dist/managers/MXLConfigManager/constants.cjs.map +1 -1
- package/dist/managers/MXLConfigManager/constants.js.map +1 -1
- package/dist/managers/MXLConfigManager/utils.cjs.map +1 -1
- package/dist/managers/MXLConfigManager/utils.js.map +1 -1
- package/dist/managers/MXLLimitManager/MXLLimitManager.cjs.map +1 -1
- package/dist/managers/MXLLimitManager/MXLLimitManager.js.map +1 -1
- package/dist/managers/MXLLimitManager/constants.cjs.map +1 -1
- package/dist/managers/MXLLimitManager/constants.js.map +1 -1
- package/dist/managers/MXLLogManager/MXLLogManager.cjs.map +1 -1
- package/dist/managers/MXLLogManager/MXLLogManager.d.cts.map +1 -1
- package/dist/managers/MXLLogManager/MXLLogManager.d.ts.map +1 -1
- package/dist/managers/MXLLogManager/MXLLogManager.js.map +1 -1
- package/dist/managers/MXLPageManager/MXLPageManager.cjs.map +1 -1
- package/dist/managers/MXLPageManager/MXLPageManager.js.map +1 -1
- package/dist/managers/MXLSDKFeaturesManager/MXLSDKFeaturesManager.cjs.map +1 -1
- package/dist/managers/MXLSDKFeaturesManager/MXLSDKFeaturesManager.js.map +1 -1
- package/dist/managers/MXLSpanSessionManager/MXLSpanSessionManager.cjs.map +1 -1
- package/dist/managers/MXLSpanSessionManager/MXLSpanSessionManager.d.cts.map +1 -1
- package/dist/managers/MXLSpanSessionManager/MXLSpanSessionManager.d.ts.map +1 -1
- package/dist/managers/MXLSpanSessionManager/MXLSpanSessionManager.js.map +1 -1
- package/dist/managers/MXLTraceManager/MXLExtendedSpan.cjs.map +1 -1
- package/dist/managers/MXLTraceManager/MXLExtendedSpan.d.cts.map +1 -1
- package/dist/managers/MXLTraceManager/MXLExtendedSpan.d.ts.map +1 -1
- package/dist/managers/MXLTraceManager/MXLExtendedSpan.js.map +1 -1
- package/dist/managers/MXLTraceManager/MXLTraceManager.cjs.map +1 -1
- package/dist/managers/MXLTraceManager/MXLTraceManager.js.map +1 -1
- package/dist/managers/MXLUserManager/MXLUserManager.cjs.map +1 -1
- package/dist/managers/MXLUserManager/MXLUserManager.js.map +1 -1
- package/dist/managers/MXLUserManager/types.cjs.map +1 -1
- package/dist/managers/MXLUserManager/types.js.map +1 -1
- package/dist/mxl-web-sdk.js +5 -5
- package/dist/mxl-web-sdk.js.map +1 -1
- package/dist/processors/BrowserLogRecordProcessor/BrowserLogRecordProcessor.cjs.map +1 -1
- package/dist/processors/BrowserLogRecordProcessor/BrowserLogRecordProcessor.js.map +1 -1
- package/dist/processors/BrowserSpanProcessor/BrowserSpanProcessor.cjs.map +1 -1
- package/dist/processors/BrowserSpanProcessor/BrowserSpanProcessor.js.map +1 -1
- package/dist/processors/IdentifiableSessionLogRecordProcessor/IdentifiableSessionLogRecordProcessor.cjs.map +1 -1
- package/dist/processors/IdentifiableSessionLogRecordProcessor/IdentifiableSessionLogRecordProcessor.js.map +1 -1
- package/dist/processors/LogRecordScrubProcessor/LogRecordScrubProcessor.cjs.map +1 -1
- package/dist/processors/LogRecordScrubProcessor/LogRecordScrubProcessor.js.map +1 -1
- package/dist/processors/MXLLogRecordProcessor/MXLLogRecordProcessor.cjs.map +1 -1
- package/dist/processors/MXLLogRecordProcessor/MXLLogRecordProcessor.js.map +1 -1
- package/dist/processors/MXLNetworkSpanProcessor/MXLNetworkSpanProcessor.cjs.map +1 -1
- package/dist/processors/MXLNetworkSpanProcessor/MXLNetworkSpanProcessor.js.map +1 -1
- package/dist/processors/MXLSessionBatchedSpanProcessor/MXLSessionBatchedSpanProcessor.cjs.map +1 -1
- package/dist/processors/MXLSessionBatchedSpanProcessor/MXLSessionBatchedSpanProcessor.js.map +1 -1
- package/dist/processors/PageLogRecordProcessor/PageLogRecordProcessor.cjs.map +1 -1
- package/dist/processors/PageLogRecordProcessor/PageLogRecordProcessor.js.map +1 -1
- package/dist/processors/PageSpanProcessor/PageSpanProcessor.cjs.map +1 -1
- package/dist/processors/PageSpanProcessor/PageSpanProcessor.js.map +1 -1
- package/dist/processors/SpanScrubProcessor/SpanScrubProcessor.cjs.map +1 -1
- package/dist/processors/SpanScrubProcessor/SpanScrubProcessor.js.map +1 -1
- package/dist/processors/UserLogRecordProcessor/UserLogRecordProcessor.cjs.map +1 -1
- package/dist/processors/UserLogRecordProcessor/UserLogRecordProcessor.js.map +1 -1
- package/dist/processors/UserSpanProcessor/UserSpanProcessor.cjs.map +1 -1
- package/dist/processors/UserSpanProcessor/UserSpanProcessor.js.map +1 -1
- package/dist/propagators/MXLW3CTraceContextPropagator/MXLW3CTraceContextPropagator.cjs.map +1 -1
- package/dist/propagators/MXLW3CTraceContextPropagator/MXLW3CTraceContextPropagator.js.map +1 -1
- package/dist/resources/appInstanceId.cjs.map +1 -1
- package/dist/resources/appInstanceId.js.map +1 -1
- package/dist/resources/constants/index.cjs +1 -1
- package/dist/resources/constants/index.cjs.map +1 -1
- package/dist/resources/constants/index.d.cts +1 -1
- package/dist/resources/constants/index.d.ts +1 -1
- package/dist/resources/constants/index.js +1 -1
- package/dist/resources/constants/index.js.map +1 -1
- package/dist/resources/webSdkResource.cjs.map +1 -1
- package/dist/resources/webSdkResource.d.cts.map +1 -1
- package/dist/resources/webSdkResource.d.ts.map +1 -1
- package/dist/resources/webSdkResource.js.map +1 -1
- package/dist/sdk/defaultAttributeScrubbers.cjs.map +1 -1
- package/dist/sdk/defaultAttributeScrubbers.js.map +1 -1
- package/dist/sdk/initSDK.cjs +1 -1
- package/dist/sdk/initSDK.cjs.map +1 -1
- package/dist/sdk/initSDK.d.cts.map +1 -1
- package/dist/sdk/initSDK.d.ts.map +1 -1
- package/dist/sdk/initSDK.js +1 -1
- package/dist/sdk/initSDK.js.map +1 -1
- package/dist/sdk/registry.cjs.map +1 -1
- package/dist/sdk/registry.js.map +1 -1
- package/dist/sdk/setupDefaultInstrumentations.cjs.map +1 -1
- package/dist/sdk/setupDefaultInstrumentations.js.map +1 -1
- package/dist/sdk/setupSessionRecorder.cjs.map +1 -1
- package/dist/sdk/setupSessionRecorder.js.map +1 -1
- package/dist/sdk/types.d.cts.map +1 -1
- package/dist/sdk/types.d.ts +1 -1
- package/dist/sdk/types.d.ts.map +1 -1
- package/dist/sdk/utils.cjs.map +1 -1
- package/dist/sdk/utils.js.map +1 -1
- package/dist/transport/FetchTransport/FetchTransport.cjs.map +1 -1
- package/dist/transport/FetchTransport/FetchTransport.js.map +1 -1
- package/dist/transport/FetchTransport/createFetchTransport.cjs.map +1 -1
- package/dist/transport/FetchTransport/createFetchTransport.js.map +1 -1
- package/dist/transport/RetryingTransport/RetryingTransport.cjs.map +1 -1
- package/dist/transport/RetryingTransport/RetryingTransport.js.map +1 -1
- package/dist/transport/RetryingTransport/createRetryingTransport.cjs.map +1 -1
- package/dist/transport/RetryingTransport/createRetryingTransport.js.map +1 -1
- package/dist/utils/MXLSpanStorage/MXLSpanStorage.cjs.map +1 -1
- package/dist/utils/MXLSpanStorage/MXLSpanStorage.js.map +1 -1
- package/dist/utils/PerformanceManager/OTelPerformanceManager.cjs.map +1 -1
- package/dist/utils/PerformanceManager/OTelPerformanceManager.js.map +1 -1
- package/dist/utils/bulkAddEventListener/bulkAddEventListener.cjs.map +1 -1
- package/dist/utils/bulkAddEventListener/bulkAddEventListener.js.map +1 -1
- package/dist/utils/bulkRemoveEventListener/bulkRemoveEventListener.cjs.map +1 -1
- package/dist/utils/bulkRemoveEventListener/bulkRemoveEventListener.js.map +1 -1
- package/dist/utils/getVisibilityState.cjs.map +1 -1
- package/dist/utils/getVisibilityState.js.map +1 -1
- package/dist/utils/nsfConfigValidation.cjs.map +1 -1
- package/dist/utils/nsfConfigValidation.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MXLLimitManager.js","names":[],"sources":["../../../src/managers/MXLLimitManager/MXLLimitManager.ts"],"sourcesContent":["import type { AttributeValue, DiagLogger } from '@opentelemetry/api';\nimport { diag } from '@opentelemetry/api';\nimport type { ReadableSpan } from '@opentelemetry/sdk-trace-web';\nimport type { LogSeverity } from '../../api-logs
|
|
1
|
+
{"version":3,"file":"MXLLimitManager.js","names":[],"sources":["../../../src/managers/MXLLimitManager/MXLLimitManager.ts"],"sourcesContent":["import type { AttributeValue, DiagLogger } from '@opentelemetry/api';\nimport { diag } from '@opentelemetry/api';\nimport type { ReadableSpan } from '@opentelemetry/sdk-trace-web';\nimport type { LogSeverity } from '../../api-logs';\nimport { KEY_MXL_TYPE, MXL_TYPES } from '../../constants';\nimport type {\n AttributeLimitedType,\n LengthLimitedType,\n LimitedBreadcrumb,\n LimitedException,\n LimitedLog,\n LimitedSessionProperty,\n LimitedType,\n LimitManagerInternal,\n LimitOperation,\n LogLimitedType,\n MaxLimitedType,\n MXLLimitManagerArgs,\n} from './types';\n\nconst LogSeverityToLimitType: Record<LogSeverity, LogLimitedType> = {\n info: 'info_log',\n warning: 'warning_log',\n error: 'error_log',\n};\n\nexport class MXLLimitManager implements LimitManagerInternal {\n private readonly _diag: DiagLogger;\n\n private _diagnosticCounts: Record<string, number> = {};\n private _currentCount: Record<MaxLimitedType, number> = {\n exception: 0,\n error_log: 0,\n warning_log: 0,\n info_log: 0,\n breadcrumb: 0,\n session_property: 0,\n span: 0,\n network_request: 0,\n element_timing: 0,\n server_timing: 0,\n user_timing_mark: 0,\n user_timing_measure: 0,\n };\n private readonly _maxAllowed: Record<MaxLimitedType, number>;\n private readonly _maxLength: Record<LengthLimitedType, number>;\n private readonly _maxAttributes: Record<AttributeLimitedType, number>;\n\n public constructor({\n diag: diagParam,\n maxAllowed,\n maxLength,\n maxAttributes,\n }: MXLLimitManagerArgs) {\n this._diag =\n diagParam ??\n diag.createComponentLogger({\n namespace: 'MXLLimitManager',\n });\n\n this._maxAllowed = maxAllowed;\n this._maxLength = maxLength;\n this._maxAttributes = maxAttributes;\n }\n\n private _dropIfMaxReached(type: MaxLimitedType): boolean {\n if (this._currentCount[type] >= this._maxAllowed[type]) {\n this._diag.warn(\n `disallowing ${type} because the maximum number of ${this._maxAllowed[type].toString()} has already been reached for this session`,\n );\n\n this._incrDiagnosticCount(type, 'drop');\n return true;\n }\n\n this._currentCount[type] = (this._currentCount[type] || 0) + 1;\n return false;\n }\n\n public truncateString(type: LengthLimitedType, body: string) {\n if (body.length > this._maxLength[type]) {\n this._diag.warn(\n `truncating ${type} because it is longer than ${this._maxLength[type].toString()} characters: \"${body}\"`,\n );\n\n this._incrDiagnosticCount(type, 'truncate_string');\n return body.substring(0, this._maxLength[type]);\n }\n\n return body;\n }\n\n private _truncateAttributes(\n type: AttributeLimitedType,\n attributes: Record<string, AttributeValue | undefined>,\n keyType: LengthLimitedType,\n valueType: LengthLimitedType,\n ) {\n const keys = Object.keys(attributes);\n\n if (keys.length > this._maxAttributes[type]) {\n this._diag.warn(\n `truncating ${type} attributes because there are more than ${this._maxAttributes[type].toString()} set`,\n );\n this._incrDiagnosticCount(type, 'truncate_attributes');\n }\n\n const truncatedAttributes: Record<string, AttributeValue | undefined> = {};\n\n for (let i = 0; i < Math.min(keys.length, this._maxAttributes[type]); i++) {\n const truncatedKey = this.truncateString(keyType, keys[i]);\n truncatedAttributes[truncatedKey] = this.truncateString(\n valueType,\n attributes[keys[i]]?.toString() || '',\n );\n }\n\n return truncatedAttributes;\n }\n\n public limitBreadcrumb(name: string): LimitedBreadcrumb | 'dropped' {\n if (this._dropIfMaxReached('breadcrumb')) {\n return 'dropped';\n }\n\n return {\n name: this.truncateString('breadcrumb', name),\n };\n }\n\n public limitException(\n message: string,\n attributes: Record<string, AttributeValue | undefined>,\n ): LimitedException | 'dropped' {\n if (this._dropIfMaxReached('exception')) {\n return 'dropped';\n }\n\n return {\n message: this.truncateString('exception', message),\n attributes: this._truncateAttributes(\n 'exception',\n attributes,\n 'exception_attribute_key',\n 'exception_attribute_value',\n ),\n };\n }\n\n public limitLog(\n message: string,\n severity: LogSeverity,\n attributes: Record<string, AttributeValue | undefined>,\n ): LimitedLog | 'dropped' {\n const logType = LogSeverityToLimitType[severity];\n\n if (this._dropIfMaxReached(logType)) {\n return 'dropped';\n }\n\n return {\n message: this.truncateString(logType, message),\n attributes: this._truncateAttributes(\n logType,\n attributes,\n 'log_attribute_key',\n 'log_attribute_value',\n ),\n };\n }\n\n public limitSessionProperty(\n key: string,\n value: string,\n ): LimitedSessionProperty | 'dropped' {\n if (this._dropIfMaxReached('session_property')) {\n return 'dropped';\n }\n\n return {\n key: this.truncateString('session_property_key', key),\n value: this.truncateString('session_property_value', value),\n };\n }\n\n public limitElementTimingEntry(): boolean {\n return this._dropIfMaxReached('element_timing');\n }\n\n public limitServerTimingEntry(): boolean {\n return this._dropIfMaxReached('server_timing');\n }\n\n public limitUserTimingEntry(entryType: 'mark' | 'measure'): boolean {\n return this._dropIfMaxReached(\n entryType === 'mark' ? 'user_timing_mark' : 'user_timing_measure',\n );\n }\n\n public dropReadableSpan(span: ReadableSpan): boolean {\n const type =\n span.attributes[KEY_MXL_TYPE] === MXL_TYPES.Network\n ? 'network_request'\n : 'span';\n\n return this._dropIfMaxReached(type);\n }\n\n public reset(): void {\n this._diagnosticCounts = {};\n this._currentCount = {\n exception: 0,\n error_log: 0,\n warning_log: 0,\n info_log: 0,\n breadcrumb: 0,\n session_property: 0,\n span: 0,\n network_request: 0,\n element_timing: 0,\n server_timing: 0,\n user_timing_mark: 0,\n user_timing_measure: 0,\n };\n }\n\n private _incrDiagnosticCount(type: LimitedType, operation: LimitOperation) {\n const key = `mxl.app.applied_limit.${type}.${operation}.count`;\n\n this._diagnosticCounts[key] = (this._diagnosticCounts[key] || 0) + 1;\n }\n public getDiagnosticCounts(): Record<string, number> {\n return this._diagnosticCounts;\n }\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.cjs","names":[],"sources":["../../../src/managers/MXLLimitManager/constants.ts"],"sourcesContent":["import type { MXLLimitManagerArgs } from './types
|
|
1
|
+
{"version":3,"file":"constants.cjs","names":[],"sources":["../../../src/managers/MXLLimitManager/constants.ts"],"sourcesContent":["import type { MXLLimitManagerArgs } from './types';\n\nexport const DEFAULT_MAX_LOG_ATTRIBUTES = 50;\n\nexport const DEFAULT_LIMITS: MXLLimitManagerArgs = {\n // These are per session limits, the counts of items against these maximums start over when `reset` is called on the\n // limit manager which is done whenever a session ends\n maxAllowed: {\n error_log: 500,\n warning_log: 200,\n info_log: 100,\n exception: 500,\n breadcrumb: 100,\n session_property: 100,\n span: 1_000,\n network_request: 10_000,\n element_timing: 500,\n server_timing: 500,\n user_timing_mark: 500,\n user_timing_measure: 500,\n },\n maxLength: {\n error_log: 128,\n warning_log: 128,\n info_log: 128,\n exception: 1024,\n breadcrumb: 256,\n session_property_key: 128,\n session_property_value: 256,\n log_attribute_key: 128,\n log_attribute_value: 256,\n exception_attribute_key: 128,\n exception_attribute_value: 256,\n },\n maxAttributes: {\n error_log: DEFAULT_MAX_LOG_ATTRIBUTES,\n warning_log: DEFAULT_MAX_LOG_ATTRIBUTES,\n info_log: DEFAULT_MAX_LOG_ATTRIBUTES,\n exception: DEFAULT_MAX_LOG_ATTRIBUTES,\n },\n};\n"],"mappings":";;AAEA,MAAa,6BAA6B;AAE1C,MAAa,iBAAsC;CAGjD,YAAY;EACV,WAAW;EACX,aAAa;EACb,UAAU;EACV,WAAW;EACX,YAAY;EACZ,kBAAkB;EAClB,MAAM;EACN,iBAAiB;EACjB,gBAAgB;EAChB,eAAe;EACf,kBAAkB;EAClB,qBAAqB;EACtB;CACD,WAAW;EACT,WAAW;EACX,aAAa;EACb,UAAU;EACV,WAAW;EACX,YAAY;EACZ,sBAAsB;EACtB,wBAAwB;EACxB,mBAAmB;EACnB,qBAAqB;EACrB,yBAAyB;EACzB,2BAA2B;EAC5B;CACD,eAAe;EACb,WAAA;EACA,aAAA;EACA,UAAA;EACA,WAAA;EACD;CACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.js","names":[],"sources":["../../../src/managers/MXLLimitManager/constants.ts"],"sourcesContent":["import type { MXLLimitManagerArgs } from './types
|
|
1
|
+
{"version":3,"file":"constants.js","names":[],"sources":["../../../src/managers/MXLLimitManager/constants.ts"],"sourcesContent":["import type { MXLLimitManagerArgs } from './types';\n\nexport const DEFAULT_MAX_LOG_ATTRIBUTES = 50;\n\nexport const DEFAULT_LIMITS: MXLLimitManagerArgs = {\n // These are per session limits, the counts of items against these maximums start over when `reset` is called on the\n // limit manager which is done whenever a session ends\n maxAllowed: {\n error_log: 500,\n warning_log: 200,\n info_log: 100,\n exception: 500,\n breadcrumb: 100,\n session_property: 100,\n span: 1_000,\n network_request: 10_000,\n element_timing: 500,\n server_timing: 500,\n user_timing_mark: 500,\n user_timing_measure: 500,\n },\n maxLength: {\n error_log: 128,\n warning_log: 128,\n info_log: 128,\n exception: 1024,\n breadcrumb: 256,\n session_property_key: 128,\n session_property_value: 256,\n log_attribute_key: 128,\n log_attribute_value: 256,\n exception_attribute_key: 128,\n exception_attribute_value: 256,\n },\n maxAttributes: {\n error_log: DEFAULT_MAX_LOG_ATTRIBUTES,\n warning_log: DEFAULT_MAX_LOG_ATTRIBUTES,\n info_log: DEFAULT_MAX_LOG_ATTRIBUTES,\n exception: DEFAULT_MAX_LOG_ATTRIBUTES,\n },\n};\n"],"mappings":";AAEA,MAAa,6BAA6B;AAE1C,MAAa,iBAAsC;CAGjD,YAAY;EACV,WAAW;EACX,aAAa;EACb,UAAU;EACV,WAAW;EACX,YAAY;EACZ,kBAAkB;EAClB,MAAM;EACN,iBAAiB;EACjB,gBAAgB;EAChB,eAAe;EACf,kBAAkB;EAClB,qBAAqB;EACtB;CACD,WAAW;EACT,WAAW;EACX,aAAa;EACb,UAAU;EACV,WAAW;EACX,YAAY;EACZ,sBAAsB;EACtB,wBAAwB;EACxB,mBAAmB;EACnB,qBAAqB;EACrB,yBAAyB;EACzB,2BAA2B;EAC5B;CACD,eAAe;EACb,WAAA;EACA,aAAA;EACA,UAAA;EACA,WAAA;EACD;CACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MXLLogManager.cjs","names":["GLOBAL_CONFIG","logs","diag","OTelPerformanceManager","SeverityNumber","KEY_MXL_UNHANDLED_EXCEPTIONS_COUNT","KEY_MXL_TYPE","KEY_MXL_EXCEPTION_HANDLING","KEY_MXL_EXCEPTION_CAUSE","ATTR_EXCEPTION_TYPE","ATTR_EXCEPTION_MESSAGE","ATTR_EXCEPTION_STACKTRACE","KEY_MXL_JS_FILE_BUNDLE_IDS","KEY_MXL_STATE","getVisibilityState","KEY_MXL_EXCEPTION_NUMBER","getIncrementedCount","KEY_MXL_ERROR_LOG_COUNT","KEY_MXL_JS_EXCEPTION_STACKTRACE"],"sources":["../../../src/managers/MXLLogManager/MXLLogManager.ts"],"sourcesContent":["import type { Attributes, DiagLogger } from '@opentelemetry/api';\nimport { diag } from '@opentelemetry/api';\nimport type { Logger } from '@opentelemetry/api-logs';\nimport { logs, SeverityNumber } from '@opentelemetry/api-logs';\nimport {\n ATTR_EXCEPTION_MESSAGE,\n ATTR_EXCEPTION_STACKTRACE,\n ATTR_EXCEPTION_TYPE,\n} from '@opentelemetry/semantic-conventions';\nimport type { LogManager, LogSeverity } from '../../api-logs/index.ts';\nimport type {\n LogExceptionOptions,\n LogMessageOptions,\n} from '../../api-logs/manager/index.ts';\nimport type { ExceptionHandlerType } from '../../api-logs/manager/types.ts';\nimport type { VisibilityStateDocument } from '../../common/index.ts';\nimport {\n KEY_MXL_ERROR_LOG_COUNT,\n KEY_MXL_EXCEPTION_CAUSE,\n KEY_MXL_JS_FILE_BUNDLE_IDS,\n KEY_MXL_UNHANDLED_EXCEPTIONS_COUNT,\n} from '../../constants/attributes.ts';\nimport {\n KEY_MXL_EXCEPTION_HANDLING,\n KEY_MXL_EXCEPTION_NUMBER,\n KEY_MXL_JS_EXCEPTION_STACKTRACE,\n KEY_MXL_STATE,\n KEY_MXL_TYPE,\n MXL_TYPES,\n} from '../../constants/index.ts';\nimport type { PerformanceManager } from '../../utils/index.ts';\nimport {\n GLOBAL_CONFIG,\n getIncrementedCount,\n getVisibilityState,\n OTelPerformanceManager,\n} from '../../utils/index.ts';\nimport type { LimitManagerInternal } from '../MXLLimitManager/index.ts';\nimport type { SpanSessionManagerInternal } from '../MXLSpanSessionManager/index.ts';\nimport type { MXLLogManagerArgs } from './types.ts';\n\nconst MXL_EXCEPTION_NUMBER_STORAGE_KEY = 'mxl_exception_number';\n/**\n * GLOBAL_CONFIG._MXLFileBundleIDs is populated at runtime when each file is loaded,\n * based on the contents injected by the mxl-web-cli.\n */\nconst getJSFileBundleIDs = () =>\n JSON.stringify(\n GLOBAL_CONFIG._MXLFileBundleIDs ||\n GLOBAL_CONFIG._MXLFileBundleIDs ||\n {},\n );\n\nexport class MXLLogManager implements LogManager {\n private readonly _diag: DiagLogger;\n private readonly _perf: PerformanceManager;\n private readonly _logger: Logger;\n private readonly _spanSessionManager: SpanSessionManagerInternal;\n private readonly _limitManager: LimitManagerInternal;\n private readonly _visibilityDoc: VisibilityStateDocument;\n private readonly _storage: Storage;\n\n public constructor({\n diag: diagParam,\n perf,\n spanSessionManager,\n limitManager,\n loggerProvider: globalLoggerProviderOverride,\n visibilityDoc = window.document,\n storage = window.localStorage,\n }: MXLLogManagerArgs) {\n const loggerProvider = globalLoggerProviderOverride ?? logs;\n\n this._diag =\n diagParam ??\n diag.createComponentLogger({\n namespace: 'MXLLogManager',\n });\n this._perf = perf ?? new OTelPerformanceManager();\n this._logger = loggerProvider.getLogger('mxl-web-sdk-logs');\n this._spanSessionManager = spanSessionManager;\n this._limitManager = limitManager;\n this._visibilityDoc = visibilityDoc;\n this._storage = storage;\n }\n\n private _validateAttributes(attributes: unknown): Attributes {\n if (Object.prototype.toString.call(attributes) !== '[object Object]') {\n this._diag.warn('attributes must be a plain object', attributes);\n return {};\n }\n return attributes as Attributes;\n }\n\n private static _logSeverityToSeverityNumber(\n severity: LogSeverity,\n ): SeverityNumber {\n switch (severity) {\n case 'info':\n return SeverityNumber.INFO;\n case 'warning':\n return SeverityNumber.WARN;\n default:\n return SeverityNumber.ERROR;\n }\n }\n\n public logException(\n error: unknown,\n {\n handled = true,\n attributes = {},\n timestamp = this._perf.getNowMillis(),\n handler = 'manual',\n }: LogExceptionOptions = {},\n ) {\n const validAttrs = this._validateAttributes(attributes);\n\n if (!handled) {\n this._spanSessionManager.incrSessionCountForKey(\n KEY_MXL_UNHANDLED_EXCEPTIONS_COUNT,\n );\n }\n\n const type = error?.constructor?.name || typeof error;\n let errMessage = '';\n let errName = type;\n let errStack = '';\n let errCause = '';\n\n if (error instanceof Error) {\n errMessage = String(error.message || '').trim();\n errName = error.name || '';\n errStack = error.stack || '';\n errCause = error.cause ? 'present' : '';\n } else if (error && typeof error === 'object') {\n try {\n errMessage = JSON.stringify(error);\n } catch {\n errMessage = String(error).trim();\n }\n } else {\n errMessage = String(error).trim();\n }\n\n const limited = this._limitManager.limitException(errMessage, validAttrs);\n if (limited === 'dropped') {\n return;\n }\n\n this._logger.emit({\n timestamp,\n severityNumber: SeverityNumber.ERROR,\n severityText: 'ERROR',\n body: limited.message,\n attributes: {\n ...limited.attributes,\n [KEY_MXL_TYPE]: MXL_TYPES.SystemException,\n [KEY_MXL_EXCEPTION_HANDLING]: MXLLogManager._exceptionHandlingType(\n handled,\n handler,\n ),\n [KEY_MXL_EXCEPTION_CAUSE]: errCause,\n [ATTR_EXCEPTION_TYPE]: type,\n ['exception.name']: errName,\n [ATTR_EXCEPTION_MESSAGE]: limited.message,\n [ATTR_EXCEPTION_STACKTRACE]: errStack,\n [KEY_MXL_JS_FILE_BUNDLE_IDS]: getJSFileBundleIDs(),\n [KEY_MXL_STATE]: getVisibilityState(this._visibilityDoc),\n [KEY_MXL_EXCEPTION_NUMBER]: getIncrementedCount(\n this._storage,\n MXL_EXCEPTION_NUMBER_STORAGE_KEY,\n this._diag,\n ),\n },\n });\n }\n\n public message(\n message: string,\n severity: LogSeverity,\n {\n attributes = {},\n includeStacktrace = true,\n stacktrace,\n }: LogMessageOptions = {},\n ) {\n if (typeof message !== 'string' || !message.trim()) {\n this._diag.warn('Message must be a non-empty string');\n return;\n }\n\n if (!['info', 'warning', 'error'].includes(severity)) {\n this._diag.warn('Severity must be info, warning, or error');\n return;\n }\n\n const validAttrs = this._validateAttributes(attributes);\n\n if (severity === 'error') {\n this._spanSessionManager.incrSessionCountForKey(KEY_MXL_ERROR_LOG_COUNT);\n }\n\n let stack = '';\n if (severity !== 'info') {\n if (typeof stacktrace === 'string') {\n stack = stacktrace;\n } else if (includeStacktrace) {\n stack = new Error().stack || '';\n }\n }\n\n this._logMessage({\n message: message.trim(),\n severity,\n timestamp: this._perf.getNowMillis(),\n attributes: validAttrs,\n stack,\n });\n }\n\n private _logMessage({\n message,\n severity,\n timestamp,\n attributes = {},\n stack,\n }: {\n message: string;\n severity: LogSeverity;\n timestamp: number;\n attributes?: Attributes;\n stack?: string;\n }) {\n const limitedLog = this._limitManager.limitLog(\n message,\n severity,\n attributes,\n );\n\n if (limitedLog === 'dropped') {\n return;\n }\n\n this._logger.emit({\n timestamp,\n severityNumber: MXLLogManager._logSeverityToSeverityNumber(severity),\n severityText: severity.toUpperCase(),\n body: limitedLog.message,\n attributes: {\n ...limitedLog.attributes,\n [KEY_MXL_TYPE]: MXL_TYPES.SystemLog,\n ...(stack\n ? {\n [KEY_MXL_JS_EXCEPTION_STACKTRACE]: stack,\n [KEY_MXL_JS_FILE_BUNDLE_IDS]: getJSFileBundleIDs(),\n }\n : {}),\n [KEY_MXL_STATE]: getVisibilityState(this._visibilityDoc),\n },\n });\n }\n\n private static _exceptionHandlingType(\n handled: boolean,\n handler: ExceptionHandlerType,\n ): string {\n if (handled) {\n return 'handled';\n }\n\n if (handler === 'global_exception') {\n return 'unhandled_error';\n }\n\n if (handler === 'promise_rejection') {\n return 'unhandled_rejection';\n }\n\n return 'unhandled';\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"MXLLogManager.cjs","names":["GLOBAL_CONFIG","logs","diag","OTelPerformanceManager","SeverityNumber","KEY_MXL_UNHANDLED_EXCEPTIONS_COUNT","KEY_MXL_TYPE","KEY_MXL_EXCEPTION_HANDLING","KEY_MXL_EXCEPTION_CAUSE","ATTR_EXCEPTION_TYPE","ATTR_EXCEPTION_MESSAGE","ATTR_EXCEPTION_STACKTRACE","KEY_MXL_JS_FILE_BUNDLE_IDS","KEY_MXL_STATE","getVisibilityState","KEY_MXL_EXCEPTION_NUMBER","getIncrementedCount","KEY_MXL_ERROR_LOG_COUNT","KEY_MXL_JS_EXCEPTION_STACKTRACE"],"sources":["../../../src/managers/MXLLogManager/MXLLogManager.ts"],"sourcesContent":["import type { Attributes, DiagLogger } from '@opentelemetry/api';\nimport { diag } from '@opentelemetry/api';\nimport type { Logger } from '@opentelemetry/api-logs';\nimport { logs, SeverityNumber } from '@opentelemetry/api-logs';\nimport {\n ATTR_EXCEPTION_MESSAGE,\n ATTR_EXCEPTION_STACKTRACE,\n ATTR_EXCEPTION_TYPE,\n} from '@opentelemetry/semantic-conventions';\nimport type { LogManager, LogSeverity } from '../../api-logs';\nimport type {\n LogExceptionOptions,\n LogMessageOptions,\n} from '../../api-logs/manager';\nimport type { ExceptionHandlerType } from '../../api-logs/manager/types';\nimport type { VisibilityStateDocument } from '../../common';\nimport {\n KEY_MXL_EXCEPTION_HANDLING,\n KEY_MXL_EXCEPTION_NUMBER,\n KEY_MXL_JS_EXCEPTION_STACKTRACE,\n KEY_MXL_STATE,\n KEY_MXL_TYPE,\n MXL_TYPES,\n} from '../../constants';\nimport {\n KEY_MXL_ERROR_LOG_COUNT,\n KEY_MXL_EXCEPTION_CAUSE,\n KEY_MXL_JS_FILE_BUNDLE_IDS,\n KEY_MXL_UNHANDLED_EXCEPTIONS_COUNT,\n} from '../../constants/attributes';\nimport type { PerformanceManager } from '../../utils';\nimport {\n GLOBAL_CONFIG,\n getIncrementedCount,\n getVisibilityState,\n OTelPerformanceManager,\n} from '../../utils';\nimport type { LimitManagerInternal } from '../MXLLimitManager';\nimport type { SpanSessionManagerInternal } from '../MXLSpanSessionManager';\nimport type { MXLLogManagerArgs } from './types';\n\nconst MXL_EXCEPTION_NUMBER_STORAGE_KEY = 'mxl_exception_number';\n/**\n * GLOBAL_CONFIG._MXLFileBundleIDs is populated at runtime when each file is loaded,\n * based on the contents injected by the mxl-web-cli.\n */\nconst getJSFileBundleIDs = () =>\n JSON.stringify(\n GLOBAL_CONFIG._MXLFileBundleIDs || GLOBAL_CONFIG._MXLFileBundleIDs || {},\n );\n\nexport class MXLLogManager implements LogManager {\n private readonly _diag: DiagLogger;\n private readonly _perf: PerformanceManager;\n private readonly _logger: Logger;\n private readonly _spanSessionManager: SpanSessionManagerInternal;\n private readonly _limitManager: LimitManagerInternal;\n private readonly _visibilityDoc: VisibilityStateDocument;\n private readonly _storage: Storage;\n\n public constructor({\n diag: diagParam,\n perf,\n spanSessionManager,\n limitManager,\n loggerProvider: globalLoggerProviderOverride,\n visibilityDoc = window.document,\n storage = window.localStorage,\n }: MXLLogManagerArgs) {\n const loggerProvider = globalLoggerProviderOverride ?? logs;\n\n this._diag =\n diagParam ??\n diag.createComponentLogger({\n namespace: 'MXLLogManager',\n });\n this._perf = perf ?? new OTelPerformanceManager();\n this._logger = loggerProvider.getLogger('mxl-web-sdk-logs');\n this._spanSessionManager = spanSessionManager;\n this._limitManager = limitManager;\n this._visibilityDoc = visibilityDoc;\n this._storage = storage;\n }\n\n private _validateAttributes(attributes: unknown): Attributes {\n if (Object.prototype.toString.call(attributes) !== '[object Object]') {\n this._diag.warn('attributes must be a plain object', attributes);\n return {};\n }\n return attributes as Attributes;\n }\n\n private static _logSeverityToSeverityNumber(\n severity: LogSeverity,\n ): SeverityNumber {\n switch (severity) {\n case 'info':\n return SeverityNumber.INFO;\n case 'warning':\n return SeverityNumber.WARN;\n default:\n return SeverityNumber.ERROR;\n }\n }\n\n public logException(\n error: unknown,\n {\n handled = true,\n attributes = {},\n timestamp = this._perf.getNowMillis(),\n handler = 'manual',\n }: LogExceptionOptions = {},\n ) {\n const validAttrs = this._validateAttributes(attributes);\n\n if (!handled) {\n this._spanSessionManager.incrSessionCountForKey(\n KEY_MXL_UNHANDLED_EXCEPTIONS_COUNT,\n );\n }\n\n const type = error?.constructor?.name || typeof error;\n let errMessage = '';\n let errName = type;\n let errStack = '';\n let errCause = '';\n\n if (error instanceof Error) {\n errMessage = String(error.message || '').trim();\n errName = error.name || '';\n errStack = error.stack || '';\n errCause = error.cause ? 'present' : '';\n } else if (error && typeof error === 'object') {\n try {\n errMessage = JSON.stringify(error);\n } catch {\n errMessage = String(error).trim();\n }\n } else {\n errMessage = String(error).trim();\n }\n\n const limited = this._limitManager.limitException(errMessage, validAttrs);\n if (limited === 'dropped') {\n return;\n }\n\n this._logger.emit({\n timestamp,\n severityNumber: SeverityNumber.ERROR,\n severityText: 'ERROR',\n body: limited.message,\n attributes: {\n ...limited.attributes,\n [KEY_MXL_TYPE]: MXL_TYPES.SystemException,\n [KEY_MXL_EXCEPTION_HANDLING]: MXLLogManager._exceptionHandlingType(\n handled,\n handler,\n ),\n [KEY_MXL_EXCEPTION_CAUSE]: errCause,\n [ATTR_EXCEPTION_TYPE]: type,\n ['exception.name']: errName,\n [ATTR_EXCEPTION_MESSAGE]: limited.message,\n [ATTR_EXCEPTION_STACKTRACE]: errStack,\n [KEY_MXL_JS_FILE_BUNDLE_IDS]: getJSFileBundleIDs(),\n [KEY_MXL_STATE]: getVisibilityState(this._visibilityDoc),\n [KEY_MXL_EXCEPTION_NUMBER]: getIncrementedCount(\n this._storage,\n MXL_EXCEPTION_NUMBER_STORAGE_KEY,\n this._diag,\n ),\n },\n });\n }\n\n public message(\n message: string,\n severity: LogSeverity,\n {\n attributes = {},\n includeStacktrace = true,\n stacktrace,\n }: LogMessageOptions = {},\n ) {\n if (typeof message !== 'string' || !message.trim()) {\n this._diag.warn('Message must be a non-empty string');\n return;\n }\n\n if (!['info', 'warning', 'error'].includes(severity)) {\n this._diag.warn('Severity must be info, warning, or error');\n return;\n }\n\n const validAttrs = this._validateAttributes(attributes);\n\n if (severity === 'error') {\n this._spanSessionManager.incrSessionCountForKey(KEY_MXL_ERROR_LOG_COUNT);\n }\n\n let stack = '';\n if (severity !== 'info') {\n if (typeof stacktrace === 'string') {\n stack = stacktrace;\n } else if (includeStacktrace) {\n stack = new Error().stack || '';\n }\n }\n\n this._logMessage({\n message: message.trim(),\n severity,\n timestamp: this._perf.getNowMillis(),\n attributes: validAttrs,\n stack,\n });\n }\n\n private _logMessage({\n message,\n severity,\n timestamp,\n attributes = {},\n stack,\n }: {\n message: string;\n severity: LogSeverity;\n timestamp: number;\n attributes?: Attributes;\n stack?: string;\n }) {\n const limitedLog = this._limitManager.limitLog(\n message,\n severity,\n attributes,\n );\n\n if (limitedLog === 'dropped') {\n return;\n }\n\n this._logger.emit({\n timestamp,\n severityNumber: MXLLogManager._logSeverityToSeverityNumber(severity),\n severityText: severity.toUpperCase(),\n body: limitedLog.message,\n attributes: {\n ...limitedLog.attributes,\n [KEY_MXL_TYPE]: MXL_TYPES.SystemLog,\n ...(stack\n ? {\n [KEY_MXL_JS_EXCEPTION_STACKTRACE]: stack,\n [KEY_MXL_JS_FILE_BUNDLE_IDS]: getJSFileBundleIDs(),\n }\n : {}),\n [KEY_MXL_STATE]: getVisibilityState(this._visibilityDoc),\n },\n });\n }\n\n private static _exceptionHandlingType(\n handled: boolean,\n handler: ExceptionHandlerType,\n ): string {\n if (handled) {\n return 'handled';\n }\n\n if (handler === 'global_exception') {\n return 'unhandled_error';\n }\n\n if (handler === 'promise_rejection') {\n return 'unhandled_rejection';\n }\n\n return 'unhandled';\n }\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MXLLogManager.d.cts","names":[],"sources":["../../../src/managers/MXLLogManager/MXLLogManager.ts"],"mappings":";;;;
|
|
1
|
+
{"version":3,"file":"MXLLogManager.d.cts","names":[],"sources":["../../../src/managers/MXLLogManager/MXLLogManager.ts"],"mappings":";;;;cAmDa,aAAA,YAAyB,UAAA;EAAA,iBACnB,KAAA;EAAA,iBACA,KAAA;EAAA,iBACA,OAAA;EAAA,iBACA,mBAAA;EAAA,iBACA,aAAA;EAAA,iBACA,cAAA;EAAA,iBACA,QAAA;;IAGf,IAAA,EAAM,SAAA;IACN,IAAA;IACA,kBAAA;IACA,YAAA;IACA,cAAA,EAAgB,4BAAA;IAChB,aAAA;IACA;EAAA,GACC,iBAAA;EAAA,QAgBK,mBAAA;EAAA,eAQO,4BAAA;EAaR,YAAA,CACL,KAAA;IAEE,OAAA;IACA,UAAA;IACA,SAAA;IACA;EAAA,IACC,mBAAA;EAgEE,OAAA,CACL,OAAA,UACA,QAAA,EAAU,WAAA;IAER,UAAA;IACA,iBAAA;IACA;EAAA,IACC,iBAAA;EAAA,QAoCG,WAAA;EAAA,eA0CO,sBAAA;AAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MXLLogManager.d.ts","names":[],"sources":["../../../src/managers/MXLLogManager/MXLLogManager.ts"],"mappings":";;;;
|
|
1
|
+
{"version":3,"file":"MXLLogManager.d.ts","names":[],"sources":["../../../src/managers/MXLLogManager/MXLLogManager.ts"],"mappings":";;;;cAmDa,aAAA,YAAyB,UAAA;EAAA,iBACnB,KAAA;EAAA,iBACA,KAAA;EAAA,iBACA,OAAA;EAAA,iBACA,mBAAA;EAAA,iBACA,aAAA;EAAA,iBACA,cAAA;EAAA,iBACA,QAAA;;IAGf,IAAA,EAAM,SAAA;IACN,IAAA;IACA,kBAAA;IACA,YAAA;IACA,cAAA,EAAgB,4BAAA;IAChB,aAAA;IACA;EAAA,GACC,iBAAA;EAAA,QAgBK,mBAAA;EAAA,eAQO,4BAAA;EAaR,YAAA,CACL,KAAA;IAEE,OAAA;IACA,UAAA;IACA,SAAA;IACA;EAAA,IACC,mBAAA;EAgEE,OAAA,CACL,OAAA,UACA,QAAA,EAAU,WAAA;IAER,UAAA;IACA,iBAAA;IACA;EAAA,IACC,iBAAA;EAAA,QAoCG,WAAA;EAAA,eA0CO,sBAAA;AAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MXLLogManager.js","names":[],"sources":["../../../src/managers/MXLLogManager/MXLLogManager.ts"],"sourcesContent":["import type { Attributes, DiagLogger } from '@opentelemetry/api';\nimport { diag } from '@opentelemetry/api';\nimport type { Logger } from '@opentelemetry/api-logs';\nimport { logs, SeverityNumber } from '@opentelemetry/api-logs';\nimport {\n ATTR_EXCEPTION_MESSAGE,\n ATTR_EXCEPTION_STACKTRACE,\n ATTR_EXCEPTION_TYPE,\n} from '@opentelemetry/semantic-conventions';\nimport type { LogManager, LogSeverity } from '../../api-logs/index.ts';\nimport type {\n LogExceptionOptions,\n LogMessageOptions,\n} from '../../api-logs/manager/index.ts';\nimport type { ExceptionHandlerType } from '../../api-logs/manager/types.ts';\nimport type { VisibilityStateDocument } from '../../common/index.ts';\nimport {\n KEY_MXL_ERROR_LOG_COUNT,\n KEY_MXL_EXCEPTION_CAUSE,\n KEY_MXL_JS_FILE_BUNDLE_IDS,\n KEY_MXL_UNHANDLED_EXCEPTIONS_COUNT,\n} from '../../constants/attributes.ts';\nimport {\n KEY_MXL_EXCEPTION_HANDLING,\n KEY_MXL_EXCEPTION_NUMBER,\n KEY_MXL_JS_EXCEPTION_STACKTRACE,\n KEY_MXL_STATE,\n KEY_MXL_TYPE,\n MXL_TYPES,\n} from '../../constants/index.ts';\nimport type { PerformanceManager } from '../../utils/index.ts';\nimport {\n GLOBAL_CONFIG,\n getIncrementedCount,\n getVisibilityState,\n OTelPerformanceManager,\n} from '../../utils/index.ts';\nimport type { LimitManagerInternal } from '../MXLLimitManager/index.ts';\nimport type { SpanSessionManagerInternal } from '../MXLSpanSessionManager/index.ts';\nimport type { MXLLogManagerArgs } from './types.ts';\n\nconst MXL_EXCEPTION_NUMBER_STORAGE_KEY = 'mxl_exception_number';\n/**\n * GLOBAL_CONFIG._MXLFileBundleIDs is populated at runtime when each file is loaded,\n * based on the contents injected by the mxl-web-cli.\n */\nconst getJSFileBundleIDs = () =>\n JSON.stringify(\n GLOBAL_CONFIG._MXLFileBundleIDs ||\n GLOBAL_CONFIG._MXLFileBundleIDs ||\n {},\n );\n\nexport class MXLLogManager implements LogManager {\n private readonly _diag: DiagLogger;\n private readonly _perf: PerformanceManager;\n private readonly _logger: Logger;\n private readonly _spanSessionManager: SpanSessionManagerInternal;\n private readonly _limitManager: LimitManagerInternal;\n private readonly _visibilityDoc: VisibilityStateDocument;\n private readonly _storage: Storage;\n\n public constructor({\n diag: diagParam,\n perf,\n spanSessionManager,\n limitManager,\n loggerProvider: globalLoggerProviderOverride,\n visibilityDoc = window.document,\n storage = window.localStorage,\n }: MXLLogManagerArgs) {\n const loggerProvider = globalLoggerProviderOverride ?? logs;\n\n this._diag =\n diagParam ??\n diag.createComponentLogger({\n namespace: 'MXLLogManager',\n });\n this._perf = perf ?? new OTelPerformanceManager();\n this._logger = loggerProvider.getLogger('mxl-web-sdk-logs');\n this._spanSessionManager = spanSessionManager;\n this._limitManager = limitManager;\n this._visibilityDoc = visibilityDoc;\n this._storage = storage;\n }\n\n private _validateAttributes(attributes: unknown): Attributes {\n if (Object.prototype.toString.call(attributes) !== '[object Object]') {\n this._diag.warn('attributes must be a plain object', attributes);\n return {};\n }\n return attributes as Attributes;\n }\n\n private static _logSeverityToSeverityNumber(\n severity: LogSeverity,\n ): SeverityNumber {\n switch (severity) {\n case 'info':\n return SeverityNumber.INFO;\n case 'warning':\n return SeverityNumber.WARN;\n default:\n return SeverityNumber.ERROR;\n }\n }\n\n public logException(\n error: unknown,\n {\n handled = true,\n attributes = {},\n timestamp = this._perf.getNowMillis(),\n handler = 'manual',\n }: LogExceptionOptions = {},\n ) {\n const validAttrs = this._validateAttributes(attributes);\n\n if (!handled) {\n this._spanSessionManager.incrSessionCountForKey(\n KEY_MXL_UNHANDLED_EXCEPTIONS_COUNT,\n );\n }\n\n const type = error?.constructor?.name || typeof error;\n let errMessage = '';\n let errName = type;\n let errStack = '';\n let errCause = '';\n\n if (error instanceof Error) {\n errMessage = String(error.message || '').trim();\n errName = error.name || '';\n errStack = error.stack || '';\n errCause = error.cause ? 'present' : '';\n } else if (error && typeof error === 'object') {\n try {\n errMessage = JSON.stringify(error);\n } catch {\n errMessage = String(error).trim();\n }\n } else {\n errMessage = String(error).trim();\n }\n\n const limited = this._limitManager.limitException(errMessage, validAttrs);\n if (limited === 'dropped') {\n return;\n }\n\n this._logger.emit({\n timestamp,\n severityNumber: SeverityNumber.ERROR,\n severityText: 'ERROR',\n body: limited.message,\n attributes: {\n ...limited.attributes,\n [KEY_MXL_TYPE]: MXL_TYPES.SystemException,\n [KEY_MXL_EXCEPTION_HANDLING]: MXLLogManager._exceptionHandlingType(\n handled,\n handler,\n ),\n [KEY_MXL_EXCEPTION_CAUSE]: errCause,\n [ATTR_EXCEPTION_TYPE]: type,\n ['exception.name']: errName,\n [ATTR_EXCEPTION_MESSAGE]: limited.message,\n [ATTR_EXCEPTION_STACKTRACE]: errStack,\n [KEY_MXL_JS_FILE_BUNDLE_IDS]: getJSFileBundleIDs(),\n [KEY_MXL_STATE]: getVisibilityState(this._visibilityDoc),\n [KEY_MXL_EXCEPTION_NUMBER]: getIncrementedCount(\n this._storage,\n MXL_EXCEPTION_NUMBER_STORAGE_KEY,\n this._diag,\n ),\n },\n });\n }\n\n public message(\n message: string,\n severity: LogSeverity,\n {\n attributes = {},\n includeStacktrace = true,\n stacktrace,\n }: LogMessageOptions = {},\n ) {\n if (typeof message !== 'string' || !message.trim()) {\n this._diag.warn('Message must be a non-empty string');\n return;\n }\n\n if (!['info', 'warning', 'error'].includes(severity)) {\n this._diag.warn('Severity must be info, warning, or error');\n return;\n }\n\n const validAttrs = this._validateAttributes(attributes);\n\n if (severity === 'error') {\n this._spanSessionManager.incrSessionCountForKey(KEY_MXL_ERROR_LOG_COUNT);\n }\n\n let stack = '';\n if (severity !== 'info') {\n if (typeof stacktrace === 'string') {\n stack = stacktrace;\n } else if (includeStacktrace) {\n stack = new Error().stack || '';\n }\n }\n\n this._logMessage({\n message: message.trim(),\n severity,\n timestamp: this._perf.getNowMillis(),\n attributes: validAttrs,\n stack,\n });\n }\n\n private _logMessage({\n message,\n severity,\n timestamp,\n attributes = {},\n stack,\n }: {\n message: string;\n severity: LogSeverity;\n timestamp: number;\n attributes?: Attributes;\n stack?: string;\n }) {\n const limitedLog = this._limitManager.limitLog(\n message,\n severity,\n attributes,\n );\n\n if (limitedLog === 'dropped') {\n return;\n }\n\n this._logger.emit({\n timestamp,\n severityNumber: MXLLogManager._logSeverityToSeverityNumber(severity),\n severityText: severity.toUpperCase(),\n body: limitedLog.message,\n attributes: {\n ...limitedLog.attributes,\n [KEY_MXL_TYPE]: MXL_TYPES.SystemLog,\n ...(stack\n ? {\n [KEY_MXL_JS_EXCEPTION_STACKTRACE]: stack,\n [KEY_MXL_JS_FILE_BUNDLE_IDS]: getJSFileBundleIDs(),\n }\n : {}),\n [KEY_MXL_STATE]: getVisibilityState(this._visibilityDoc),\n },\n });\n }\n\n private static _exceptionHandlingType(\n handled: boolean,\n handler: ExceptionHandlerType,\n ): string {\n if (handled) {\n return 'handled';\n }\n\n if (handler === 'global_exception') {\n return 'unhandled_error';\n }\n\n if (handler === 'promise_rejection') {\n return 'unhandled_rejection';\n }\n\n return 'unhandled';\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"MXLLogManager.js","names":[],"sources":["../../../src/managers/MXLLogManager/MXLLogManager.ts"],"sourcesContent":["import type { Attributes, DiagLogger } from '@opentelemetry/api';\nimport { diag } from '@opentelemetry/api';\nimport type { Logger } from '@opentelemetry/api-logs';\nimport { logs, SeverityNumber } from '@opentelemetry/api-logs';\nimport {\n ATTR_EXCEPTION_MESSAGE,\n ATTR_EXCEPTION_STACKTRACE,\n ATTR_EXCEPTION_TYPE,\n} from '@opentelemetry/semantic-conventions';\nimport type { LogManager, LogSeverity } from '../../api-logs';\nimport type {\n LogExceptionOptions,\n LogMessageOptions,\n} from '../../api-logs/manager';\nimport type { ExceptionHandlerType } from '../../api-logs/manager/types';\nimport type { VisibilityStateDocument } from '../../common';\nimport {\n KEY_MXL_EXCEPTION_HANDLING,\n KEY_MXL_EXCEPTION_NUMBER,\n KEY_MXL_JS_EXCEPTION_STACKTRACE,\n KEY_MXL_STATE,\n KEY_MXL_TYPE,\n MXL_TYPES,\n} from '../../constants';\nimport {\n KEY_MXL_ERROR_LOG_COUNT,\n KEY_MXL_EXCEPTION_CAUSE,\n KEY_MXL_JS_FILE_BUNDLE_IDS,\n KEY_MXL_UNHANDLED_EXCEPTIONS_COUNT,\n} from '../../constants/attributes';\nimport type { PerformanceManager } from '../../utils';\nimport {\n GLOBAL_CONFIG,\n getIncrementedCount,\n getVisibilityState,\n OTelPerformanceManager,\n} from '../../utils';\nimport type { LimitManagerInternal } from '../MXLLimitManager';\nimport type { SpanSessionManagerInternal } from '../MXLSpanSessionManager';\nimport type { MXLLogManagerArgs } from './types';\n\nconst MXL_EXCEPTION_NUMBER_STORAGE_KEY = 'mxl_exception_number';\n/**\n * GLOBAL_CONFIG._MXLFileBundleIDs is populated at runtime when each file is loaded,\n * based on the contents injected by the mxl-web-cli.\n */\nconst getJSFileBundleIDs = () =>\n JSON.stringify(\n GLOBAL_CONFIG._MXLFileBundleIDs || GLOBAL_CONFIG._MXLFileBundleIDs || {},\n );\n\nexport class MXLLogManager implements LogManager {\n private readonly _diag: DiagLogger;\n private readonly _perf: PerformanceManager;\n private readonly _logger: Logger;\n private readonly _spanSessionManager: SpanSessionManagerInternal;\n private readonly _limitManager: LimitManagerInternal;\n private readonly _visibilityDoc: VisibilityStateDocument;\n private readonly _storage: Storage;\n\n public constructor({\n diag: diagParam,\n perf,\n spanSessionManager,\n limitManager,\n loggerProvider: globalLoggerProviderOverride,\n visibilityDoc = window.document,\n storage = window.localStorage,\n }: MXLLogManagerArgs) {\n const loggerProvider = globalLoggerProviderOverride ?? logs;\n\n this._diag =\n diagParam ??\n diag.createComponentLogger({\n namespace: 'MXLLogManager',\n });\n this._perf = perf ?? new OTelPerformanceManager();\n this._logger = loggerProvider.getLogger('mxl-web-sdk-logs');\n this._spanSessionManager = spanSessionManager;\n this._limitManager = limitManager;\n this._visibilityDoc = visibilityDoc;\n this._storage = storage;\n }\n\n private _validateAttributes(attributes: unknown): Attributes {\n if (Object.prototype.toString.call(attributes) !== '[object Object]') {\n this._diag.warn('attributes must be a plain object', attributes);\n return {};\n }\n return attributes as Attributes;\n }\n\n private static _logSeverityToSeverityNumber(\n severity: LogSeverity,\n ): SeverityNumber {\n switch (severity) {\n case 'info':\n return SeverityNumber.INFO;\n case 'warning':\n return SeverityNumber.WARN;\n default:\n return SeverityNumber.ERROR;\n }\n }\n\n public logException(\n error: unknown,\n {\n handled = true,\n attributes = {},\n timestamp = this._perf.getNowMillis(),\n handler = 'manual',\n }: LogExceptionOptions = {},\n ) {\n const validAttrs = this._validateAttributes(attributes);\n\n if (!handled) {\n this._spanSessionManager.incrSessionCountForKey(\n KEY_MXL_UNHANDLED_EXCEPTIONS_COUNT,\n );\n }\n\n const type = error?.constructor?.name || typeof error;\n let errMessage = '';\n let errName = type;\n let errStack = '';\n let errCause = '';\n\n if (error instanceof Error) {\n errMessage = String(error.message || '').trim();\n errName = error.name || '';\n errStack = error.stack || '';\n errCause = error.cause ? 'present' : '';\n } else if (error && typeof error === 'object') {\n try {\n errMessage = JSON.stringify(error);\n } catch {\n errMessage = String(error).trim();\n }\n } else {\n errMessage = String(error).trim();\n }\n\n const limited = this._limitManager.limitException(errMessage, validAttrs);\n if (limited === 'dropped') {\n return;\n }\n\n this._logger.emit({\n timestamp,\n severityNumber: SeverityNumber.ERROR,\n severityText: 'ERROR',\n body: limited.message,\n attributes: {\n ...limited.attributes,\n [KEY_MXL_TYPE]: MXL_TYPES.SystemException,\n [KEY_MXL_EXCEPTION_HANDLING]: MXLLogManager._exceptionHandlingType(\n handled,\n handler,\n ),\n [KEY_MXL_EXCEPTION_CAUSE]: errCause,\n [ATTR_EXCEPTION_TYPE]: type,\n ['exception.name']: errName,\n [ATTR_EXCEPTION_MESSAGE]: limited.message,\n [ATTR_EXCEPTION_STACKTRACE]: errStack,\n [KEY_MXL_JS_FILE_BUNDLE_IDS]: getJSFileBundleIDs(),\n [KEY_MXL_STATE]: getVisibilityState(this._visibilityDoc),\n [KEY_MXL_EXCEPTION_NUMBER]: getIncrementedCount(\n this._storage,\n MXL_EXCEPTION_NUMBER_STORAGE_KEY,\n this._diag,\n ),\n },\n });\n }\n\n public message(\n message: string,\n severity: LogSeverity,\n {\n attributes = {},\n includeStacktrace = true,\n stacktrace,\n }: LogMessageOptions = {},\n ) {\n if (typeof message !== 'string' || !message.trim()) {\n this._diag.warn('Message must be a non-empty string');\n return;\n }\n\n if (!['info', 'warning', 'error'].includes(severity)) {\n this._diag.warn('Severity must be info, warning, or error');\n return;\n }\n\n const validAttrs = this._validateAttributes(attributes);\n\n if (severity === 'error') {\n this._spanSessionManager.incrSessionCountForKey(KEY_MXL_ERROR_LOG_COUNT);\n }\n\n let stack = '';\n if (severity !== 'info') {\n if (typeof stacktrace === 'string') {\n stack = stacktrace;\n } else if (includeStacktrace) {\n stack = new Error().stack || '';\n }\n }\n\n this._logMessage({\n message: message.trim(),\n severity,\n timestamp: this._perf.getNowMillis(),\n attributes: validAttrs,\n stack,\n });\n }\n\n private _logMessage({\n message,\n severity,\n timestamp,\n attributes = {},\n stack,\n }: {\n message: string;\n severity: LogSeverity;\n timestamp: number;\n attributes?: Attributes;\n stack?: string;\n }) {\n const limitedLog = this._limitManager.limitLog(\n message,\n severity,\n attributes,\n );\n\n if (limitedLog === 'dropped') {\n return;\n }\n\n this._logger.emit({\n timestamp,\n severityNumber: MXLLogManager._logSeverityToSeverityNumber(severity),\n severityText: severity.toUpperCase(),\n body: limitedLog.message,\n attributes: {\n ...limitedLog.attributes,\n [KEY_MXL_TYPE]: MXL_TYPES.SystemLog,\n ...(stack\n ? {\n [KEY_MXL_JS_EXCEPTION_STACKTRACE]: stack,\n [KEY_MXL_JS_FILE_BUNDLE_IDS]: getJSFileBundleIDs(),\n }\n : {}),\n [KEY_MXL_STATE]: getVisibilityState(this._visibilityDoc),\n },\n });\n }\n\n private static _exceptionHandlingType(\n handled: boolean,\n handler: ExceptionHandlerType,\n ): string {\n if (handled) {\n return 'handled';\n }\n\n if (handler === 'global_exception') {\n return 'unhandled_error';\n }\n\n if (handler === 'promise_rejection') {\n return 'unhandled_rejection';\n }\n\n return 'unhandled';\n }\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MXLPageManager.cjs","names":["generateUUID"],"sources":["../../../src/managers/MXLPageManager/MXLPageManager.ts"],"sourcesContent":["import type { PageManager, Route } from '../../api-page
|
|
1
|
+
{"version":3,"file":"MXLPageManager.cjs","names":["generateUUID"],"sources":["../../../src/managers/MXLPageManager/MXLPageManager.ts"],"sourcesContent":["import type { PageManager, Route } from '../../api-page';\nimport type { TitleDocument } from '../../common';\nimport { generateUUID } from '../../utils';\nimport type { MXLPageManagerArgs } from './types';\n\nexport class MXLPageManager implements PageManager {\n private _currentRoute: Route | null = null;\n private _currentPageId: string | null = null;\n private _pageLabel: string | null = null;\n private readonly _titleDocument: TitleDocument | undefined;\n private readonly _useDocumentTitleAsPageLabel: boolean;\n\n public constructor({\n useDocumentTitleAsPageLabel = true,\n titleDocument = window.document,\n }: MXLPageManagerArgs = {}) {\n this._useDocumentTitleAsPageLabel = useDocumentTitleAsPageLabel;\n this._titleDocument = titleDocument;\n }\n\n public getCurrentPageId = (): string | null => this._currentPageId;\n\n public getCurrentRoute = () => this._currentRoute;\n\n public setPageLabel = (label: string): void => {\n this._pageLabel = label;\n };\n\n public getPageLabel = (): string | null => {\n return (\n this._pageLabel ||\n (!this._useDocumentTitleAsPageLabel || !this._titleDocument\n ? null\n : this._titleDocument.title)\n );\n };\n\n public setCurrentRoute = (route: Route) => {\n if (!this._currentRoute || this._currentRoute.url !== route.url) {\n this._currentPageId = generateUUID();\n }\n\n this._currentRoute = route;\n\n if (route.label) {\n this._pageLabel = route.label;\n } else {\n this._pageLabel = null;\n }\n };\n\n public clearCurrentRoute = () => {\n this._currentRoute = null;\n this._currentPageId = null;\n this._pageLabel = null;\n };\n}\n"],"mappings":";;;AAKA,IAAa,iBAAb,MAAmD;CACjD,gBAAsC;CACtC,iBAAwC;CACxC,aAAoC;CACpC;CACA;CAEA,YAAmB,EACjB,8BAA8B,MAC9B,gBAAgB,OAAO,aACD,EAAE,EAAE;AAC1B,OAAK,+BAA+B;AACpC,OAAK,iBAAiB;;CAGxB,yBAA+C,KAAK;CAEpD,wBAA+B,KAAK;CAEpC,gBAAuB,UAAwB;AAC7C,OAAK,aAAa;;CAGpB,qBAA2C;AACzC,SACE,KAAK,eACJ,CAAC,KAAK,gCAAgC,CAAC,KAAK,iBACzC,OACA,KAAK,eAAe;;CAI5B,mBAA0B,UAAiB;AACzC,MAAI,CAAC,KAAK,iBAAiB,KAAK,cAAc,QAAQ,MAAM,IAC1D,MAAK,iBAAiBA,2BAAAA,cAAc;AAGtC,OAAK,gBAAgB;AAErB,MAAI,MAAM,MACR,MAAK,aAAa,MAAM;MAExB,MAAK,aAAa;;CAItB,0BAAiC;AAC/B,OAAK,gBAAgB;AACrB,OAAK,iBAAiB;AACtB,OAAK,aAAa"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MXLPageManager.js","names":[],"sources":["../../../src/managers/MXLPageManager/MXLPageManager.ts"],"sourcesContent":["import type { PageManager, Route } from '../../api-page
|
|
1
|
+
{"version":3,"file":"MXLPageManager.js","names":[],"sources":["../../../src/managers/MXLPageManager/MXLPageManager.ts"],"sourcesContent":["import type { PageManager, Route } from '../../api-page';\nimport type { TitleDocument } from '../../common';\nimport { generateUUID } from '../../utils';\nimport type { MXLPageManagerArgs } from './types';\n\nexport class MXLPageManager implements PageManager {\n private _currentRoute: Route | null = null;\n private _currentPageId: string | null = null;\n private _pageLabel: string | null = null;\n private readonly _titleDocument: TitleDocument | undefined;\n private readonly _useDocumentTitleAsPageLabel: boolean;\n\n public constructor({\n useDocumentTitleAsPageLabel = true,\n titleDocument = window.document,\n }: MXLPageManagerArgs = {}) {\n this._useDocumentTitleAsPageLabel = useDocumentTitleAsPageLabel;\n this._titleDocument = titleDocument;\n }\n\n public getCurrentPageId = (): string | null => this._currentPageId;\n\n public getCurrentRoute = () => this._currentRoute;\n\n public setPageLabel = (label: string): void => {\n this._pageLabel = label;\n };\n\n public getPageLabel = (): string | null => {\n return (\n this._pageLabel ||\n (!this._useDocumentTitleAsPageLabel || !this._titleDocument\n ? null\n : this._titleDocument.title)\n );\n };\n\n public setCurrentRoute = (route: Route) => {\n if (!this._currentRoute || this._currentRoute.url !== route.url) {\n this._currentPageId = generateUUID();\n }\n\n this._currentRoute = route;\n\n if (route.label) {\n this._pageLabel = route.label;\n } else {\n this._pageLabel = null;\n }\n };\n\n public clearCurrentRoute = () => {\n this._currentRoute = null;\n this._currentPageId = null;\n this._pageLabel = null;\n };\n}\n"],"mappings":";;AAKA,IAAa,iBAAb,MAAmD;CACjD,gBAAsC;CACtC,iBAAwC;CACxC,aAAoC;CACpC;CACA;CAEA,YAAmB,EACjB,8BAA8B,MAC9B,gBAAgB,OAAO,aACD,EAAE,EAAE;AAC1B,OAAK,+BAA+B;AACpC,OAAK,iBAAiB;;CAGxB,yBAA+C,KAAK;CAEpD,wBAA+B,KAAK;CAEpC,gBAAuB,UAAwB;AAC7C,OAAK,aAAa;;CAGpB,qBAA2C;AACzC,SACE,KAAK,eACJ,CAAC,KAAK,gCAAgC,CAAC,KAAK,iBACzC,OACA,KAAK,eAAe;;CAI5B,mBAA0B,UAAiB;AACzC,MAAI,CAAC,KAAK,iBAAiB,KAAK,cAAc,QAAQ,MAAM,IAC1D,MAAK,iBAAiB,cAAc;AAGtC,OAAK,gBAAgB;AAErB,MAAI,MAAM,MACR,MAAK,aAAa,MAAM;MAExB,MAAK,aAAa;;CAItB,0BAAiC;AAC/B,OAAK,gBAAgB;AACrB,OAAK,iBAAiB;AACtB,OAAK,aAAa"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MXLSDKFeaturesManager.cjs","names":["isDeviceIdEnabled"],"sources":["../../../src/managers/MXLSDKFeaturesManager/MXLSDKFeaturesManager.ts"],"sourcesContent":["import type { DynamicConfigManager } from '../../sdk
|
|
1
|
+
{"version":3,"file":"MXLSDKFeaturesManager.cjs","names":["isDeviceIdEnabled"],"sources":["../../../src/managers/MXLSDKFeaturesManager/MXLSDKFeaturesManager.ts"],"sourcesContent":["import type { DynamicConfigManager } from '../../sdk';\nimport { isDeviceIdEnabled } from '../../utils';\nimport type { SDKFeaturesManager, SDKFeaturesManagerArgs } from './types';\n\nexport class MXLSDKFeaturesManager implements SDKFeaturesManager {\n private readonly _dynamicConfigManager: DynamicConfigManager;\n private readonly _deviceId: string;\n private readonly _blockNetworkSpanForwarding: boolean;\n\n public constructor({\n dynamicConfigManager,\n deviceId,\n blockNetworkSpanForwarding,\n }: SDKFeaturesManagerArgs) {\n this._dynamicConfigManager = dynamicConfigManager;\n this._deviceId = deviceId;\n this._blockNetworkSpanForwarding = blockNetworkSpanForwarding;\n }\n\n public isSDKEnabled(): boolean {\n const config = this._dynamicConfigManager.getConfig();\n\n return isDeviceIdEnabled(this._deviceId, config.samplingPct);\n }\n\n public isNetworkSpanForwardingEnabled(): boolean {\n if (this._blockNetworkSpanForwarding) {\n return false;\n }\n\n const config = this._dynamicConfigManager.getConfig();\n\n return isDeviceIdEnabled(\n this._deviceId,\n config.networkSpansForwardingThreshold,\n );\n }\n\n public isEmptySessionAvoidanceEnabled(): boolean {\n const config = this._dynamicConfigManager.getConfig();\n\n return isDeviceIdEnabled(\n this._deviceId,\n config.emptySessionAvoidanceEnabledPct,\n );\n }\n}\n"],"mappings":";;;AAIA,IAAa,wBAAb,MAAiE;CAC/D;CACA;CACA;CAEA,YAAmB,EACjB,sBACA,UACA,8BACyB;AACzB,OAAK,wBAAwB;AAC7B,OAAK,YAAY;AACjB,OAAK,8BAA8B;;CAGrC,eAA+B;EAC7B,MAAM,SAAS,KAAK,sBAAsB,WAAW;AAErD,SAAOA,gCAAAA,kBAAkB,KAAK,WAAW,OAAO,YAAY;;CAG9D,iCAAiD;AAC/C,MAAI,KAAK,4BACP,QAAO;EAGT,MAAM,SAAS,KAAK,sBAAsB,WAAW;AAErD,SAAOA,gCAAAA,kBACL,KAAK,WACL,OAAO,gCACR;;CAGH,iCAAiD;EAC/C,MAAM,SAAS,KAAK,sBAAsB,WAAW;AAErD,SAAOA,gCAAAA,kBACL,KAAK,WACL,OAAO,gCACR"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MXLSDKFeaturesManager.js","names":[],"sources":["../../../src/managers/MXLSDKFeaturesManager/MXLSDKFeaturesManager.ts"],"sourcesContent":["import type { DynamicConfigManager } from '../../sdk
|
|
1
|
+
{"version":3,"file":"MXLSDKFeaturesManager.js","names":[],"sources":["../../../src/managers/MXLSDKFeaturesManager/MXLSDKFeaturesManager.ts"],"sourcesContent":["import type { DynamicConfigManager } from '../../sdk';\nimport { isDeviceIdEnabled } from '../../utils';\nimport type { SDKFeaturesManager, SDKFeaturesManagerArgs } from './types';\n\nexport class MXLSDKFeaturesManager implements SDKFeaturesManager {\n private readonly _dynamicConfigManager: DynamicConfigManager;\n private readonly _deviceId: string;\n private readonly _blockNetworkSpanForwarding: boolean;\n\n public constructor({\n dynamicConfigManager,\n deviceId,\n blockNetworkSpanForwarding,\n }: SDKFeaturesManagerArgs) {\n this._dynamicConfigManager = dynamicConfigManager;\n this._deviceId = deviceId;\n this._blockNetworkSpanForwarding = blockNetworkSpanForwarding;\n }\n\n public isSDKEnabled(): boolean {\n const config = this._dynamicConfigManager.getConfig();\n\n return isDeviceIdEnabled(this._deviceId, config.samplingPct);\n }\n\n public isNetworkSpanForwardingEnabled(): boolean {\n if (this._blockNetworkSpanForwarding) {\n return false;\n }\n\n const config = this._dynamicConfigManager.getConfig();\n\n return isDeviceIdEnabled(\n this._deviceId,\n config.networkSpansForwardingThreshold,\n );\n }\n\n public isEmptySessionAvoidanceEnabled(): boolean {\n const config = this._dynamicConfigManager.getConfig();\n\n return isDeviceIdEnabled(\n this._deviceId,\n config.emptySessionAvoidanceEnabledPct,\n );\n }\n}\n"],"mappings":";;AAIA,IAAa,wBAAb,MAAiE;CAC/D;CACA;CACA;CAEA,YAAmB,EACjB,sBACA,UACA,8BACyB;AACzB,OAAK,wBAAwB;AAC7B,OAAK,YAAY;AACjB,OAAK,8BAA8B;;CAGrC,eAA+B;EAC7B,MAAM,SAAS,KAAK,sBAAsB,WAAW;AAErD,SAAO,kBAAkB,KAAK,WAAW,OAAO,YAAY;;CAG9D,iCAAiD;AAC/C,MAAI,KAAK,4BACP,QAAO;EAGT,MAAM,SAAS,KAAK,sBAAsB,WAAW;AAErD,SAAO,kBACL,KAAK,WACL,OAAO,gCACR;;CAGH,iCAAiD;EAC/C,MAAM,SAAS,KAAK,sBAAsB,WAAW;AAErD,SAAO,kBACL,KAAK,WACL,OAAO,gCACR"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MXLSpanSessionManager.cjs","names":["diag","OTelPerformanceManager","trace","BasicTracerProvider","KEY_PREFIX_MXL_PROPERTIES","KEY_MXL_SESSION_REASON_ENDED","KEY_MXL_SDK_STARTUP_DURATION","KEY_MXL_FROM_STORAGE","generateUUID","KEY_MXL_TYPE","KEY_MXL_STATE","getVisibilityState","ATTR_SESSION_ID","KEY_MXL_COLD_START","KEY_MXL_SESSION_NUMBER","getIncrementedCount","MXL_SESSION_NUMBER_STORAGE_KEY","KEY_MXL_EXPERIENCE_ID","KEY_MXL_TAB_ID","KEY_MXL_NAVIGATION_SOURCE","KEY_MXL_REFERRER_URL","KEY_MXL_SOURCE_TAB_ID","KEY_MXL_SESSION_REASON_STARTED","MXLExtendedSpan","getAppInstanceId","MXL_TAB_STORAGE_KEY","MXL_TAB_ACTIVITY_STORAGE_KEY"],"sources":["../../../src/managers/MXLSpanSessionManager/MXLSpanSessionManager.ts"],"sourcesContent":["import type {\n Attributes,\n DiagLogger,\n HrTime,\n Tracer,\n TracerProvider,\n} from '@opentelemetry/api';\nimport { diag, trace } from '@opentelemetry/api';\nimport type { ReadableSpan } from '@opentelemetry/sdk-trace-web';\nimport { BasicTracerProvider } from '@opentelemetry/sdk-trace-web';\nimport { ATTR_SESSION_ID } from '@opentelemetry/semantic-conventions/incubating';\nimport type {\n PropertyOptions,\n ReasonSessionEnded,\n StartSessionOptions,\n} from '../../api-sessions/index.ts';\nimport type { VisibilityStateDocument } from '../../common/index.ts';\nimport {\n KEY_MXL_COLD_START,\n KEY_MXL_EXPERIENCE_ID,\n KEY_MXL_FROM_STORAGE,\n KEY_MXL_NAVIGATION_SOURCE,\n KEY_MXL_REFERRER_URL,\n KEY_MXL_SDK_STARTUP_DURATION,\n KEY_MXL_SESSION_NUMBER,\n KEY_MXL_SESSION_REASON_ENDED,\n KEY_MXL_SESSION_REASON_STARTED,\n KEY_MXL_SOURCE_TAB_ID,\n KEY_MXL_STATE,\n KEY_MXL_TAB_ID,\n KEY_MXL_TYPE,\n KEY_PREFIX_MXL_PROPERTIES,\n MXL_TYPES,\n} from '../../constants/index.ts';\nimport type { ExtendedSpan } from '../../index.ts';\nimport { getAppInstanceId } from '../../resources/index.ts';\nimport type { PerformanceManager } from '../../utils/index.ts';\nimport {\n generateUUID,\n getIncrementedCount,\n getVisibilityState,\n OTelPerformanceManager,\n} from '../../utils/index.ts';\nimport type { LimitManagerInternal } from '../MXLLimitManager/index.ts';\nimport { MXLExtendedSpan } from '../MXLTraceManager/MXLExtendedSpan.ts';\nimport {\n MXL_SESSION_NUMBER_STORAGE_KEY,\n MXL_TAB_ACTIVITY_STORAGE_KEY,\n MXL_TAB_STORAGE_KEY,\n} from './constants.ts';\nimport type {\n MXLSpanSessionManagerArgs,\n NavigationSource,\n SessionEndedListener,\n SessionStartedListener,\n SpanSessionManagerInternal,\n Tab,\n TabActivity,\n} from './types.ts';\n\nexport class MXLSpanSessionManager implements SpanSessionManagerInternal {\n private _previousSessionId: string | null = null;\n private _activeSessionId: string | null = null;\n private _activeSessionStartTime: HrTime | null = null;\n private _sessionSpan: ExtendedSpan | null = null;\n private _activeSessionCounts: Record<string, number> | null = null;\n private _nextSessionCounts: Record<string, number> = {};\n private _coldStart = true; // Whether the session was started from a new page load or not.\n private _sdkStartupDuration = 0;\n private readonly _sessionStartedListeners: Array<SessionStartedListener> = [];\n private readonly _sessionEndedListeners: Array<SessionEndedListener> = [];\n private readonly _tab: Tab;\n private readonly _navigationSource: NavigationSource;\n private readonly _referrerInfo: {\n isValid: boolean;\n isSameOrigin: boolean;\n scrubbedUrl?: string;\n };\n\n private _tracer: Tracer;\n private readonly _noExportTracer: Tracer;\n private readonly _diag: DiagLogger;\n private readonly _perf: PerformanceManager;\n private readonly _visibilityDoc: VisibilityStateDocument;\n private readonly _storage: Storage;\n private readonly _sessionStorage: Storage;\n private readonly _limitManager: LimitManagerInternal;\n private readonly _referrer: string;\n private readonly _navigationPerformance: Pick<Performance, 'getEntriesByType'>;\n\n public constructor({\n diag: diagParam,\n perf,\n visibilityDoc = window.document,\n storage = window.localStorage,\n sessionStorage = window.sessionStorage,\n limitManager,\n referrer = document.referrer,\n navigationPerformance = window.performance,\n }: MXLSpanSessionManagerArgs) {\n this._diag =\n diagParam ??\n diag.createComponentLogger({\n namespace: 'MXLSpanSessionManager',\n });\n this._perf = perf ?? new OTelPerformanceManager();\n this._visibilityDoc = visibilityDoc;\n this._storage = storage;\n this._sessionStorage = sessionStorage;\n this._limitManager = limitManager;\n this._referrer = referrer;\n this._navigationPerformance = navigationPerformance;\n this._tracer = trace.getTracer('mxl-web-sdk-sessions');\n this._noExportTracer = new BasicTracerProvider().getTracer(\n 'mxl-web-sdk-sessions',\n );\n\n // Process referrer once at initialization\n this._referrerInfo = this._processReferrer();\n\n // Initialize tab tracking and navigation source\n const initResult = this._initTab();\n this._tab = initResult.tab;\n this._navigationSource = initResult.navigationSource;\n this._setupNewTabClickListeners();\n }\n\n // Collects all permanent session properties from localStorage\n private _getPermanentAttributes(): Attributes {\n const permanentAttributes = new Map();\n try {\n for (let i = 0; i < this._storage.length; i++) {\n const key = this._storage.key(i);\n if (key?.startsWith(KEY_PREFIX_MXL_PROPERTIES)) {\n const value = this._storage.getItem(key);\n if (value) {\n permanentAttributes.set(key, value);\n }\n }\n }\n } catch (error) {\n this._diag.warn('Error loading permanent session properties', error);\n }\n return Object.fromEntries(permanentAttributes.entries()) as Attributes;\n }\n\n public addBreadcrumb(name: string) {\n if (!this._sessionSpan) {\n this._diag.debug(\n 'trying to add breadcrumb to a session, but there is no session in progress. This is a no-op.',\n );\n return;\n }\n\n const limitedBreadcrumb = this._limitManager.limitBreadcrumb(name);\n\n if (limitedBreadcrumb === 'dropped') {\n return;\n }\n\n this._sessionSpan.addEvent(\n 'mxl-breadcrumb',\n {\n message: limitedBreadcrumb.name,\n },\n this._perf.getNowMillis(),\n );\n }\n\n public addProperty(\n propertyKey: string,\n value: string,\n options?: PropertyOptions,\n ) {\n if (!this._sessionSpan) {\n this._diag.debug(\n 'trying to add properties to a session, but there is no session in progress. This is a no-op.',\n );\n return;\n }\n\n const limitedSessionProperty = this._limitManager.limitSessionProperty(\n propertyKey,\n value,\n );\n\n if (limitedSessionProperty === 'dropped') {\n return;\n }\n\n const attributeKey = KEY_PREFIX_MXL_PROPERTIES + limitedSessionProperty.key;\n this._sessionSpan.setAttribute(attributeKey, limitedSessionProperty.value);\n\n if (options?.lifespan === 'permanent') {\n try {\n this._storage.setItem(attributeKey, value);\n } catch (error) {\n this._diag.warn('Failed to set permanent session property', error);\n }\n }\n }\n\n public removeProperty(propertyKey: string) {\n if (!this._sessionSpan) {\n this._diag.debug(\n 'trying to remove a session property, but there is no session in progress. This is a no-op.',\n );\n return;\n }\n\n // We truncate long session property keys on addProperty so need to apply the same logic here\n const attributeKey =\n KEY_PREFIX_MXL_PROPERTIES +\n this._limitManager.truncateString('session_property_key', propertyKey);\n this._sessionSpan.removeAttribute(attributeKey);\n\n try {\n if (this._storage.getItem(attributeKey)) {\n this._storage.removeItem(attributeKey);\n }\n } catch (error) {\n this._diag.warn('Error removing permanent session property', error);\n }\n }\n\n // the external api doesn't include a reason, and if a users uses it to end a session, the reason will be 'manual'\n // note: don't use this internally, this is just for user facing APIs. Use this.endSessionSpanInternal instead.\n public endSessionSpan() {\n this.endSessionSpanInternal('manual');\n }\n\n // endSessionSpanInternal is not part of the public API, but is used internally to end a session span adding a specific reason\n public endSessionSpanInternal(reason: ReasonSessionEnded) {\n if (!this._sessionSpan) {\n this._diag.debug(\n 'trying to end a session, but there is no session in progress. This is a no-op.',\n );\n return;\n }\n\n for (const listener of this._sessionEndedListeners) {\n try {\n listener();\n } catch (error) {\n this._diag.warn('Error while executing session ended listener', error);\n }\n }\n\n this._sessionSpan.setAttributes(this._endSessionSpanAttributes(reason));\n this._sessionSpan.end();\n this._sessionSpan = null;\n this._activeSessionStartTime = null;\n this._previousSessionId = this._activeSessionId;\n this._activeSessionId = null;\n this._activeSessionCounts = null;\n\n // For the limit manager to add a session ended listener it would need a reference to this\n // session manager which would create a circular dependency\n this._limitManager.reset();\n }\n\n private _endSessionSpanAttributes(reason: ReasonSessionEnded): Attributes {\n return {\n ...this._getPermanentAttributes(),\n [KEY_MXL_SESSION_REASON_ENDED]: reason,\n ...this._activeSessionCounts,\n ...this._limitManager.getDiagnosticCounts(),\n [KEY_MXL_SDK_STARTUP_DURATION]: this._sdkStartupDuration,\n };\n }\n\n // currentSessionAsReadableSpan creates a copy of the current session span with the same attributes\n // that endSessionSpanInternal would add, but does not affect the original session span which remains active.\n public currentSessionAsReadableSpan(\n reason: ReasonSessionEnded,\n ): ReadableSpan | null {\n if (!this._sessionSpan || !this._activeSessionStartTime) {\n this._diag.debug(\n 'trying to end a session, but there is no session in progress. This is a no-op.',\n );\n return null;\n }\n\n // Create a new span with the same name and start time as the original session span,\n // but using a new tracer so that it does not get exported.\n const span = this._noExportTracer.startSpan('mxl-session', {\n startTime: this._activeSessionStartTime,\n attributes: {\n // Copy all current attributes from the original session span, plus the ending attributes\n ...this._sessionSpan.attributes,\n ...this._endSessionSpanAttributes(reason),\n [KEY_MXL_FROM_STORAGE]: true,\n },\n });\n span.end();\n return span as unknown as ReadableSpan;\n }\n\n public getSessionId(): string | null {\n return this._activeSessionId;\n }\n\n public getPreviousSessionId(): string | null {\n return this._previousSessionId;\n }\n\n public getSessionSpan(): ExtendedSpan | null {\n return this._sessionSpan;\n }\n\n public getSessionStartTime(): HrTime | null {\n return this._activeSessionStartTime;\n }\n\n public startSessionSpan(options?: StartSessionOptions) {\n // if there is a session already in progress, end it first\n if (this._sessionSpan) {\n this.endSessionSpanInternal('manual');\n }\n\n this._activeSessionId = generateUUID();\n this._activeSessionStartTime = this._perf.getNowHRTime();\n this._activeSessionCounts = {};\n const previouslyRecordedCounts = this._nextSessionCounts;\n this._nextSessionCounts = {};\n\n const attributes: Attributes = {\n ...this._getPermanentAttributes(),\n [KEY_MXL_TYPE]: MXL_TYPES.Session,\n [KEY_MXL_STATE]: getVisibilityState(this._visibilityDoc),\n [ATTR_SESSION_ID]: this._activeSessionId,\n [KEY_MXL_COLD_START]: this._coldStart,\n [KEY_MXL_SESSION_NUMBER]: getIncrementedCount(\n this._storage,\n MXL_SESSION_NUMBER_STORAGE_KEY,\n this._diag,\n ),\n [KEY_MXL_EXPERIENCE_ID]: this._tab.experienceId,\n [KEY_MXL_TAB_ID]: this._tab.tabId,\n [KEY_MXL_NAVIGATION_SOURCE]: this._navigationSource,\n ...previouslyRecordedCounts,\n };\n\n // Add scrubbed referrer URL if available\n if (this._referrerInfo.isValid && this._referrerInfo.scrubbedUrl) {\n attributes[KEY_MXL_REFERRER_URL] = this._referrerInfo.scrubbedUrl;\n }\n\n if (this._tab.sourceTabId) {\n attributes[KEY_MXL_SOURCE_TAB_ID] = this._tab.sourceTabId;\n }\n\n const sessionStartReason = options?.reason ?? 'manual';\n attributes[KEY_MXL_SESSION_REASON_STARTED] = sessionStartReason;\n\n this._sessionSpan = new MXLExtendedSpan(\n this._tracer.startSpan('mxl-session', {\n attributes,\n }),\n );\n\n this._coldStart = false;\n\n for (const listener of this._sessionStartedListeners) {\n try {\n listener();\n } catch (error) {\n this._diag.warn(\n 'Error while executing session started listener',\n error,\n );\n }\n }\n }\n\n public incrSessionCountForKey(key: string) {\n if (!this._sessionSpan || !this._activeSessionCounts) {\n this._diag.debug(\n 'trying to increment a count for the active session, but there is no session in progress. This is a no-op.',\n );\n return;\n }\n\n this._activeSessionCounts[key] = (this._activeSessionCounts[key] || 0) + 1;\n }\n\n public incrNextSessionCountForKey(key: string) {\n this._nextSessionCounts[key] = (this._nextSessionCounts[key] || 0) + 1;\n }\n\n public addSessionStartedListener(listener: SessionStartedListener) {\n const listenerIndex = this._sessionStartedListeners.push(listener);\n\n return () => {\n this._sessionStartedListeners.splice(listenerIndex - 1, 1);\n };\n }\n\n public addSessionEndedListener(listener: SessionEndedListener) {\n const listenerIndex = this._sessionEndedListeners.push(listener);\n\n return () => {\n this._sessionEndedListeners.splice(listenerIndex - 1, 1);\n };\n }\n\n public recordSDKStartupDuration(duration: number) {\n this._sdkStartupDuration = Math.ceil(duration);\n }\n\n public setTracerProvider(tracerProvider: TracerProvider) {\n this._tracer = tracerProvider.getTracer('mxl-web-sdk-sessions');\n }\n\n private _determineNavigationSource(): NavigationSource {\n // Check Navigation Timing API first\n try {\n const navEntries =\n this._navigationPerformance.getEntriesByType('navigation');\n if (navEntries.length > 0 && navEntries[0]) {\n const navEntry = navEntries[0];\n if (navEntry.type === 'reload') {\n return 'reload';\n } else if (navEntry.type === 'back_forward') {\n return 'back_forward';\n }\n }\n } catch (error) {\n this._diag.warn('Failed to get navigation type', error);\n }\n\n // If not reload/back_forward, analyze referrer\n if (this._referrerInfo.isValid) {\n return this._referrerInfo.isSameOrigin ? 'same_origin' : 'external';\n }\n\n return 'direct';\n }\n\n private _processReferrer(): {\n isValid: boolean;\n isSameOrigin: boolean;\n scrubbedUrl?: string;\n } {\n if (!this._referrer) {\n return { isValid: false, isSameOrigin: false };\n }\n\n try {\n const referrerUrl = new URL(this._referrer);\n const currentOrigin = window.location.origin;\n\n return {\n isValid: true,\n isSameOrigin: referrerUrl.origin === currentOrigin,\n scrubbedUrl: referrerUrl.origin + referrerUrl.pathname,\n };\n } catch {\n return { isValid: false, isSameOrigin: false };\n }\n }\n\n private _getTabContext(navigationSource: NavigationSource): {\n sourceTabId?: string;\n experienceId: string;\n tabId: string;\n } {\n // Always use getAppInstanceId to ensure consistent tab ID\n const tabId = getAppInstanceId(this._sessionStorage, this._diag);\n\n // Look for source tab only if navigation is from same origin\n let sourceTabId: string | undefined;\n let experienceId: string | undefined;\n\n if (navigationSource === 'same_origin') {\n const lastActivity = this._getTabActivity();\n if (lastActivity) {\n const age = Date.now() - lastActivity.lastActivityMs;\n // 10 second window to detect source tabs - balances capturing legitimate\n // tab relationships while avoiding false positives from stale activity\n if (age <= 10_000) {\n sourceTabId = lastActivity.tabId;\n experienceId = lastActivity.experienceId;\n }\n }\n }\n\n // Only generate new UUID if we didn't inherit one from source tab\n experienceId ??= generateUUID();\n\n return {\n sourceTabId,\n experienceId,\n tabId,\n };\n }\n\n private _initTab(): { tab: Tab; navigationSource: NavigationSource } {\n // Determine navigation source once at startup\n const navigationSource = this._determineNavigationSource();\n\n // On page reload, preserve the same tab IDs\n try {\n const stored = this._sessionStorage.getItem(MXL_TAB_STORAGE_KEY);\n if (stored) {\n return {\n tab: JSON.parse(stored) as Tab,\n navigationSource,\n };\n }\n } catch (e) {\n this._diag.warn('Failed to retrieve tab data', e);\n }\n\n // Get complete navigation context for new tab\n const tabContext = this._getTabContext(navigationSource);\n const tab: Tab = {\n experienceId: tabContext.experienceId,\n sourceTabId: tabContext.sourceTabId,\n tabId: tabContext.tabId,\n };\n\n // Persist tab data for page reloads\n try {\n this._sessionStorage.setItem(MXL_TAB_STORAGE_KEY, JSON.stringify(tab));\n } catch (e) {\n this._diag.warn('Failed to store tab data', e);\n }\n\n return { tab, navigationSource };\n }\n\n private _getTabActivity(): TabActivity | null {\n try {\n const stored = this._storage.getItem(MXL_TAB_ACTIVITY_STORAGE_KEY);\n if (!stored) {\n return null;\n }\n\n return JSON.parse(stored) as TabActivity;\n } catch (e) {\n this._diag.warn('Failed to retrieve tab activity', e);\n return null;\n }\n }\n\n private _storeTabActivity(activity: TabActivity): void {\n try {\n this._storage.setItem(\n MXL_TAB_ACTIVITY_STORAGE_KEY,\n JSON.stringify(activity),\n );\n } catch (error) {\n this._diag.warn('Failed to save tab activity', error);\n }\n }\n\n private _storeCurrentTabAsSource(): void {\n const activity: TabActivity = {\n tabId: this._tab.tabId,\n experienceId: this._tab.experienceId,\n lastActivityMs: Date.now(),\n };\n\n this._storeTabActivity(activity);\n }\n\n private _setupNewTabClickListeners(): void {\n const handleNewTabClick = (ev: MouseEvent) => {\n // Check for modifier keys that open new tabs/windows\n if (\n ev.button === 1 || // Middle click\n ev.ctrlKey ||\n ev.metaKey || // Cmd/Ctrl + click\n ev.shiftKey // Shift + click (new window)\n ) {\n this._storeCurrentTabAsSource();\n return;\n }\n\n // Check for elements with attributes that open new tabs\n const newTabAnchor = (ev.target as HTMLElement | null)?.closest(\n 'a[target=\"_blank\"], form[target=\"_blank\"], a[rel*=\"noopener\"], a[rel*=\"noreferrer\"]',\n );\n if (newTabAnchor) {\n this._storeCurrentTabAsSource();\n }\n };\n\n // Capture phase ensures we record before navigation\n const options = { capture: true, passive: true };\n document.addEventListener('auxclick', handleNewTabClick, options);\n document.addEventListener('click', handleNewTabClick, options);\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"MXLSpanSessionManager.cjs","names":["diag","OTelPerformanceManager","trace","BasicTracerProvider","KEY_PREFIX_MXL_PROPERTIES","KEY_MXL_SESSION_REASON_ENDED","KEY_MXL_SDK_STARTUP_DURATION","KEY_MXL_FROM_STORAGE","generateUUID","KEY_MXL_TYPE","KEY_MXL_STATE","getVisibilityState","ATTR_SESSION_ID","KEY_MXL_COLD_START","KEY_MXL_SESSION_NUMBER","getIncrementedCount","MXL_SESSION_NUMBER_STORAGE_KEY","KEY_MXL_EXPERIENCE_ID","KEY_MXL_TAB_ID","KEY_MXL_NAVIGATION_SOURCE","KEY_MXL_REFERRER_URL","KEY_MXL_SOURCE_TAB_ID","KEY_MXL_SESSION_REASON_STARTED","MXLExtendedSpan","getAppInstanceId","MXL_TAB_STORAGE_KEY","MXL_TAB_ACTIVITY_STORAGE_KEY"],"sources":["../../../src/managers/MXLSpanSessionManager/MXLSpanSessionManager.ts"],"sourcesContent":["import type {\n Attributes,\n DiagLogger,\n HrTime,\n Tracer,\n TracerProvider,\n} from '@opentelemetry/api';\nimport { diag, trace } from '@opentelemetry/api';\nimport type { ReadableSpan } from '@opentelemetry/sdk-trace-web';\nimport { BasicTracerProvider } from '@opentelemetry/sdk-trace-web';\nimport { ATTR_SESSION_ID } from '@opentelemetry/semantic-conventions/incubating';\nimport type { ExtendedSpan } from '../..';\nimport type {\n PropertyOptions,\n ReasonSessionEnded,\n StartSessionOptions,\n} from '../../api-sessions';\nimport type { VisibilityStateDocument } from '../../common';\nimport {\n KEY_MXL_COLD_START,\n KEY_MXL_EXPERIENCE_ID,\n KEY_MXL_FROM_STORAGE,\n KEY_MXL_NAVIGATION_SOURCE,\n KEY_MXL_REFERRER_URL,\n KEY_MXL_SDK_STARTUP_DURATION,\n KEY_MXL_SESSION_NUMBER,\n KEY_MXL_SESSION_REASON_ENDED,\n KEY_MXL_SESSION_REASON_STARTED,\n KEY_MXL_SOURCE_TAB_ID,\n KEY_MXL_STATE,\n KEY_MXL_TAB_ID,\n KEY_MXL_TYPE,\n KEY_PREFIX_MXL_PROPERTIES,\n MXL_TYPES,\n} from '../../constants';\nimport { getAppInstanceId } from '../../resources';\nimport type { PerformanceManager } from '../../utils';\nimport {\n generateUUID,\n getIncrementedCount,\n getVisibilityState,\n OTelPerformanceManager,\n} from '../../utils';\nimport type { LimitManagerInternal } from '../MXLLimitManager';\nimport { MXLExtendedSpan } from '../MXLTraceManager/MXLExtendedSpan';\nimport {\n MXL_SESSION_NUMBER_STORAGE_KEY,\n MXL_TAB_ACTIVITY_STORAGE_KEY,\n MXL_TAB_STORAGE_KEY,\n} from './constants';\nimport type {\n MXLSpanSessionManagerArgs,\n NavigationSource,\n SessionEndedListener,\n SessionStartedListener,\n SpanSessionManagerInternal,\n Tab,\n TabActivity,\n} from './types';\n\nexport class MXLSpanSessionManager implements SpanSessionManagerInternal {\n private _previousSessionId: string | null = null;\n private _activeSessionId: string | null = null;\n private _activeSessionStartTime: HrTime | null = null;\n private _sessionSpan: ExtendedSpan | null = null;\n private _activeSessionCounts: Record<string, number> | null = null;\n private _nextSessionCounts: Record<string, number> = {};\n private _coldStart = true; // Whether the session was started from a new page load or not.\n private _sdkStartupDuration = 0;\n private readonly _sessionStartedListeners: Array<SessionStartedListener> = [];\n private readonly _sessionEndedListeners: Array<SessionEndedListener> = [];\n private readonly _tab: Tab;\n private readonly _navigationSource: NavigationSource;\n private readonly _referrerInfo: {\n isValid: boolean;\n isSameOrigin: boolean;\n scrubbedUrl?: string;\n };\n\n private _tracer: Tracer;\n private readonly _noExportTracer: Tracer;\n private readonly _diag: DiagLogger;\n private readonly _perf: PerformanceManager;\n private readonly _visibilityDoc: VisibilityStateDocument;\n private readonly _storage: Storage;\n private readonly _sessionStorage: Storage;\n private readonly _limitManager: LimitManagerInternal;\n private readonly _referrer: string;\n private readonly _navigationPerformance: Pick<\n Performance,\n 'getEntriesByType'\n >;\n\n public constructor({\n diag: diagParam,\n perf,\n visibilityDoc = window.document,\n storage = window.localStorage,\n sessionStorage = window.sessionStorage,\n limitManager,\n referrer = document.referrer,\n navigationPerformance = window.performance,\n }: MXLSpanSessionManagerArgs) {\n this._diag =\n diagParam ??\n diag.createComponentLogger({\n namespace: 'MXLSpanSessionManager',\n });\n this._perf = perf ?? new OTelPerformanceManager();\n this._visibilityDoc = visibilityDoc;\n this._storage = storage;\n this._sessionStorage = sessionStorage;\n this._limitManager = limitManager;\n this._referrer = referrer;\n this._navigationPerformance = navigationPerformance;\n this._tracer = trace.getTracer('mxl-web-sdk-sessions');\n this._noExportTracer = new BasicTracerProvider().getTracer(\n 'mxl-web-sdk-sessions',\n );\n\n // Process referrer once at initialization\n this._referrerInfo = this._processReferrer();\n\n // Initialize tab tracking and navigation source\n const initResult = this._initTab();\n this._tab = initResult.tab;\n this._navigationSource = initResult.navigationSource;\n this._setupNewTabClickListeners();\n }\n\n // Collects all permanent session properties from localStorage\n private _getPermanentAttributes(): Attributes {\n const permanentAttributes = new Map();\n try {\n for (let i = 0; i < this._storage.length; i++) {\n const key = this._storage.key(i);\n if (key?.startsWith(KEY_PREFIX_MXL_PROPERTIES)) {\n const value = this._storage.getItem(key);\n if (value) {\n permanentAttributes.set(key, value);\n }\n }\n }\n } catch (error) {\n this._diag.warn('Error loading permanent session properties', error);\n }\n return Object.fromEntries(permanentAttributes.entries()) as Attributes;\n }\n\n public addBreadcrumb(name: string) {\n if (!this._sessionSpan) {\n this._diag.debug(\n 'trying to add breadcrumb to a session, but there is no session in progress. This is a no-op.',\n );\n return;\n }\n\n const limitedBreadcrumb = this._limitManager.limitBreadcrumb(name);\n\n if (limitedBreadcrumb === 'dropped') {\n return;\n }\n\n this._sessionSpan.addEvent(\n 'mxl-breadcrumb',\n {\n message: limitedBreadcrumb.name,\n },\n this._perf.getNowMillis(),\n );\n }\n\n public addProperty(\n propertyKey: string,\n value: string,\n options?: PropertyOptions,\n ) {\n if (!this._sessionSpan) {\n this._diag.debug(\n 'trying to add properties to a session, but there is no session in progress. This is a no-op.',\n );\n return;\n }\n\n const limitedSessionProperty = this._limitManager.limitSessionProperty(\n propertyKey,\n value,\n );\n\n if (limitedSessionProperty === 'dropped') {\n return;\n }\n\n const attributeKey = KEY_PREFIX_MXL_PROPERTIES + limitedSessionProperty.key;\n this._sessionSpan.setAttribute(attributeKey, limitedSessionProperty.value);\n\n if (options?.lifespan === 'permanent') {\n try {\n this._storage.setItem(attributeKey, value);\n } catch (error) {\n this._diag.warn('Failed to set permanent session property', error);\n }\n }\n }\n\n public removeProperty(propertyKey: string) {\n if (!this._sessionSpan) {\n this._diag.debug(\n 'trying to remove a session property, but there is no session in progress. This is a no-op.',\n );\n return;\n }\n\n // We truncate long session property keys on addProperty so need to apply the same logic here\n const attributeKey =\n KEY_PREFIX_MXL_PROPERTIES +\n this._limitManager.truncateString('session_property_key', propertyKey);\n this._sessionSpan.removeAttribute(attributeKey);\n\n try {\n if (this._storage.getItem(attributeKey)) {\n this._storage.removeItem(attributeKey);\n }\n } catch (error) {\n this._diag.warn('Error removing permanent session property', error);\n }\n }\n\n // the external api doesn't include a reason, and if a users uses it to end a session, the reason will be 'manual'\n // note: don't use this internally, this is just for user facing APIs. Use this.endSessionSpanInternal instead.\n public endSessionSpan() {\n this.endSessionSpanInternal('manual');\n }\n\n // endSessionSpanInternal is not part of the public API, but is used internally to end a session span adding a specific reason\n public endSessionSpanInternal(reason: ReasonSessionEnded) {\n if (!this._sessionSpan) {\n this._diag.debug(\n 'trying to end a session, but there is no session in progress. This is a no-op.',\n );\n return;\n }\n\n for (const listener of this._sessionEndedListeners) {\n try {\n listener();\n } catch (error) {\n this._diag.warn('Error while executing session ended listener', error);\n }\n }\n\n this._sessionSpan.setAttributes(this._endSessionSpanAttributes(reason));\n this._sessionSpan.end();\n this._sessionSpan = null;\n this._activeSessionStartTime = null;\n this._previousSessionId = this._activeSessionId;\n this._activeSessionId = null;\n this._activeSessionCounts = null;\n\n // For the limit manager to add a session ended listener it would need a reference to this\n // session manager which would create a circular dependency\n this._limitManager.reset();\n }\n\n private _endSessionSpanAttributes(reason: ReasonSessionEnded): Attributes {\n return {\n ...this._getPermanentAttributes(),\n [KEY_MXL_SESSION_REASON_ENDED]: reason,\n ...this._activeSessionCounts,\n ...this._limitManager.getDiagnosticCounts(),\n [KEY_MXL_SDK_STARTUP_DURATION]: this._sdkStartupDuration,\n };\n }\n\n // currentSessionAsReadableSpan creates a copy of the current session span with the same attributes\n // that endSessionSpanInternal would add, but does not affect the original session span which remains active.\n public currentSessionAsReadableSpan(\n reason: ReasonSessionEnded,\n ): ReadableSpan | null {\n if (!this._sessionSpan || !this._activeSessionStartTime) {\n this._diag.debug(\n 'trying to end a session, but there is no session in progress. This is a no-op.',\n );\n return null;\n }\n\n // Create a new span with the same name and start time as the original session span,\n // but using a new tracer so that it does not get exported.\n const span = this._noExportTracer.startSpan('mxl-session', {\n startTime: this._activeSessionStartTime,\n attributes: {\n // Copy all current attributes from the original session span, plus the ending attributes\n ...this._sessionSpan.attributes,\n ...this._endSessionSpanAttributes(reason),\n [KEY_MXL_FROM_STORAGE]: true,\n },\n });\n span.end();\n return span as unknown as ReadableSpan;\n }\n\n public getSessionId(): string | null {\n return this._activeSessionId;\n }\n\n public getPreviousSessionId(): string | null {\n return this._previousSessionId;\n }\n\n public getSessionSpan(): ExtendedSpan | null {\n return this._sessionSpan;\n }\n\n public getSessionStartTime(): HrTime | null {\n return this._activeSessionStartTime;\n }\n\n public startSessionSpan(options?: StartSessionOptions) {\n // if there is a session already in progress, end it first\n if (this._sessionSpan) {\n this.endSessionSpanInternal('manual');\n }\n\n this._activeSessionId = generateUUID();\n this._activeSessionStartTime = this._perf.getNowHRTime();\n this._activeSessionCounts = {};\n const previouslyRecordedCounts = this._nextSessionCounts;\n this._nextSessionCounts = {};\n\n const attributes: Attributes = {\n ...this._getPermanentAttributes(),\n [KEY_MXL_TYPE]: MXL_TYPES.Session,\n [KEY_MXL_STATE]: getVisibilityState(this._visibilityDoc),\n [ATTR_SESSION_ID]: this._activeSessionId,\n [KEY_MXL_COLD_START]: this._coldStart,\n [KEY_MXL_SESSION_NUMBER]: getIncrementedCount(\n this._storage,\n MXL_SESSION_NUMBER_STORAGE_KEY,\n this._diag,\n ),\n [KEY_MXL_EXPERIENCE_ID]: this._tab.experienceId,\n [KEY_MXL_TAB_ID]: this._tab.tabId,\n [KEY_MXL_NAVIGATION_SOURCE]: this._navigationSource,\n ...previouslyRecordedCounts,\n };\n\n // Add scrubbed referrer URL if available\n if (this._referrerInfo.isValid && this._referrerInfo.scrubbedUrl) {\n attributes[KEY_MXL_REFERRER_URL] = this._referrerInfo.scrubbedUrl;\n }\n\n if (this._tab.sourceTabId) {\n attributes[KEY_MXL_SOURCE_TAB_ID] = this._tab.sourceTabId;\n }\n\n const sessionStartReason = options?.reason ?? 'manual';\n attributes[KEY_MXL_SESSION_REASON_STARTED] = sessionStartReason;\n\n this._sessionSpan = new MXLExtendedSpan(\n this._tracer.startSpan('mxl-session', {\n attributes,\n }),\n );\n\n this._coldStart = false;\n\n for (const listener of this._sessionStartedListeners) {\n try {\n listener();\n } catch (error) {\n this._diag.warn(\n 'Error while executing session started listener',\n error,\n );\n }\n }\n }\n\n public incrSessionCountForKey(key: string) {\n if (!this._sessionSpan || !this._activeSessionCounts) {\n this._diag.debug(\n 'trying to increment a count for the active session, but there is no session in progress. This is a no-op.',\n );\n return;\n }\n\n this._activeSessionCounts[key] = (this._activeSessionCounts[key] || 0) + 1;\n }\n\n public incrNextSessionCountForKey(key: string) {\n this._nextSessionCounts[key] = (this._nextSessionCounts[key] || 0) + 1;\n }\n\n public addSessionStartedListener(listener: SessionStartedListener) {\n const listenerIndex = this._sessionStartedListeners.push(listener);\n\n return () => {\n this._sessionStartedListeners.splice(listenerIndex - 1, 1);\n };\n }\n\n public addSessionEndedListener(listener: SessionEndedListener) {\n const listenerIndex = this._sessionEndedListeners.push(listener);\n\n return () => {\n this._sessionEndedListeners.splice(listenerIndex - 1, 1);\n };\n }\n\n public recordSDKStartupDuration(duration: number) {\n this._sdkStartupDuration = Math.ceil(duration);\n }\n\n public setTracerProvider(tracerProvider: TracerProvider) {\n this._tracer = tracerProvider.getTracer('mxl-web-sdk-sessions');\n }\n\n private _determineNavigationSource(): NavigationSource {\n // Check Navigation Timing API first\n try {\n const navEntries =\n this._navigationPerformance.getEntriesByType('navigation');\n if (navEntries.length > 0 && navEntries[0]) {\n const navEntry = navEntries[0];\n if (navEntry.type === 'reload') {\n return 'reload';\n } else if (navEntry.type === 'back_forward') {\n return 'back_forward';\n }\n }\n } catch (error) {\n this._diag.warn('Failed to get navigation type', error);\n }\n\n // If not reload/back_forward, analyze referrer\n if (this._referrerInfo.isValid) {\n return this._referrerInfo.isSameOrigin ? 'same_origin' : 'external';\n }\n\n return 'direct';\n }\n\n private _processReferrer(): {\n isValid: boolean;\n isSameOrigin: boolean;\n scrubbedUrl?: string;\n } {\n if (!this._referrer) {\n return { isValid: false, isSameOrigin: false };\n }\n\n try {\n const referrerUrl = new URL(this._referrer);\n const currentOrigin = window.location.origin;\n\n return {\n isValid: true,\n isSameOrigin: referrerUrl.origin === currentOrigin,\n scrubbedUrl: referrerUrl.origin + referrerUrl.pathname,\n };\n } catch {\n return { isValid: false, isSameOrigin: false };\n }\n }\n\n private _getTabContext(navigationSource: NavigationSource): {\n sourceTabId?: string;\n experienceId: string;\n tabId: string;\n } {\n // Always use getAppInstanceId to ensure consistent tab ID\n const tabId = getAppInstanceId(this._sessionStorage, this._diag);\n\n // Look for source tab only if navigation is from same origin\n let sourceTabId: string | undefined;\n let experienceId: string | undefined;\n\n if (navigationSource === 'same_origin') {\n const lastActivity = this._getTabActivity();\n if (lastActivity) {\n const age = Date.now() - lastActivity.lastActivityMs;\n // 10 second window to detect source tabs - balances capturing legitimate\n // tab relationships while avoiding false positives from stale activity\n if (age <= 10_000) {\n sourceTabId = lastActivity.tabId;\n experienceId = lastActivity.experienceId;\n }\n }\n }\n\n // Only generate new UUID if we didn't inherit one from source tab\n experienceId ??= generateUUID();\n\n return {\n sourceTabId,\n experienceId,\n tabId,\n };\n }\n\n private _initTab(): { tab: Tab; navigationSource: NavigationSource } {\n // Determine navigation source once at startup\n const navigationSource = this._determineNavigationSource();\n\n // On page reload, preserve the same tab IDs\n try {\n const stored = this._sessionStorage.getItem(MXL_TAB_STORAGE_KEY);\n if (stored) {\n return {\n tab: JSON.parse(stored) as Tab,\n navigationSource,\n };\n }\n } catch (e) {\n this._diag.warn('Failed to retrieve tab data', e);\n }\n\n // Get complete navigation context for new tab\n const tabContext = this._getTabContext(navigationSource);\n const tab: Tab = {\n experienceId: tabContext.experienceId,\n sourceTabId: tabContext.sourceTabId,\n tabId: tabContext.tabId,\n };\n\n // Persist tab data for page reloads\n try {\n this._sessionStorage.setItem(MXL_TAB_STORAGE_KEY, JSON.stringify(tab));\n } catch (e) {\n this._diag.warn('Failed to store tab data', e);\n }\n\n return { tab, navigationSource };\n }\n\n private _getTabActivity(): TabActivity | null {\n try {\n const stored = this._storage.getItem(MXL_TAB_ACTIVITY_STORAGE_KEY);\n if (!stored) {\n return null;\n }\n\n return JSON.parse(stored) as TabActivity;\n } catch (e) {\n this._diag.warn('Failed to retrieve tab activity', e);\n return null;\n }\n }\n\n private _storeTabActivity(activity: TabActivity): void {\n try {\n this._storage.setItem(\n MXL_TAB_ACTIVITY_STORAGE_KEY,\n JSON.stringify(activity),\n );\n } catch (error) {\n this._diag.warn('Failed to save tab activity', error);\n }\n }\n\n private _storeCurrentTabAsSource(): void {\n const activity: TabActivity = {\n tabId: this._tab.tabId,\n experienceId: this._tab.experienceId,\n lastActivityMs: Date.now(),\n };\n\n this._storeTabActivity(activity);\n }\n\n private _setupNewTabClickListeners(): void {\n const handleNewTabClick = (ev: MouseEvent) => {\n // Check for modifier keys that open new tabs/windows\n if (\n ev.button === 1 || // Middle click\n ev.ctrlKey ||\n ev.metaKey || // Cmd/Ctrl + click\n ev.shiftKey // Shift + click (new window)\n ) {\n this._storeCurrentTabAsSource();\n return;\n }\n\n // Check for elements with attributes that open new tabs\n const newTabAnchor = (ev.target as HTMLElement | null)?.closest(\n 'a[target=\"_blank\"], form[target=\"_blank\"], a[rel*=\"noopener\"], a[rel*=\"noreferrer\"]',\n );\n if (newTabAnchor) {\n this._storeCurrentTabAsSource();\n }\n };\n\n // Capture phase ensures we record before navigation\n const options = { capture: true, passive: true };\n document.addEventListener('auxclick', handleNewTabClick, options);\n document.addEventListener('click', handleNewTabClick, options);\n }\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MXLSpanSessionManager.d.cts","names":[],"sources":["../../../src/managers/MXLSpanSessionManager/MXLSpanSessionManager.ts"],"mappings":";;;;;;;cA4Da,qBAAA,YAAiC,0BAAA;EAAA,QACpC,kBAAA;EAAA,QACA,gBAAA;EAAA,QACA,uBAAA;EAAA,QACA,YAAA;EAAA,QACA,oBAAA;EAAA,QACA,kBAAA;EAAA,QACA,UAAA;EAAA,QACA,mBAAA;EAAA,iBACS,wBAAA;EAAA,iBACA,sBAAA;EAAA,iBACA,IAAA;EAAA,iBACA,iBAAA;EAAA,iBACA,aAAA;EAAA,QAMT,OAAA;EAAA,iBACS,eAAA;EAAA,iBACA,KAAA;EAAA,iBACA,KAAA;EAAA,iBACA,cAAA;EAAA,iBACA,QAAA;EAAA,iBACA,eAAA;EAAA,iBACA,aAAA;EAAA,iBACA,SAAA;EAAA,iBACA,sBAAA;;
|
|
1
|
+
{"version":3,"file":"MXLSpanSessionManager.d.cts","names":[],"sources":["../../../src/managers/MXLSpanSessionManager/MXLSpanSessionManager.ts"],"mappings":";;;;;;;cA4Da,qBAAA,YAAiC,0BAAA;EAAA,QACpC,kBAAA;EAAA,QACA,gBAAA;EAAA,QACA,uBAAA;EAAA,QACA,YAAA;EAAA,QACA,oBAAA;EAAA,QACA,kBAAA;EAAA,QACA,UAAA;EAAA,QACA,mBAAA;EAAA,iBACS,wBAAA;EAAA,iBACA,sBAAA;EAAA,iBACA,IAAA;EAAA,iBACA,iBAAA;EAAA,iBACA,aAAA;EAAA,QAMT,OAAA;EAAA,iBACS,eAAA;EAAA,iBACA,KAAA;EAAA,iBACA,KAAA;EAAA,iBACA,cAAA;EAAA,iBACA,QAAA;EAAA,iBACA,eAAA;EAAA,iBACA,aAAA;EAAA,iBACA,SAAA;EAAA,iBACA,sBAAA;;IAMf,IAAA,EAAM,SAAA;IACN,IAAA;IACA,aAAA;IACA,OAAA;IACA,cAAA;IACA,YAAA;IACA,QAAA;IACA;EAAA,GACC,yBAAA;EAAA,QA6BK,uBAAA;EAkBD,aAAA,CAAc,IAAA;EAuBd,WAAA,CACL,WAAA,UACA,KAAA,UACA,OAAA,GAAU,eAAA;EA8BL,cAAA,CAAe,WAAA;EAyBf,cAAA,CAAA;EAKA,sBAAA,CAAuB,MAAA,EAAQ,kBAAA;EAAA,QA6B9B,yBAAA;EAYD,4BAAA,CACL,MAAA,EAAQ,kBAAA,GACP,YAAA;EAuBI,YAAA,CAAA;EAIA,oBAAA,CAAA;EAIA,cAAA,CAAA,GAAkB,YAAA;EAIlB,mBAAA,CAAA,GAAuB,MAAA;EAIvB,gBAAA,CAAiB,OAAA,GAAU,mBAAA;EA6D3B,sBAAA,CAAuB,GAAA;EAWvB,0BAAA,CAA2B,GAAA;EAI3B,yBAAA,CAA0B,QAAA,EAAU,sBAAA;EAQpC,uBAAA,CAAwB,QAAA,EAAU,oBAAA;EAQlC,wBAAA,CAAyB,QAAA;EAIzB,iBAAA,CAAkB,cAAA,EAAgB,cAAA;EAAA,QAIjC,0BAAA;EAAA,QAyBA,gBAAA;EAAA,QAuBA,cAAA;EAAA,QAmCA,QAAA;EAAA,QAmCA,eAAA;EAAA,QAcA,iBAAA;EAAA,QAWA,wBAAA;EAAA,QAUA,0BAAA;AAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MXLSpanSessionManager.d.ts","names":[],"sources":["../../../src/managers/MXLSpanSessionManager/MXLSpanSessionManager.ts"],"mappings":";;;;;;;cA4Da,qBAAA,YAAiC,0BAAA;EAAA,QACpC,kBAAA;EAAA,QACA,gBAAA;EAAA,QACA,uBAAA;EAAA,QACA,YAAA;EAAA,QACA,oBAAA;EAAA,QACA,kBAAA;EAAA,QACA,UAAA;EAAA,QACA,mBAAA;EAAA,iBACS,wBAAA;EAAA,iBACA,sBAAA;EAAA,iBACA,IAAA;EAAA,iBACA,iBAAA;EAAA,iBACA,aAAA;EAAA,QAMT,OAAA;EAAA,iBACS,eAAA;EAAA,iBACA,KAAA;EAAA,iBACA,KAAA;EAAA,iBACA,cAAA;EAAA,iBACA,QAAA;EAAA,iBACA,eAAA;EAAA,iBACA,aAAA;EAAA,iBACA,SAAA;EAAA,iBACA,sBAAA;;
|
|
1
|
+
{"version":3,"file":"MXLSpanSessionManager.d.ts","names":[],"sources":["../../../src/managers/MXLSpanSessionManager/MXLSpanSessionManager.ts"],"mappings":";;;;;;;cA4Da,qBAAA,YAAiC,0BAAA;EAAA,QACpC,kBAAA;EAAA,QACA,gBAAA;EAAA,QACA,uBAAA;EAAA,QACA,YAAA;EAAA,QACA,oBAAA;EAAA,QACA,kBAAA;EAAA,QACA,UAAA;EAAA,QACA,mBAAA;EAAA,iBACS,wBAAA;EAAA,iBACA,sBAAA;EAAA,iBACA,IAAA;EAAA,iBACA,iBAAA;EAAA,iBACA,aAAA;EAAA,QAMT,OAAA;EAAA,iBACS,eAAA;EAAA,iBACA,KAAA;EAAA,iBACA,KAAA;EAAA,iBACA,cAAA;EAAA,iBACA,QAAA;EAAA,iBACA,eAAA;EAAA,iBACA,aAAA;EAAA,iBACA,SAAA;EAAA,iBACA,sBAAA;;IAMf,IAAA,EAAM,SAAA;IACN,IAAA;IACA,aAAA;IACA,OAAA;IACA,cAAA;IACA,YAAA;IACA,QAAA;IACA;EAAA,GACC,yBAAA;EAAA,QA6BK,uBAAA;EAkBD,aAAA,CAAc,IAAA;EAuBd,WAAA,CACL,WAAA,UACA,KAAA,UACA,OAAA,GAAU,eAAA;EA8BL,cAAA,CAAe,WAAA;EAyBf,cAAA,CAAA;EAKA,sBAAA,CAAuB,MAAA,EAAQ,kBAAA;EAAA,QA6B9B,yBAAA;EAYD,4BAAA,CACL,MAAA,EAAQ,kBAAA,GACP,YAAA;EAuBI,YAAA,CAAA;EAIA,oBAAA,CAAA;EAIA,cAAA,CAAA,GAAkB,YAAA;EAIlB,mBAAA,CAAA,GAAuB,MAAA;EAIvB,gBAAA,CAAiB,OAAA,GAAU,mBAAA;EA6D3B,sBAAA,CAAuB,GAAA;EAWvB,0BAAA,CAA2B,GAAA;EAI3B,yBAAA,CAA0B,QAAA,EAAU,sBAAA;EAQpC,uBAAA,CAAwB,QAAA,EAAU,oBAAA;EAQlC,wBAAA,CAAyB,QAAA;EAIzB,iBAAA,CAAkB,cAAA,EAAgB,cAAA;EAAA,QAIjC,0BAAA;EAAA,QAyBA,gBAAA;EAAA,QAuBA,cAAA;EAAA,QAmCA,QAAA;EAAA,QAmCA,eAAA;EAAA,QAcA,iBAAA;EAAA,QAWA,wBAAA;EAAA,QAUA,0BAAA;AAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MXLSpanSessionManager.js","names":[],"sources":["../../../src/managers/MXLSpanSessionManager/MXLSpanSessionManager.ts"],"sourcesContent":["import type {\n Attributes,\n DiagLogger,\n HrTime,\n Tracer,\n TracerProvider,\n} from '@opentelemetry/api';\nimport { diag, trace } from '@opentelemetry/api';\nimport type { ReadableSpan } from '@opentelemetry/sdk-trace-web';\nimport { BasicTracerProvider } from '@opentelemetry/sdk-trace-web';\nimport { ATTR_SESSION_ID } from '@opentelemetry/semantic-conventions/incubating';\nimport type {\n PropertyOptions,\n ReasonSessionEnded,\n StartSessionOptions,\n} from '../../api-sessions/index.ts';\nimport type { VisibilityStateDocument } from '../../common/index.ts';\nimport {\n KEY_MXL_COLD_START,\n KEY_MXL_EXPERIENCE_ID,\n KEY_MXL_FROM_STORAGE,\n KEY_MXL_NAVIGATION_SOURCE,\n KEY_MXL_REFERRER_URL,\n KEY_MXL_SDK_STARTUP_DURATION,\n KEY_MXL_SESSION_NUMBER,\n KEY_MXL_SESSION_REASON_ENDED,\n KEY_MXL_SESSION_REASON_STARTED,\n KEY_MXL_SOURCE_TAB_ID,\n KEY_MXL_STATE,\n KEY_MXL_TAB_ID,\n KEY_MXL_TYPE,\n KEY_PREFIX_MXL_PROPERTIES,\n MXL_TYPES,\n} from '../../constants/index.ts';\nimport type { ExtendedSpan } from '../../index.ts';\nimport { getAppInstanceId } from '../../resources/index.ts';\nimport type { PerformanceManager } from '../../utils/index.ts';\nimport {\n generateUUID,\n getIncrementedCount,\n getVisibilityState,\n OTelPerformanceManager,\n} from '../../utils/index.ts';\nimport type { LimitManagerInternal } from '../MXLLimitManager/index.ts';\nimport { MXLExtendedSpan } from '../MXLTraceManager/MXLExtendedSpan.ts';\nimport {\n MXL_SESSION_NUMBER_STORAGE_KEY,\n MXL_TAB_ACTIVITY_STORAGE_KEY,\n MXL_TAB_STORAGE_KEY,\n} from './constants.ts';\nimport type {\n MXLSpanSessionManagerArgs,\n NavigationSource,\n SessionEndedListener,\n SessionStartedListener,\n SpanSessionManagerInternal,\n Tab,\n TabActivity,\n} from './types.ts';\n\nexport class MXLSpanSessionManager implements SpanSessionManagerInternal {\n private _previousSessionId: string | null = null;\n private _activeSessionId: string | null = null;\n private _activeSessionStartTime: HrTime | null = null;\n private _sessionSpan: ExtendedSpan | null = null;\n private _activeSessionCounts: Record<string, number> | null = null;\n private _nextSessionCounts: Record<string, number> = {};\n private _coldStart = true; // Whether the session was started from a new page load or not.\n private _sdkStartupDuration = 0;\n private readonly _sessionStartedListeners: Array<SessionStartedListener> = [];\n private readonly _sessionEndedListeners: Array<SessionEndedListener> = [];\n private readonly _tab: Tab;\n private readonly _navigationSource: NavigationSource;\n private readonly _referrerInfo: {\n isValid: boolean;\n isSameOrigin: boolean;\n scrubbedUrl?: string;\n };\n\n private _tracer: Tracer;\n private readonly _noExportTracer: Tracer;\n private readonly _diag: DiagLogger;\n private readonly _perf: PerformanceManager;\n private readonly _visibilityDoc: VisibilityStateDocument;\n private readonly _storage: Storage;\n private readonly _sessionStorage: Storage;\n private readonly _limitManager: LimitManagerInternal;\n private readonly _referrer: string;\n private readonly _navigationPerformance: Pick<Performance, 'getEntriesByType'>;\n\n public constructor({\n diag: diagParam,\n perf,\n visibilityDoc = window.document,\n storage = window.localStorage,\n sessionStorage = window.sessionStorage,\n limitManager,\n referrer = document.referrer,\n navigationPerformance = window.performance,\n }: MXLSpanSessionManagerArgs) {\n this._diag =\n diagParam ??\n diag.createComponentLogger({\n namespace: 'MXLSpanSessionManager',\n });\n this._perf = perf ?? new OTelPerformanceManager();\n this._visibilityDoc = visibilityDoc;\n this._storage = storage;\n this._sessionStorage = sessionStorage;\n this._limitManager = limitManager;\n this._referrer = referrer;\n this._navigationPerformance = navigationPerformance;\n this._tracer = trace.getTracer('mxl-web-sdk-sessions');\n this._noExportTracer = new BasicTracerProvider().getTracer(\n 'mxl-web-sdk-sessions',\n );\n\n // Process referrer once at initialization\n this._referrerInfo = this._processReferrer();\n\n // Initialize tab tracking and navigation source\n const initResult = this._initTab();\n this._tab = initResult.tab;\n this._navigationSource = initResult.navigationSource;\n this._setupNewTabClickListeners();\n }\n\n // Collects all permanent session properties from localStorage\n private _getPermanentAttributes(): Attributes {\n const permanentAttributes = new Map();\n try {\n for (let i = 0; i < this._storage.length; i++) {\n const key = this._storage.key(i);\n if (key?.startsWith(KEY_PREFIX_MXL_PROPERTIES)) {\n const value = this._storage.getItem(key);\n if (value) {\n permanentAttributes.set(key, value);\n }\n }\n }\n } catch (error) {\n this._diag.warn('Error loading permanent session properties', error);\n }\n return Object.fromEntries(permanentAttributes.entries()) as Attributes;\n }\n\n public addBreadcrumb(name: string) {\n if (!this._sessionSpan) {\n this._diag.debug(\n 'trying to add breadcrumb to a session, but there is no session in progress. This is a no-op.',\n );\n return;\n }\n\n const limitedBreadcrumb = this._limitManager.limitBreadcrumb(name);\n\n if (limitedBreadcrumb === 'dropped') {\n return;\n }\n\n this._sessionSpan.addEvent(\n 'mxl-breadcrumb',\n {\n message: limitedBreadcrumb.name,\n },\n this._perf.getNowMillis(),\n );\n }\n\n public addProperty(\n propertyKey: string,\n value: string,\n options?: PropertyOptions,\n ) {\n if (!this._sessionSpan) {\n this._diag.debug(\n 'trying to add properties to a session, but there is no session in progress. This is a no-op.',\n );\n return;\n }\n\n const limitedSessionProperty = this._limitManager.limitSessionProperty(\n propertyKey,\n value,\n );\n\n if (limitedSessionProperty === 'dropped') {\n return;\n }\n\n const attributeKey = KEY_PREFIX_MXL_PROPERTIES + limitedSessionProperty.key;\n this._sessionSpan.setAttribute(attributeKey, limitedSessionProperty.value);\n\n if (options?.lifespan === 'permanent') {\n try {\n this._storage.setItem(attributeKey, value);\n } catch (error) {\n this._diag.warn('Failed to set permanent session property', error);\n }\n }\n }\n\n public removeProperty(propertyKey: string) {\n if (!this._sessionSpan) {\n this._diag.debug(\n 'trying to remove a session property, but there is no session in progress. This is a no-op.',\n );\n return;\n }\n\n // We truncate long session property keys on addProperty so need to apply the same logic here\n const attributeKey =\n KEY_PREFIX_MXL_PROPERTIES +\n this._limitManager.truncateString('session_property_key', propertyKey);\n this._sessionSpan.removeAttribute(attributeKey);\n\n try {\n if (this._storage.getItem(attributeKey)) {\n this._storage.removeItem(attributeKey);\n }\n } catch (error) {\n this._diag.warn('Error removing permanent session property', error);\n }\n }\n\n // the external api doesn't include a reason, and if a users uses it to end a session, the reason will be 'manual'\n // note: don't use this internally, this is just for user facing APIs. Use this.endSessionSpanInternal instead.\n public endSessionSpan() {\n this.endSessionSpanInternal('manual');\n }\n\n // endSessionSpanInternal is not part of the public API, but is used internally to end a session span adding a specific reason\n public endSessionSpanInternal(reason: ReasonSessionEnded) {\n if (!this._sessionSpan) {\n this._diag.debug(\n 'trying to end a session, but there is no session in progress. This is a no-op.',\n );\n return;\n }\n\n for (const listener of this._sessionEndedListeners) {\n try {\n listener();\n } catch (error) {\n this._diag.warn('Error while executing session ended listener', error);\n }\n }\n\n this._sessionSpan.setAttributes(this._endSessionSpanAttributes(reason));\n this._sessionSpan.end();\n this._sessionSpan = null;\n this._activeSessionStartTime = null;\n this._previousSessionId = this._activeSessionId;\n this._activeSessionId = null;\n this._activeSessionCounts = null;\n\n // For the limit manager to add a session ended listener it would need a reference to this\n // session manager which would create a circular dependency\n this._limitManager.reset();\n }\n\n private _endSessionSpanAttributes(reason: ReasonSessionEnded): Attributes {\n return {\n ...this._getPermanentAttributes(),\n [KEY_MXL_SESSION_REASON_ENDED]: reason,\n ...this._activeSessionCounts,\n ...this._limitManager.getDiagnosticCounts(),\n [KEY_MXL_SDK_STARTUP_DURATION]: this._sdkStartupDuration,\n };\n }\n\n // currentSessionAsReadableSpan creates a copy of the current session span with the same attributes\n // that endSessionSpanInternal would add, but does not affect the original session span which remains active.\n public currentSessionAsReadableSpan(\n reason: ReasonSessionEnded,\n ): ReadableSpan | null {\n if (!this._sessionSpan || !this._activeSessionStartTime) {\n this._diag.debug(\n 'trying to end a session, but there is no session in progress. This is a no-op.',\n );\n return null;\n }\n\n // Create a new span with the same name and start time as the original session span,\n // but using a new tracer so that it does not get exported.\n const span = this._noExportTracer.startSpan('mxl-session', {\n startTime: this._activeSessionStartTime,\n attributes: {\n // Copy all current attributes from the original session span, plus the ending attributes\n ...this._sessionSpan.attributes,\n ...this._endSessionSpanAttributes(reason),\n [KEY_MXL_FROM_STORAGE]: true,\n },\n });\n span.end();\n return span as unknown as ReadableSpan;\n }\n\n public getSessionId(): string | null {\n return this._activeSessionId;\n }\n\n public getPreviousSessionId(): string | null {\n return this._previousSessionId;\n }\n\n public getSessionSpan(): ExtendedSpan | null {\n return this._sessionSpan;\n }\n\n public getSessionStartTime(): HrTime | null {\n return this._activeSessionStartTime;\n }\n\n public startSessionSpan(options?: StartSessionOptions) {\n // if there is a session already in progress, end it first\n if (this._sessionSpan) {\n this.endSessionSpanInternal('manual');\n }\n\n this._activeSessionId = generateUUID();\n this._activeSessionStartTime = this._perf.getNowHRTime();\n this._activeSessionCounts = {};\n const previouslyRecordedCounts = this._nextSessionCounts;\n this._nextSessionCounts = {};\n\n const attributes: Attributes = {\n ...this._getPermanentAttributes(),\n [KEY_MXL_TYPE]: MXL_TYPES.Session,\n [KEY_MXL_STATE]: getVisibilityState(this._visibilityDoc),\n [ATTR_SESSION_ID]: this._activeSessionId,\n [KEY_MXL_COLD_START]: this._coldStart,\n [KEY_MXL_SESSION_NUMBER]: getIncrementedCount(\n this._storage,\n MXL_SESSION_NUMBER_STORAGE_KEY,\n this._diag,\n ),\n [KEY_MXL_EXPERIENCE_ID]: this._tab.experienceId,\n [KEY_MXL_TAB_ID]: this._tab.tabId,\n [KEY_MXL_NAVIGATION_SOURCE]: this._navigationSource,\n ...previouslyRecordedCounts,\n };\n\n // Add scrubbed referrer URL if available\n if (this._referrerInfo.isValid && this._referrerInfo.scrubbedUrl) {\n attributes[KEY_MXL_REFERRER_URL] = this._referrerInfo.scrubbedUrl;\n }\n\n if (this._tab.sourceTabId) {\n attributes[KEY_MXL_SOURCE_TAB_ID] = this._tab.sourceTabId;\n }\n\n const sessionStartReason = options?.reason ?? 'manual';\n attributes[KEY_MXL_SESSION_REASON_STARTED] = sessionStartReason;\n\n this._sessionSpan = new MXLExtendedSpan(\n this._tracer.startSpan('mxl-session', {\n attributes,\n }),\n );\n\n this._coldStart = false;\n\n for (const listener of this._sessionStartedListeners) {\n try {\n listener();\n } catch (error) {\n this._diag.warn(\n 'Error while executing session started listener',\n error,\n );\n }\n }\n }\n\n public incrSessionCountForKey(key: string) {\n if (!this._sessionSpan || !this._activeSessionCounts) {\n this._diag.debug(\n 'trying to increment a count for the active session, but there is no session in progress. This is a no-op.',\n );\n return;\n }\n\n this._activeSessionCounts[key] = (this._activeSessionCounts[key] || 0) + 1;\n }\n\n public incrNextSessionCountForKey(key: string) {\n this._nextSessionCounts[key] = (this._nextSessionCounts[key] || 0) + 1;\n }\n\n public addSessionStartedListener(listener: SessionStartedListener) {\n const listenerIndex = this._sessionStartedListeners.push(listener);\n\n return () => {\n this._sessionStartedListeners.splice(listenerIndex - 1, 1);\n };\n }\n\n public addSessionEndedListener(listener: SessionEndedListener) {\n const listenerIndex = this._sessionEndedListeners.push(listener);\n\n return () => {\n this._sessionEndedListeners.splice(listenerIndex - 1, 1);\n };\n }\n\n public recordSDKStartupDuration(duration: number) {\n this._sdkStartupDuration = Math.ceil(duration);\n }\n\n public setTracerProvider(tracerProvider: TracerProvider) {\n this._tracer = tracerProvider.getTracer('mxl-web-sdk-sessions');\n }\n\n private _determineNavigationSource(): NavigationSource {\n // Check Navigation Timing API first\n try {\n const navEntries =\n this._navigationPerformance.getEntriesByType('navigation');\n if (navEntries.length > 0 && navEntries[0]) {\n const navEntry = navEntries[0];\n if (navEntry.type === 'reload') {\n return 'reload';\n } else if (navEntry.type === 'back_forward') {\n return 'back_forward';\n }\n }\n } catch (error) {\n this._diag.warn('Failed to get navigation type', error);\n }\n\n // If not reload/back_forward, analyze referrer\n if (this._referrerInfo.isValid) {\n return this._referrerInfo.isSameOrigin ? 'same_origin' : 'external';\n }\n\n return 'direct';\n }\n\n private _processReferrer(): {\n isValid: boolean;\n isSameOrigin: boolean;\n scrubbedUrl?: string;\n } {\n if (!this._referrer) {\n return { isValid: false, isSameOrigin: false };\n }\n\n try {\n const referrerUrl = new URL(this._referrer);\n const currentOrigin = window.location.origin;\n\n return {\n isValid: true,\n isSameOrigin: referrerUrl.origin === currentOrigin,\n scrubbedUrl: referrerUrl.origin + referrerUrl.pathname,\n };\n } catch {\n return { isValid: false, isSameOrigin: false };\n }\n }\n\n private _getTabContext(navigationSource: NavigationSource): {\n sourceTabId?: string;\n experienceId: string;\n tabId: string;\n } {\n // Always use getAppInstanceId to ensure consistent tab ID\n const tabId = getAppInstanceId(this._sessionStorage, this._diag);\n\n // Look for source tab only if navigation is from same origin\n let sourceTabId: string | undefined;\n let experienceId: string | undefined;\n\n if (navigationSource === 'same_origin') {\n const lastActivity = this._getTabActivity();\n if (lastActivity) {\n const age = Date.now() - lastActivity.lastActivityMs;\n // 10 second window to detect source tabs - balances capturing legitimate\n // tab relationships while avoiding false positives from stale activity\n if (age <= 10_000) {\n sourceTabId = lastActivity.tabId;\n experienceId = lastActivity.experienceId;\n }\n }\n }\n\n // Only generate new UUID if we didn't inherit one from source tab\n experienceId ??= generateUUID();\n\n return {\n sourceTabId,\n experienceId,\n tabId,\n };\n }\n\n private _initTab(): { tab: Tab; navigationSource: NavigationSource } {\n // Determine navigation source once at startup\n const navigationSource = this._determineNavigationSource();\n\n // On page reload, preserve the same tab IDs\n try {\n const stored = this._sessionStorage.getItem(MXL_TAB_STORAGE_KEY);\n if (stored) {\n return {\n tab: JSON.parse(stored) as Tab,\n navigationSource,\n };\n }\n } catch (e) {\n this._diag.warn('Failed to retrieve tab data', e);\n }\n\n // Get complete navigation context for new tab\n const tabContext = this._getTabContext(navigationSource);\n const tab: Tab = {\n experienceId: tabContext.experienceId,\n sourceTabId: tabContext.sourceTabId,\n tabId: tabContext.tabId,\n };\n\n // Persist tab data for page reloads\n try {\n this._sessionStorage.setItem(MXL_TAB_STORAGE_KEY, JSON.stringify(tab));\n } catch (e) {\n this._diag.warn('Failed to store tab data', e);\n }\n\n return { tab, navigationSource };\n }\n\n private _getTabActivity(): TabActivity | null {\n try {\n const stored = this._storage.getItem(MXL_TAB_ACTIVITY_STORAGE_KEY);\n if (!stored) {\n return null;\n }\n\n return JSON.parse(stored) as TabActivity;\n } catch (e) {\n this._diag.warn('Failed to retrieve tab activity', e);\n return null;\n }\n }\n\n private _storeTabActivity(activity: TabActivity): void {\n try {\n this._storage.setItem(\n MXL_TAB_ACTIVITY_STORAGE_KEY,\n JSON.stringify(activity),\n );\n } catch (error) {\n this._diag.warn('Failed to save tab activity', error);\n }\n }\n\n private _storeCurrentTabAsSource(): void {\n const activity: TabActivity = {\n tabId: this._tab.tabId,\n experienceId: this._tab.experienceId,\n lastActivityMs: Date.now(),\n };\n\n this._storeTabActivity(activity);\n }\n\n private _setupNewTabClickListeners(): void {\n const handleNewTabClick = (ev: MouseEvent) => {\n // Check for modifier keys that open new tabs/windows\n if (\n ev.button === 1 || // Middle click\n ev.ctrlKey ||\n ev.metaKey || // Cmd/Ctrl + click\n ev.shiftKey // Shift + click (new window)\n ) {\n this._storeCurrentTabAsSource();\n return;\n }\n\n // Check for elements with attributes that open new tabs\n const newTabAnchor = (ev.target as HTMLElement | null)?.closest(\n 'a[target=\"_blank\"], form[target=\"_blank\"], a[rel*=\"noopener\"], a[rel*=\"noreferrer\"]',\n );\n if (newTabAnchor) {\n this._storeCurrentTabAsSource();\n }\n };\n\n // Capture phase ensures we record before navigation\n const options = { capture: true, passive: true };\n document.addEventListener('auxclick', handleNewTabClick, options);\n document.addEventListener('click', handleNewTabClick, options);\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"MXLSpanSessionManager.js","names":[],"sources":["../../../src/managers/MXLSpanSessionManager/MXLSpanSessionManager.ts"],"sourcesContent":["import type {\n Attributes,\n DiagLogger,\n HrTime,\n Tracer,\n TracerProvider,\n} from '@opentelemetry/api';\nimport { diag, trace } from '@opentelemetry/api';\nimport type { ReadableSpan } from '@opentelemetry/sdk-trace-web';\nimport { BasicTracerProvider } from '@opentelemetry/sdk-trace-web';\nimport { ATTR_SESSION_ID } from '@opentelemetry/semantic-conventions/incubating';\nimport type { ExtendedSpan } from '../..';\nimport type {\n PropertyOptions,\n ReasonSessionEnded,\n StartSessionOptions,\n} from '../../api-sessions';\nimport type { VisibilityStateDocument } from '../../common';\nimport {\n KEY_MXL_COLD_START,\n KEY_MXL_EXPERIENCE_ID,\n KEY_MXL_FROM_STORAGE,\n KEY_MXL_NAVIGATION_SOURCE,\n KEY_MXL_REFERRER_URL,\n KEY_MXL_SDK_STARTUP_DURATION,\n KEY_MXL_SESSION_NUMBER,\n KEY_MXL_SESSION_REASON_ENDED,\n KEY_MXL_SESSION_REASON_STARTED,\n KEY_MXL_SOURCE_TAB_ID,\n KEY_MXL_STATE,\n KEY_MXL_TAB_ID,\n KEY_MXL_TYPE,\n KEY_PREFIX_MXL_PROPERTIES,\n MXL_TYPES,\n} from '../../constants';\nimport { getAppInstanceId } from '../../resources';\nimport type { PerformanceManager } from '../../utils';\nimport {\n generateUUID,\n getIncrementedCount,\n getVisibilityState,\n OTelPerformanceManager,\n} from '../../utils';\nimport type { LimitManagerInternal } from '../MXLLimitManager';\nimport { MXLExtendedSpan } from '../MXLTraceManager/MXLExtendedSpan';\nimport {\n MXL_SESSION_NUMBER_STORAGE_KEY,\n MXL_TAB_ACTIVITY_STORAGE_KEY,\n MXL_TAB_STORAGE_KEY,\n} from './constants';\nimport type {\n MXLSpanSessionManagerArgs,\n NavigationSource,\n SessionEndedListener,\n SessionStartedListener,\n SpanSessionManagerInternal,\n Tab,\n TabActivity,\n} from './types';\n\nexport class MXLSpanSessionManager implements SpanSessionManagerInternal {\n private _previousSessionId: string | null = null;\n private _activeSessionId: string | null = null;\n private _activeSessionStartTime: HrTime | null = null;\n private _sessionSpan: ExtendedSpan | null = null;\n private _activeSessionCounts: Record<string, number> | null = null;\n private _nextSessionCounts: Record<string, number> = {};\n private _coldStart = true; // Whether the session was started from a new page load or not.\n private _sdkStartupDuration = 0;\n private readonly _sessionStartedListeners: Array<SessionStartedListener> = [];\n private readonly _sessionEndedListeners: Array<SessionEndedListener> = [];\n private readonly _tab: Tab;\n private readonly _navigationSource: NavigationSource;\n private readonly _referrerInfo: {\n isValid: boolean;\n isSameOrigin: boolean;\n scrubbedUrl?: string;\n };\n\n private _tracer: Tracer;\n private readonly _noExportTracer: Tracer;\n private readonly _diag: DiagLogger;\n private readonly _perf: PerformanceManager;\n private readonly _visibilityDoc: VisibilityStateDocument;\n private readonly _storage: Storage;\n private readonly _sessionStorage: Storage;\n private readonly _limitManager: LimitManagerInternal;\n private readonly _referrer: string;\n private readonly _navigationPerformance: Pick<\n Performance,\n 'getEntriesByType'\n >;\n\n public constructor({\n diag: diagParam,\n perf,\n visibilityDoc = window.document,\n storage = window.localStorage,\n sessionStorage = window.sessionStorage,\n limitManager,\n referrer = document.referrer,\n navigationPerformance = window.performance,\n }: MXLSpanSessionManagerArgs) {\n this._diag =\n diagParam ??\n diag.createComponentLogger({\n namespace: 'MXLSpanSessionManager',\n });\n this._perf = perf ?? new OTelPerformanceManager();\n this._visibilityDoc = visibilityDoc;\n this._storage = storage;\n this._sessionStorage = sessionStorage;\n this._limitManager = limitManager;\n this._referrer = referrer;\n this._navigationPerformance = navigationPerformance;\n this._tracer = trace.getTracer('mxl-web-sdk-sessions');\n this._noExportTracer = new BasicTracerProvider().getTracer(\n 'mxl-web-sdk-sessions',\n );\n\n // Process referrer once at initialization\n this._referrerInfo = this._processReferrer();\n\n // Initialize tab tracking and navigation source\n const initResult = this._initTab();\n this._tab = initResult.tab;\n this._navigationSource = initResult.navigationSource;\n this._setupNewTabClickListeners();\n }\n\n // Collects all permanent session properties from localStorage\n private _getPermanentAttributes(): Attributes {\n const permanentAttributes = new Map();\n try {\n for (let i = 0; i < this._storage.length; i++) {\n const key = this._storage.key(i);\n if (key?.startsWith(KEY_PREFIX_MXL_PROPERTIES)) {\n const value = this._storage.getItem(key);\n if (value) {\n permanentAttributes.set(key, value);\n }\n }\n }\n } catch (error) {\n this._diag.warn('Error loading permanent session properties', error);\n }\n return Object.fromEntries(permanentAttributes.entries()) as Attributes;\n }\n\n public addBreadcrumb(name: string) {\n if (!this._sessionSpan) {\n this._diag.debug(\n 'trying to add breadcrumb to a session, but there is no session in progress. This is a no-op.',\n );\n return;\n }\n\n const limitedBreadcrumb = this._limitManager.limitBreadcrumb(name);\n\n if (limitedBreadcrumb === 'dropped') {\n return;\n }\n\n this._sessionSpan.addEvent(\n 'mxl-breadcrumb',\n {\n message: limitedBreadcrumb.name,\n },\n this._perf.getNowMillis(),\n );\n }\n\n public addProperty(\n propertyKey: string,\n value: string,\n options?: PropertyOptions,\n ) {\n if (!this._sessionSpan) {\n this._diag.debug(\n 'trying to add properties to a session, but there is no session in progress. This is a no-op.',\n );\n return;\n }\n\n const limitedSessionProperty = this._limitManager.limitSessionProperty(\n propertyKey,\n value,\n );\n\n if (limitedSessionProperty === 'dropped') {\n return;\n }\n\n const attributeKey = KEY_PREFIX_MXL_PROPERTIES + limitedSessionProperty.key;\n this._sessionSpan.setAttribute(attributeKey, limitedSessionProperty.value);\n\n if (options?.lifespan === 'permanent') {\n try {\n this._storage.setItem(attributeKey, value);\n } catch (error) {\n this._diag.warn('Failed to set permanent session property', error);\n }\n }\n }\n\n public removeProperty(propertyKey: string) {\n if (!this._sessionSpan) {\n this._diag.debug(\n 'trying to remove a session property, but there is no session in progress. This is a no-op.',\n );\n return;\n }\n\n // We truncate long session property keys on addProperty so need to apply the same logic here\n const attributeKey =\n KEY_PREFIX_MXL_PROPERTIES +\n this._limitManager.truncateString('session_property_key', propertyKey);\n this._sessionSpan.removeAttribute(attributeKey);\n\n try {\n if (this._storage.getItem(attributeKey)) {\n this._storage.removeItem(attributeKey);\n }\n } catch (error) {\n this._diag.warn('Error removing permanent session property', error);\n }\n }\n\n // the external api doesn't include a reason, and if a users uses it to end a session, the reason will be 'manual'\n // note: don't use this internally, this is just for user facing APIs. Use this.endSessionSpanInternal instead.\n public endSessionSpan() {\n this.endSessionSpanInternal('manual');\n }\n\n // endSessionSpanInternal is not part of the public API, but is used internally to end a session span adding a specific reason\n public endSessionSpanInternal(reason: ReasonSessionEnded) {\n if (!this._sessionSpan) {\n this._diag.debug(\n 'trying to end a session, but there is no session in progress. This is a no-op.',\n );\n return;\n }\n\n for (const listener of this._sessionEndedListeners) {\n try {\n listener();\n } catch (error) {\n this._diag.warn('Error while executing session ended listener', error);\n }\n }\n\n this._sessionSpan.setAttributes(this._endSessionSpanAttributes(reason));\n this._sessionSpan.end();\n this._sessionSpan = null;\n this._activeSessionStartTime = null;\n this._previousSessionId = this._activeSessionId;\n this._activeSessionId = null;\n this._activeSessionCounts = null;\n\n // For the limit manager to add a session ended listener it would need a reference to this\n // session manager which would create a circular dependency\n this._limitManager.reset();\n }\n\n private _endSessionSpanAttributes(reason: ReasonSessionEnded): Attributes {\n return {\n ...this._getPermanentAttributes(),\n [KEY_MXL_SESSION_REASON_ENDED]: reason,\n ...this._activeSessionCounts,\n ...this._limitManager.getDiagnosticCounts(),\n [KEY_MXL_SDK_STARTUP_DURATION]: this._sdkStartupDuration,\n };\n }\n\n // currentSessionAsReadableSpan creates a copy of the current session span with the same attributes\n // that endSessionSpanInternal would add, but does not affect the original session span which remains active.\n public currentSessionAsReadableSpan(\n reason: ReasonSessionEnded,\n ): ReadableSpan | null {\n if (!this._sessionSpan || !this._activeSessionStartTime) {\n this._diag.debug(\n 'trying to end a session, but there is no session in progress. This is a no-op.',\n );\n return null;\n }\n\n // Create a new span with the same name and start time as the original session span,\n // but using a new tracer so that it does not get exported.\n const span = this._noExportTracer.startSpan('mxl-session', {\n startTime: this._activeSessionStartTime,\n attributes: {\n // Copy all current attributes from the original session span, plus the ending attributes\n ...this._sessionSpan.attributes,\n ...this._endSessionSpanAttributes(reason),\n [KEY_MXL_FROM_STORAGE]: true,\n },\n });\n span.end();\n return span as unknown as ReadableSpan;\n }\n\n public getSessionId(): string | null {\n return this._activeSessionId;\n }\n\n public getPreviousSessionId(): string | null {\n return this._previousSessionId;\n }\n\n public getSessionSpan(): ExtendedSpan | null {\n return this._sessionSpan;\n }\n\n public getSessionStartTime(): HrTime | null {\n return this._activeSessionStartTime;\n }\n\n public startSessionSpan(options?: StartSessionOptions) {\n // if there is a session already in progress, end it first\n if (this._sessionSpan) {\n this.endSessionSpanInternal('manual');\n }\n\n this._activeSessionId = generateUUID();\n this._activeSessionStartTime = this._perf.getNowHRTime();\n this._activeSessionCounts = {};\n const previouslyRecordedCounts = this._nextSessionCounts;\n this._nextSessionCounts = {};\n\n const attributes: Attributes = {\n ...this._getPermanentAttributes(),\n [KEY_MXL_TYPE]: MXL_TYPES.Session,\n [KEY_MXL_STATE]: getVisibilityState(this._visibilityDoc),\n [ATTR_SESSION_ID]: this._activeSessionId,\n [KEY_MXL_COLD_START]: this._coldStart,\n [KEY_MXL_SESSION_NUMBER]: getIncrementedCount(\n this._storage,\n MXL_SESSION_NUMBER_STORAGE_KEY,\n this._diag,\n ),\n [KEY_MXL_EXPERIENCE_ID]: this._tab.experienceId,\n [KEY_MXL_TAB_ID]: this._tab.tabId,\n [KEY_MXL_NAVIGATION_SOURCE]: this._navigationSource,\n ...previouslyRecordedCounts,\n };\n\n // Add scrubbed referrer URL if available\n if (this._referrerInfo.isValid && this._referrerInfo.scrubbedUrl) {\n attributes[KEY_MXL_REFERRER_URL] = this._referrerInfo.scrubbedUrl;\n }\n\n if (this._tab.sourceTabId) {\n attributes[KEY_MXL_SOURCE_TAB_ID] = this._tab.sourceTabId;\n }\n\n const sessionStartReason = options?.reason ?? 'manual';\n attributes[KEY_MXL_SESSION_REASON_STARTED] = sessionStartReason;\n\n this._sessionSpan = new MXLExtendedSpan(\n this._tracer.startSpan('mxl-session', {\n attributes,\n }),\n );\n\n this._coldStart = false;\n\n for (const listener of this._sessionStartedListeners) {\n try {\n listener();\n } catch (error) {\n this._diag.warn(\n 'Error while executing session started listener',\n error,\n );\n }\n }\n }\n\n public incrSessionCountForKey(key: string) {\n if (!this._sessionSpan || !this._activeSessionCounts) {\n this._diag.debug(\n 'trying to increment a count for the active session, but there is no session in progress. This is a no-op.',\n );\n return;\n }\n\n this._activeSessionCounts[key] = (this._activeSessionCounts[key] || 0) + 1;\n }\n\n public incrNextSessionCountForKey(key: string) {\n this._nextSessionCounts[key] = (this._nextSessionCounts[key] || 0) + 1;\n }\n\n public addSessionStartedListener(listener: SessionStartedListener) {\n const listenerIndex = this._sessionStartedListeners.push(listener);\n\n return () => {\n this._sessionStartedListeners.splice(listenerIndex - 1, 1);\n };\n }\n\n public addSessionEndedListener(listener: SessionEndedListener) {\n const listenerIndex = this._sessionEndedListeners.push(listener);\n\n return () => {\n this._sessionEndedListeners.splice(listenerIndex - 1, 1);\n };\n }\n\n public recordSDKStartupDuration(duration: number) {\n this._sdkStartupDuration = Math.ceil(duration);\n }\n\n public setTracerProvider(tracerProvider: TracerProvider) {\n this._tracer = tracerProvider.getTracer('mxl-web-sdk-sessions');\n }\n\n private _determineNavigationSource(): NavigationSource {\n // Check Navigation Timing API first\n try {\n const navEntries =\n this._navigationPerformance.getEntriesByType('navigation');\n if (navEntries.length > 0 && navEntries[0]) {\n const navEntry = navEntries[0];\n if (navEntry.type === 'reload') {\n return 'reload';\n } else if (navEntry.type === 'back_forward') {\n return 'back_forward';\n }\n }\n } catch (error) {\n this._diag.warn('Failed to get navigation type', error);\n }\n\n // If not reload/back_forward, analyze referrer\n if (this._referrerInfo.isValid) {\n return this._referrerInfo.isSameOrigin ? 'same_origin' : 'external';\n }\n\n return 'direct';\n }\n\n private _processReferrer(): {\n isValid: boolean;\n isSameOrigin: boolean;\n scrubbedUrl?: string;\n } {\n if (!this._referrer) {\n return { isValid: false, isSameOrigin: false };\n }\n\n try {\n const referrerUrl = new URL(this._referrer);\n const currentOrigin = window.location.origin;\n\n return {\n isValid: true,\n isSameOrigin: referrerUrl.origin === currentOrigin,\n scrubbedUrl: referrerUrl.origin + referrerUrl.pathname,\n };\n } catch {\n return { isValid: false, isSameOrigin: false };\n }\n }\n\n private _getTabContext(navigationSource: NavigationSource): {\n sourceTabId?: string;\n experienceId: string;\n tabId: string;\n } {\n // Always use getAppInstanceId to ensure consistent tab ID\n const tabId = getAppInstanceId(this._sessionStorage, this._diag);\n\n // Look for source tab only if navigation is from same origin\n let sourceTabId: string | undefined;\n let experienceId: string | undefined;\n\n if (navigationSource === 'same_origin') {\n const lastActivity = this._getTabActivity();\n if (lastActivity) {\n const age = Date.now() - lastActivity.lastActivityMs;\n // 10 second window to detect source tabs - balances capturing legitimate\n // tab relationships while avoiding false positives from stale activity\n if (age <= 10_000) {\n sourceTabId = lastActivity.tabId;\n experienceId = lastActivity.experienceId;\n }\n }\n }\n\n // Only generate new UUID if we didn't inherit one from source tab\n experienceId ??= generateUUID();\n\n return {\n sourceTabId,\n experienceId,\n tabId,\n };\n }\n\n private _initTab(): { tab: Tab; navigationSource: NavigationSource } {\n // Determine navigation source once at startup\n const navigationSource = this._determineNavigationSource();\n\n // On page reload, preserve the same tab IDs\n try {\n const stored = this._sessionStorage.getItem(MXL_TAB_STORAGE_KEY);\n if (stored) {\n return {\n tab: JSON.parse(stored) as Tab,\n navigationSource,\n };\n }\n } catch (e) {\n this._diag.warn('Failed to retrieve tab data', e);\n }\n\n // Get complete navigation context for new tab\n const tabContext = this._getTabContext(navigationSource);\n const tab: Tab = {\n experienceId: tabContext.experienceId,\n sourceTabId: tabContext.sourceTabId,\n tabId: tabContext.tabId,\n };\n\n // Persist tab data for page reloads\n try {\n this._sessionStorage.setItem(MXL_TAB_STORAGE_KEY, JSON.stringify(tab));\n } catch (e) {\n this._diag.warn('Failed to store tab data', e);\n }\n\n return { tab, navigationSource };\n }\n\n private _getTabActivity(): TabActivity | null {\n try {\n const stored = this._storage.getItem(MXL_TAB_ACTIVITY_STORAGE_KEY);\n if (!stored) {\n return null;\n }\n\n return JSON.parse(stored) as TabActivity;\n } catch (e) {\n this._diag.warn('Failed to retrieve tab activity', e);\n return null;\n }\n }\n\n private _storeTabActivity(activity: TabActivity): void {\n try {\n this._storage.setItem(\n MXL_TAB_ACTIVITY_STORAGE_KEY,\n JSON.stringify(activity),\n );\n } catch (error) {\n this._diag.warn('Failed to save tab activity', error);\n }\n }\n\n private _storeCurrentTabAsSource(): void {\n const activity: TabActivity = {\n tabId: this._tab.tabId,\n experienceId: this._tab.experienceId,\n lastActivityMs: Date.now(),\n };\n\n this._storeTabActivity(activity);\n }\n\n private _setupNewTabClickListeners(): void {\n const handleNewTabClick = (ev: MouseEvent) => {\n // Check for modifier keys that open new tabs/windows\n if (\n ev.button === 1 || // Middle click\n ev.ctrlKey ||\n ev.metaKey || // Cmd/Ctrl + click\n ev.shiftKey // Shift + click (new window)\n ) {\n this._storeCurrentTabAsSource();\n return;\n }\n\n // Check for elements with attributes that open new tabs\n const newTabAnchor = (ev.target as HTMLElement | null)?.closest(\n 'a[target=\"_blank\"], form[target=\"_blank\"], a[rel*=\"noopener\"], a[rel*=\"noreferrer\"]',\n );\n if (newTabAnchor) {\n this._storeCurrentTabAsSource();\n }\n };\n\n // Capture phase ensures we record before navigation\n const options = { capture: true, passive: true };\n document.addEventListener('auxclick', handleNewTabClick, options);\n document.addEventListener('click', handleNewTabClick, options);\n }\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MXLExtendedSpan.cjs","names":["KEY_MXL_ERROR_CODE"],"sources":["../../../src/managers/MXLTraceManager/MXLExtendedSpan.ts"],"sourcesContent":["import type {\n Attributes,\n AttributeValue,\n Exception,\n Link,\n Span,\n SpanContext,\n SpanStatus,\n TimeInput,\n} from '@opentelemetry/api';\nimport type {
|
|
1
|
+
{"version":3,"file":"MXLExtendedSpan.cjs","names":["KEY_MXL_ERROR_CODE"],"sources":["../../../src/managers/MXLTraceManager/MXLExtendedSpan.ts"],"sourcesContent":["import type {\n Attributes,\n AttributeValue,\n Exception,\n Link,\n Span,\n SpanContext,\n SpanStatus,\n TimeInput,\n} from '@opentelemetry/api';\nimport type { ExtendedSpan, ExtendedSpanFailedOptions } from '../../api-traces';\nimport { KEY_MXL_ERROR_CODE } from '../../constants';\n\n/**\n * MXLSpan for the most part simply delegates to the underlying Span it receives on initialization so\n * that it satisfies the Span interface. In addition, it gives us a spot where we can implement helpers that are part\n * of the MXLSpan interface.\n */\nexport class MXLExtendedSpan implements ExtendedSpan {\n private readonly _span: ExtendedSpan;\n\n public constructor(span: Span) {\n this._span = span as ExtendedSpan;\n }\n\n /**\n * Expose attributes by extending OpenTelemetry's ReadableSpan.\n */\n public get attributes(): Attributes {\n return this._span.attributes;\n }\n\n public addEvent(\n name: string,\n attributesOrStartTime?: Attributes | TimeInput,\n startTime?: TimeInput,\n ): this {\n this._span.addEvent(name, attributesOrStartTime, startTime);\n return this;\n }\n\n public addLink(link: Link): this {\n this._span.addLink(link);\n return this;\n }\n\n public addLinks(links: Link[]): this {\n this._span.addLinks(links);\n return this;\n }\n\n public end(endTime?: TimeInput): void {\n this._span.end(endTime);\n }\n\n public isRecording(): boolean {\n return this._span.isRecording();\n }\n\n public recordException(exception: Exception, time?: TimeInput): void {\n this._span.recordException(exception, time);\n }\n\n public setAttribute(key: string, value: AttributeValue): this {\n this._span.setAttribute(key, value);\n return this;\n }\n\n public setAttributes(attributes: Attributes): this {\n this._span.setAttributes(attributes);\n return this;\n }\n\n public removeAttribute(key: string): this {\n const { [key]: _, ...attributes } = this._span.attributes;\n // @ts-expect-error Read/write spans are allowed per the spec https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/sdk.md#additional-span-interfaces\n this._span.attributes = attributes;\n return this;\n }\n\n public setStatus(status: SpanStatus): this {\n this._span.setStatus(status);\n return this;\n }\n\n public spanContext(): SpanContext {\n return this._span.spanContext();\n }\n\n public updateName(name: string): this {\n this._span.updateName(name);\n return this;\n }\n\n public fail(\n options: ExtendedSpanFailedOptions = {\n code: 'failure',\n },\n ): void {\n if (options.code) {\n this._span.setAttribute(KEY_MXL_ERROR_CODE, options.code.toUpperCase());\n }\n\n this._span.end(options.endTime);\n }\n}\n"],"mappings":";;;;;;;;AAkBA,IAAa,kBAAb,MAAqD;CACnD;CAEA,YAAmB,MAAY;AAC7B,OAAK,QAAQ;;;;;CAMf,IAAW,aAAyB;AAClC,SAAO,KAAK,MAAM;;CAGpB,SACE,MACA,uBACA,WACM;AACN,OAAK,MAAM,SAAS,MAAM,uBAAuB,UAAU;AAC3D,SAAO;;CAGT,QAAe,MAAkB;AAC/B,OAAK,MAAM,QAAQ,KAAK;AACxB,SAAO;;CAGT,SAAgB,OAAqB;AACnC,OAAK,MAAM,SAAS,MAAM;AAC1B,SAAO;;CAGT,IAAW,SAA2B;AACpC,OAAK,MAAM,IAAI,QAAQ;;CAGzB,cAA8B;AAC5B,SAAO,KAAK,MAAM,aAAa;;CAGjC,gBAAuB,WAAsB,MAAwB;AACnE,OAAK,MAAM,gBAAgB,WAAW,KAAK;;CAG7C,aAAoB,KAAa,OAA6B;AAC5D,OAAK,MAAM,aAAa,KAAK,MAAM;AACnC,SAAO;;CAGT,cAAqB,YAA8B;AACjD,OAAK,MAAM,cAAc,WAAW;AACpC,SAAO;;CAGT,gBAAuB,KAAmB;EACxC,MAAM,GAAG,MAAM,GAAG,GAAG,eAAe,KAAK,MAAM;AAE/C,OAAK,MAAM,aAAa;AACxB,SAAO;;CAGT,UAAiB,QAA0B;AACzC,OAAK,MAAM,UAAU,OAAO;AAC5B,SAAO;;CAGT,cAAkC;AAChC,SAAO,KAAK,MAAM,aAAa;;CAGjC,WAAkB,MAAoB;AACpC,OAAK,MAAM,WAAW,KAAK;AAC3B,SAAO;;CAGT,KACE,UAAqC,EACnC,MAAM,WACP,EACK;AACN,MAAI,QAAQ,KACV,MAAK,MAAM,aAAaA,6BAAAA,oBAAoB,QAAQ,KAAK,aAAa,CAAC;AAGzE,OAAK,MAAM,IAAI,QAAQ,QAAQ"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MXLExtendedSpan.d.cts","names":[],"sources":["../../../src/managers/MXLTraceManager/MXLExtendedSpan.ts"],"mappings":";;;;;;;
|
|
1
|
+
{"version":3,"file":"MXLExtendedSpan.d.cts","names":[],"sources":["../../../src/managers/MXLTraceManager/MXLExtendedSpan.ts"],"mappings":";;;;;;;AAkBA;;cAAa,eAAA,YAA2B,YAAA;EAAA,iBACrB,KAAA;cAEE,IAAA,EAAM,IAAA;EAaC;;;EAAA,IANf,UAAA,CAAA,GAAc,UAAA;EAIlB,QAAA,CACL,IAAA,UACA,qBAAA,GAAwB,UAAA,GAAa,SAAA,EACrC,SAAA,GAAY,SAAA;EAMP,OAAA,CAAQ,IAAA,EAAM,IAAA;EAKd,QAAA,CAAS,KAAA,EAAO,IAAA;EAKhB,GAAA,CAAI,OAAA,GAAU,SAAA;EAId,WAAA,CAAA;EAIA,eAAA,CAAgB,SAAA,EAAW,SAAA,EAAW,IAAA,GAAO,SAAA;EAI7C,YAAA,CAAa,GAAA,UAAa,KAAA,EAAO,cAAA;EAKjC,aAAA,CAAc,UAAA,EAAY,UAAA;EAK1B,eAAA,CAAgB,GAAA;EAOhB,SAAA,CAAU,MAAA,EAAQ,UAAA;EAKlB,WAAA,CAAA,GAAe,WAAA;EAIf,UAAA,CAAW,IAAA;EAKX,IAAA,CACL,OAAA,GAAS,yBAAA;AAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MXLExtendedSpan.d.ts","names":[],"sources":["../../../src/managers/MXLTraceManager/MXLExtendedSpan.ts"],"mappings":";;;;;;;
|
|
1
|
+
{"version":3,"file":"MXLExtendedSpan.d.ts","names":[],"sources":["../../../src/managers/MXLTraceManager/MXLExtendedSpan.ts"],"mappings":";;;;;;;AAkBA;;cAAa,eAAA,YAA2B,YAAA;EAAA,iBACrB,KAAA;cAEE,IAAA,EAAM,IAAA;EAaC;;;EAAA,IANf,UAAA,CAAA,GAAc,UAAA;EAIlB,QAAA,CACL,IAAA,UACA,qBAAA,GAAwB,UAAA,GAAa,SAAA,EACrC,SAAA,GAAY,SAAA;EAMP,OAAA,CAAQ,IAAA,EAAM,IAAA;EAKd,QAAA,CAAS,KAAA,EAAO,IAAA;EAKhB,GAAA,CAAI,OAAA,GAAU,SAAA;EAId,WAAA,CAAA;EAIA,eAAA,CAAgB,SAAA,EAAW,SAAA,EAAW,IAAA,GAAO,SAAA;EAI7C,YAAA,CAAa,GAAA,UAAa,KAAA,EAAO,cAAA;EAKjC,aAAA,CAAc,UAAA,EAAY,UAAA;EAK1B,eAAA,CAAgB,GAAA;EAOhB,SAAA,CAAU,MAAA,EAAQ,UAAA;EAKlB,WAAA,CAAA,GAAe,WAAA;EAIf,UAAA,CAAW,IAAA;EAKX,IAAA,CACL,OAAA,GAAS,yBAAA;AAAA"}
|