@sentry/react-native 6.13.0 → 7.0.0-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/RNSentry.podspec +1 -1
- package/android/build.gradle +1 -1
- package/android/src/main/java/io/sentry/react/RNSentryModuleImpl.java +11 -14
- package/android/src/main/java/io/sentry/react/RNSentryVersion.java +1 -1
- package/dist/js/client.d.ts +12 -0
- package/dist/js/client.d.ts.map +1 -1
- package/dist/js/client.js +24 -1
- package/dist/js/client.js.map +1 -1
- package/dist/js/feedback/FeedbackWidget.d.ts +1 -1
- package/dist/js/feedback/FeedbackWidget.d.ts.map +1 -1
- package/dist/js/feedback/FeedbackWidget.js +18 -17
- package/dist/js/feedback/FeedbackWidget.js.map +1 -1
- package/dist/js/feedback/FeedbackWidget.types.d.ts +29 -29
- package/dist/js/feedback/FeedbackWidget.types.d.ts.map +1 -1
- package/dist/js/feedback/FeedbackWidget.types.js.map +1 -1
- package/dist/js/feedback/FeedbackWidgetManager.d.ts.map +1 -1
- package/dist/js/feedback/FeedbackWidgetManager.js +10 -6
- package/dist/js/feedback/FeedbackWidgetManager.js.map +1 -1
- package/dist/js/feedback/defaults.d.ts +1 -1
- package/dist/js/feedback/defaults.d.ts.map +1 -1
- package/dist/js/feedback/defaults.js.map +1 -1
- package/dist/js/feedback/integration.d.ts +1 -1
- package/dist/js/feedback/integration.d.ts.map +1 -1
- package/dist/js/feedback/integration.js.map +1 -1
- package/dist/js/feedback/utils.d.ts +5 -0
- package/dist/js/feedback/utils.d.ts.map +1 -1
- package/dist/js/feedback/utils.js +10 -1
- package/dist/js/feedback/utils.js.map +1 -1
- package/dist/js/index.d.ts +2 -2
- package/dist/js/index.d.ts.map +1 -1
- package/dist/js/index.js +1 -1
- package/dist/js/index.js.map +1 -1
- package/dist/js/integrations/debugsymbolicator.js +2 -1
- package/dist/js/integrations/debugsymbolicator.js.map +1 -1
- package/dist/js/integrations/debugsymbolicatorutils.d.ts.map +1 -1
- package/dist/js/integrations/debugsymbolicatorutils.js +12 -2
- package/dist/js/integrations/debugsymbolicatorutils.js.map +1 -1
- package/dist/js/integrations/default.d.ts.map +1 -1
- package/dist/js/integrations/default.js +9 -5
- package/dist/js/integrations/default.js.map +1 -1
- package/dist/js/integrations/expocontext.d.ts +18 -0
- package/dist/js/integrations/expocontext.d.ts.map +1 -1
- package/dist/js/integrations/expocontext.js +20 -12
- package/dist/js/integrations/expocontext.js.map +1 -1
- package/dist/js/integrations/nativelinkederrors.js +4 -3
- package/dist/js/integrations/nativelinkederrors.js.map +1 -1
- package/dist/js/integrations/reactnativeerrorhandlers.d.ts.map +1 -1
- package/dist/js/integrations/reactnativeerrorhandlers.js +2 -1
- package/dist/js/integrations/reactnativeerrorhandlers.js.map +1 -1
- package/dist/js/integrations/screenshot.js +3 -3
- package/dist/js/integrations/screenshot.js.map +1 -1
- package/dist/js/integrations/spotlight.d.ts.map +1 -1
- package/dist/js/integrations/spotlight.js +8 -4
- package/dist/js/integrations/spotlight.js.map +1 -1
- package/dist/js/integrations/viewhierarchy.js +2 -1
- package/dist/js/integrations/viewhierarchy.js.map +1 -1
- package/dist/js/options.d.ts +8 -1
- package/dist/js/options.d.ts.map +1 -1
- package/dist/js/options.js.map +1 -1
- package/dist/js/profiling/cache.d.ts +1 -1
- package/dist/js/profiling/convertHermesProfile.d.ts.map +1 -1
- package/dist/js/profiling/convertHermesProfile.js +18 -5
- package/dist/js/profiling/convertHermesProfile.js.map +1 -1
- package/dist/js/profiling/debugid.d.ts.map +1 -1
- package/dist/js/profiling/debugid.js +9 -1
- package/dist/js/profiling/debugid.js.map +1 -1
- package/dist/js/profiling/hermes.d.ts +1 -1
- package/dist/js/profiling/hermes.d.ts.map +1 -1
- package/dist/js/profiling/integration.js +2 -1
- package/dist/js/profiling/integration.js.map +1 -1
- package/dist/js/profiling/utils.d.ts.map +1 -1
- package/dist/js/profiling/utils.js +15 -17
- package/dist/js/profiling/utils.js.map +1 -1
- package/dist/js/replay/CustomMask.js +1 -1
- package/dist/js/replay/CustomMask.js.map +1 -1
- package/dist/js/replay/mobilereplay.js +2 -1
- package/dist/js/replay/mobilereplay.js.map +1 -1
- package/dist/js/scopeSync.d.ts.map +1 -1
- package/dist/js/scopeSync.js +7 -1
- package/dist/js/scopeSync.js.map +1 -1
- package/dist/js/sdk.d.ts.map +1 -1
- package/dist/js/sdk.js +2 -2
- package/dist/js/sdk.js.map +1 -1
- package/dist/js/tools/ModulesCollector.js +1 -0
- package/dist/js/tools/ModulesCollector.js.map +1 -1
- package/dist/js/tools/collectModules.js +1 -0
- package/dist/js/tools/collectModules.js.map +1 -1
- package/dist/js/tools/enableLogger.js +1 -0
- package/dist/js/tools/enableLogger.js.map +1 -1
- package/dist/js/tools/metroMiddleware.js +2 -1
- package/dist/js/tools/metroMiddleware.js.map +1 -1
- package/dist/js/tools/metroconfig.js +5 -3
- package/dist/js/tools/metroconfig.js.map +1 -1
- package/dist/js/tools/sentryBabelTransformer.js +1 -0
- package/dist/js/tools/sentryBabelTransformer.js.map +1 -1
- package/dist/js/tools/sentryBabelTransformerUtils.js +1 -0
- package/dist/js/tools/sentryBabelTransformerUtils.js.map +1 -1
- package/dist/js/tools/sentryMetroSerializer.js +1 -0
- package/dist/js/tools/sentryMetroSerializer.js.map +1 -1
- package/dist/js/tools/utils.js +1 -0
- package/dist/js/tools/utils.js.map +1 -1
- package/dist/js/tools/vendor/expo/expoconfig.js +1 -0
- package/dist/js/tools/vendor/expo/expoconfig.js.map +1 -1
- package/dist/js/tools/vendor/metro/metroBabelTransformer.js +1 -0
- package/dist/js/tools/vendor/metro/metroBabelTransformer.js.map +1 -1
- package/dist/js/tools/vendor/metro/utils.js +1 -0
- package/dist/js/tools/vendor/metro/utils.js.map +1 -1
- package/dist/js/touchevents.d.ts.map +1 -1
- package/dist/js/touchevents.js +4 -0
- package/dist/js/touchevents.js.map +1 -1
- package/dist/js/tracing/integrations/appStart.d.ts +1 -1
- package/dist/js/tracing/integrations/appStart.d.ts.map +1 -1
- package/dist/js/tracing/integrations/appStart.js +9 -2
- package/dist/js/tracing/integrations/appStart.js.map +1 -1
- package/dist/js/tracing/integrations/nativeFrames.js.map +1 -1
- package/dist/js/tracing/integrations/stalltracking.d.ts +1 -1
- package/dist/js/tracing/integrations/stalltracking.d.ts.map +1 -1
- package/dist/js/tracing/integrations/timeToDisplayIntegration.d.ts.map +1 -1
- package/dist/js/tracing/integrations/timeToDisplayIntegration.js +14 -10
- package/dist/js/tracing/integrations/timeToDisplayIntegration.js.map +1 -1
- package/dist/js/tracing/onSpanEndUtils.d.ts +1 -1
- package/dist/js/tracing/onSpanEndUtils.d.ts.map +1 -1
- package/dist/js/tracing/onSpanEndUtils.js +2 -1
- package/dist/js/tracing/onSpanEndUtils.js.map +1 -1
- package/dist/js/tracing/reactnativenavigation.js +1 -1
- package/dist/js/tracing/reactnativenavigation.js.map +1 -1
- package/dist/js/tracing/reactnativeprofiler.d.ts +3 -1
- package/dist/js/tracing/reactnativeprofiler.d.ts.map +1 -1
- package/dist/js/tracing/reactnativeprofiler.js +2 -1
- package/dist/js/tracing/reactnativeprofiler.js.map +1 -1
- package/dist/js/tracing/reactnativetracing.d.ts +4 -1
- package/dist/js/tracing/reactnativetracing.d.ts.map +1 -1
- package/dist/js/tracing/reactnativetracing.js +5 -1
- package/dist/js/tracing/reactnativetracing.js.map +1 -1
- package/dist/js/tracing/reactnavigation.d.ts.map +1 -1
- package/dist/js/tracing/reactnavigation.js +5 -4
- package/dist/js/tracing/reactnavigation.js.map +1 -1
- package/dist/js/tracing/span.js +3 -3
- package/dist/js/tracing/span.js.map +1 -1
- package/dist/js/tracing/timeToDisplayFallback.d.ts +1 -1
- package/dist/js/tracing/timeToDisplayFallback.d.ts.map +1 -1
- package/dist/js/tracing/timeToDisplayFallback.js.map +1 -1
- package/dist/js/transports/encodePolyfill.d.ts.map +1 -1
- package/dist/js/transports/encodePolyfill.js +5 -5
- package/dist/js/transports/encodePolyfill.js.map +1 -1
- package/dist/js/utils/AsyncExpiringMap.d.ts.map +1 -1
- package/dist/js/utils/AsyncExpiringMap.js +8 -4
- package/dist/js/utils/AsyncExpiringMap.js.map +1 -1
- package/dist/js/utils/envelope.d.ts.map +1 -1
- package/dist/js/utils/envelope.js +1 -2
- package/dist/js/utils/envelope.js.map +1 -1
- package/dist/js/utils/environment.d.ts.map +1 -1
- package/dist/js/utils/environment.js +5 -6
- package/dist/js/utils/environment.js.map +1 -1
- package/dist/js/utils/rnlibraries.d.ts.map +1 -1
- package/dist/js/utils/rnlibraries.js +24 -0
- package/dist/js/utils/rnlibraries.js.map +1 -1
- package/dist/js/vendor/base64-js/fromByteArray.d.ts.map +1 -1
- package/dist/js/vendor/base64-js/fromByteArray.js +6 -0
- package/dist/js/vendor/base64-js/fromByteArray.js.map +1 -1
- package/dist/js/version.d.ts +1 -1
- package/dist/js/version.d.ts.map +1 -1
- package/dist/js/version.js +1 -1
- package/dist/js/version.js.map +1 -1
- package/dist/js/wrapper.js +3 -2
- package/dist/js/wrapper.js.map +1 -1
- package/ios/RNSentryVersion.m +1 -1
- package/package.json +12 -13
- package/plugin/build/withSentry.js +1 -1
- package/plugin/build/withSentryAndroidGradlePlugin.js +1 -1
- package/ts3.8/dist/js/client.d.ts +12 -0
- package/ts3.8/dist/js/feedback/FeedbackWidget.d.ts +1 -1
- package/ts3.8/dist/js/feedback/FeedbackWidget.types.d.ts +29 -29
- package/ts3.8/dist/js/feedback/defaults.d.ts +1 -1
- package/ts3.8/dist/js/feedback/integration.d.ts +1 -1
- package/ts3.8/dist/js/feedback/utils.d.ts +5 -0
- package/ts3.8/dist/js/index.d.ts +2 -2
- package/ts3.8/dist/js/integrations/expocontext.d.ts +18 -0
- package/ts3.8/dist/js/options.d.ts +8 -1
- package/ts3.8/dist/js/profiling/cache.d.ts +1 -1
- package/ts3.8/dist/js/profiling/hermes.d.ts +1 -1
- package/ts3.8/dist/js/tracing/integrations/appStart.d.ts +1 -1
- package/ts3.8/dist/js/tracing/integrations/stalltracking.d.ts +1 -1
- package/ts3.8/dist/js/tracing/onSpanEndUtils.d.ts +1 -1
- package/ts3.8/dist/js/tracing/reactnativeprofiler.d.ts +3 -1
- package/ts3.8/dist/js/tracing/reactnativetracing.d.ts +4 -1
- package/ts3.8/dist/js/tracing/timeToDisplayFallback.d.ts +1 -1
- package/ts3.8/dist/js/version.d.ts +1 -1
|
@@ -59,10 +59,19 @@ export function convertToSentryProfile(hermesProfile) {
|
|
|
59
59
|
* @returns the mapped Sentry samples, the set of Hermes stack frame IDs, and the set of JS thread IDs
|
|
60
60
|
*/
|
|
61
61
|
export function mapSamples(hermesSamples, maxElapsedSinceStartNs = MAX_PROFILE_DURATION_NS) {
|
|
62
|
+
const samples = [];
|
|
62
63
|
const jsThreads = new Set();
|
|
63
64
|
const hermesStacks = new Set();
|
|
64
|
-
const
|
|
65
|
-
|
|
65
|
+
const firstSample = hermesSamples[0];
|
|
66
|
+
if (!firstSample) {
|
|
67
|
+
logger.warn('[Profiling] No samples found in profile.');
|
|
68
|
+
return {
|
|
69
|
+
samples,
|
|
70
|
+
hermesStacks,
|
|
71
|
+
jsThreads,
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
const start = Number(firstSample.ts);
|
|
66
75
|
for (const hermesSample of hermesSamples) {
|
|
67
76
|
jsThreads.add(hermesSample.tid);
|
|
68
77
|
hermesStacks.add(hermesSample.sf);
|
|
@@ -97,8 +106,11 @@ function mapFrames(hermesStackFrames) {
|
|
|
97
106
|
if (!Object.prototype.hasOwnProperty.call(hermesStackFrames, key)) {
|
|
98
107
|
continue;
|
|
99
108
|
}
|
|
100
|
-
|
|
101
|
-
|
|
109
|
+
const hermesStackFrame = hermesStackFrames[key];
|
|
110
|
+
if (hermesStackFrame) {
|
|
111
|
+
hermesStackFrameIdToSentryFrameIdMap.set(Number(key), frames.length);
|
|
112
|
+
frames.push(parseHermesJSStackFrame(hermesStackFrame));
|
|
113
|
+
}
|
|
102
114
|
}
|
|
103
115
|
return {
|
|
104
116
|
frames,
|
|
@@ -111,6 +123,7 @@ function mapFrames(hermesStackFrames) {
|
|
|
111
123
|
* @returns the mapped Sentry stacks and a map from Hermes stack IDs to Sentry stack IDs (indices in the stacks array)
|
|
112
124
|
*/
|
|
113
125
|
function mapStacks(hermesStacks, hermesStackFrames, hermesStackFrameIdToSentryFrameIdMap) {
|
|
126
|
+
var _a;
|
|
114
127
|
const hermesStackToSentryStackMap = new Map();
|
|
115
128
|
const stacks = [];
|
|
116
129
|
for (const hermesStackFunctionFrameId of hermesStacks) {
|
|
@@ -121,7 +134,7 @@ function mapStacks(hermesStacks, hermesStackFrames, hermesStackFrameIdToSentryFr
|
|
|
121
134
|
while (currentHermesFrameId !== undefined) {
|
|
122
135
|
const sentryFrameId = hermesStackFrameIdToSentryFrameIdMap.get(currentHermesFrameId);
|
|
123
136
|
sentryFrameId !== undefined && stack.push(sentryFrameId);
|
|
124
|
-
currentHermesFrameId = hermesStackFrames[currentHermesFrameId]
|
|
137
|
+
currentHermesFrameId = (_a = hermesStackFrames[currentHermesFrameId]) === null || _a === void 0 ? void 0 : _a.parent;
|
|
125
138
|
}
|
|
126
139
|
stacks.push(stack);
|
|
127
140
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"convertHermesProfile.js","sourceRoot":"","sources":["../../../src/js/profiling/convertHermesProfile.ts"],"names":[],"mappings":"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","sourcesContent":["import type { FrameId, StackId, ThreadCpuFrame, ThreadCpuSample, ThreadCpuStack, ThreadId } from '@sentry/core';\nimport { logger } from '@sentry/core';\n\nimport { MAX_PROFILE_DURATION_MS } from './constants';\nimport type * as Hermes from './hermes';\nimport { DEFAULT_BUNDLE_NAME } from './hermes';\nimport type { RawThreadCpuProfile } from './types';\n\nconst PLACEHOLDER_THREAD_ID_STRING = '0';\nconst MS_TO_NS = 1e6;\nconst MAX_PROFILE_DURATION_NS = MAX_PROFILE_DURATION_MS * MS_TO_NS;\nconst UNKNOWN_STACK_ID = -1;\nconst JS_THREAD_NAME = 'JavaScriptThread';\nconst JS_THREAD_PRIORITY = 1;\n\n/**\n * Converts a Hermes profile to a Sentry profile.\n *\n * Maps Hermes samples to Sentry samples.\n * Maps Hermes stack frames to Sentry frames.\n * Hermes stack frame is an object representing a function call in the stack\n * with a link to its parent stack frame. Root of the represented stack tree\n * is main function call in Hermes that is [root] stack frame.\n *\n * @returns Sentry profile or null if no samples are found.\n */\nexport function convertToSentryProfile(hermesProfile: Hermes.Profile): RawThreadCpuProfile | null {\n if (hermesProfile.samples.length === 0) {\n logger.warn('[Profiling] No samples found in profile.');\n return null;\n }\n\n const { samples, hermesStacks, jsThreads } = mapSamples(hermesProfile.samples);\n\n const { frames, hermesStackFrameIdToSentryFrameIdMap } = mapFrames(hermesProfile.stackFrames);\n\n const { stacks, hermesStackToSentryStackMap } = mapStacks(\n hermesStacks,\n hermesProfile.stackFrames,\n hermesStackFrameIdToSentryFrameIdMap,\n );\n\n for (const sample of samples) {\n const sentryStackId = hermesStackToSentryStackMap.get(sample.stack_id);\n if (sentryStackId === undefined) {\n logger.error(`[Profiling] Hermes Stack ID ${sample.stack_id} not found when mapping to Sentry Stack ID.`);\n sample.stack_id = UNKNOWN_STACK_ID;\n } else {\n sample.stack_id = sentryStackId;\n }\n }\n\n const thread_metadata: Record<ThreadId, { name?: string; priority?: number }> = {};\n for (const jsThreadId of jsThreads) {\n thread_metadata[jsThreadId] = {\n name: JS_THREAD_NAME,\n priority: JS_THREAD_PRIORITY,\n };\n }\n const active_thread_id = Object.keys(thread_metadata)[0] || PLACEHOLDER_THREAD_ID_STRING;\n\n return {\n samples,\n frames,\n stacks,\n thread_metadata,\n active_thread_id,\n };\n}\n\n/**\n * Maps Hermes samples to Sentry samples.\n * Calculates the elapsed time since the first sample based on the absolute timestamps of the Hermes samples.\n * Hermes stack frame IDs represent the last (leaf, furthest from the main func) frame of the call stack.\n * @returns the mapped Sentry samples, the set of Hermes stack frame IDs, and the set of JS thread IDs\n */\nexport function mapSamples(\n hermesSamples: Hermes.Sample[],\n maxElapsedSinceStartNs: number = MAX_PROFILE_DURATION_NS,\n): {\n samples: ThreadCpuSample[];\n hermesStacks: Set<Hermes.StackFrameId>;\n jsThreads: Set<ThreadId>;\n} {\n const jsThreads = new Set<ThreadId>();\n const hermesStacks = new Set<Hermes.StackFrameId>();\n\n const start = Number(hermesSamples[0].ts);\n const samples: ThreadCpuSample[] = [];\n for (const hermesSample of hermesSamples) {\n jsThreads.add(hermesSample.tid);\n hermesStacks.add(hermesSample.sf);\n\n const elapsed_since_start_ns = (Number(hermesSample.ts) - start) * 1e3;\n if (elapsed_since_start_ns >= maxElapsedSinceStartNs) {\n logger.warn(\n `[Profiling] Sample has elapsed time since start ${elapsed_since_start_ns}ns ` +\n `greater than the max elapsed time ${maxElapsedSinceStartNs}ns.`,\n );\n break;\n }\n\n samples.push({\n stack_id: hermesSample.sf,\n thread_id: hermesSample.tid,\n elapsed_since_start_ns: elapsed_since_start_ns.toFixed(0),\n });\n }\n\n return {\n samples,\n hermesStacks,\n jsThreads,\n };\n}\n\n/**\n * Maps Hermes StackFrames tree represented as an JS object to a Sentry frames array.\n * Converts line and columns strings to numbers.\n * @returns the mapped Sentry frames\n */\nfunction mapFrames(hermesStackFrames: Record<Hermes.StackFrameId, Hermes.StackFrame>): {\n frames: ThreadCpuFrame[];\n hermesStackFrameIdToSentryFrameIdMap: Map<Hermes.StackFrameId, FrameId>;\n} {\n const frames: ThreadCpuFrame[] = [];\n const hermesStackFrameIdToSentryFrameIdMap = new Map<Hermes.StackFrameId, FrameId>();\n for (const key in hermesStackFrames) {\n // asc order based on the key is not guaranteed\n if (!Object.prototype.hasOwnProperty.call(hermesStackFrames, key)) {\n continue;\n }\n hermesStackFrameIdToSentryFrameIdMap.set(Number(key), frames.length);\n frames.push(parseHermesJSStackFrame(hermesStackFrames[key]));\n }\n\n return {\n frames,\n hermesStackFrameIdToSentryFrameIdMap,\n };\n}\n\n/**\n * Maps Hermes stack frame IDs to Sentry stack arrays.\n * Hermes stack frame IDs represent the last (leaf, furthest from the main func) frame of the call stack.\n * @returns the mapped Sentry stacks and a map from Hermes stack IDs to Sentry stack IDs (indices in the stacks array)\n */\nfunction mapStacks(\n hermesStacks: Set<Hermes.StackFrameId>,\n hermesStackFrames: Record<Hermes.StackFrameId, Hermes.StackFrame>,\n hermesStackFrameIdToSentryFrameIdMap: Map<Hermes.StackFrameId, FrameId>,\n): {\n stacks: ThreadCpuStack[];\n hermesStackToSentryStackMap: Map<Hermes.StackFrameId, StackId>;\n} {\n const hermesStackToSentryStackMap = new Map<Hermes.StackFrameId, StackId>();\n const stacks: ThreadCpuStack[] = [];\n for (const hermesStackFunctionFrameId of hermesStacks) {\n const stackId = stacks.length;\n hermesStackToSentryStackMap.set(hermesStackFunctionFrameId, stackId);\n const stack: ThreadCpuStack = [];\n let currentHermesFrameId: Hermes.StackFrameId | undefined = hermesStackFunctionFrameId;\n while (currentHermesFrameId !== undefined) {\n const sentryFrameId = hermesStackFrameIdToSentryFrameIdMap.get(currentHermesFrameId);\n sentryFrameId !== undefined && stack.push(sentryFrameId);\n currentHermesFrameId = hermesStackFrames[currentHermesFrameId] && hermesStackFrames[currentHermesFrameId].parent;\n }\n stacks.push(stack);\n }\n\n return {\n stacks,\n hermesStackToSentryStackMap,\n };\n}\n\n/**\n * Parses Hermes StackFrame to Sentry StackFrame.\n * For native frames only function name is returned, for Hermes bytecode the line and column are calculated.\n */\nexport function parseHermesJSStackFrame(frame: Hermes.StackFrame): ThreadCpuFrame {\n if (frame.category !== 'JavaScript') {\n // Native\n if (frame.name === '[root]') {\n return { function: frame.name, in_app: false };\n }\n return { function: frame.name };\n }\n\n if (frame.funcVirtAddr !== undefined && frame.offset !== undefined) {\n // Hermes Bytecode\n return {\n function: frame.name,\n abs_path: DEFAULT_BUNDLE_NAME,\n // https://github.com/krystofwoldrich/metro/blob/417e6f276ff9422af6039fc4d1bce41fcf7d9f46/packages/metro-symbolicate/src/Symbolication.js#L298-L301\n // Hermes lineno is hardcoded 1, currently only one bundle symbolication is supported by metro-symbolicate and thus by us.\n lineno: 1,\n // Hermes colno is 0-based, while Sentry is 1-based\n colno: Number(frame.funcVirtAddr) + Number(frame.offset) + 1,\n };\n }\n\n // JavaScript\n const indexOfLeftParenthesis = frame.name.indexOf('(');\n return {\n function: indexOfLeftParenthesis !== -1 ? frame.name.substring(0, indexOfLeftParenthesis) || undefined : frame.name,\n abs_path: DEFAULT_BUNDLE_NAME,\n lineno: frame.line !== undefined ? Number(frame.line) : undefined,\n colno: frame.column !== undefined ? Number(frame.column) : undefined,\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"convertHermesProfile.js","sourceRoot":"","sources":["../../../src/js/profiling/convertHermesProfile.ts"],"names":[],"mappings":"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","sourcesContent":["import type { FrameId, StackId, ThreadCpuFrame, ThreadCpuSample, ThreadCpuStack, ThreadId } from '@sentry/core';\nimport { logger } from '@sentry/core';\n\nimport { MAX_PROFILE_DURATION_MS } from './constants';\nimport type * as Hermes from './hermes';\nimport { DEFAULT_BUNDLE_NAME } from './hermes';\nimport type { RawThreadCpuProfile } from './types';\n\nconst PLACEHOLDER_THREAD_ID_STRING = '0';\nconst MS_TO_NS = 1e6;\nconst MAX_PROFILE_DURATION_NS = MAX_PROFILE_DURATION_MS * MS_TO_NS;\nconst UNKNOWN_STACK_ID = -1;\nconst JS_THREAD_NAME = 'JavaScriptThread';\nconst JS_THREAD_PRIORITY = 1;\n\n/**\n * Converts a Hermes profile to a Sentry profile.\n *\n * Maps Hermes samples to Sentry samples.\n * Maps Hermes stack frames to Sentry frames.\n * Hermes stack frame is an object representing a function call in the stack\n * with a link to its parent stack frame. Root of the represented stack tree\n * is main function call in Hermes that is [root] stack frame.\n *\n * @returns Sentry profile or null if no samples are found.\n */\nexport function convertToSentryProfile(hermesProfile: Hermes.Profile): RawThreadCpuProfile | null {\n if (hermesProfile.samples.length === 0) {\n logger.warn('[Profiling] No samples found in profile.');\n return null;\n }\n\n const { samples, hermesStacks, jsThreads } = mapSamples(hermesProfile.samples);\n\n const { frames, hermesStackFrameIdToSentryFrameIdMap } = mapFrames(hermesProfile.stackFrames);\n\n const { stacks, hermesStackToSentryStackMap } = mapStacks(\n hermesStacks,\n hermesProfile.stackFrames,\n hermesStackFrameIdToSentryFrameIdMap,\n );\n\n for (const sample of samples) {\n const sentryStackId = hermesStackToSentryStackMap.get(sample.stack_id);\n if (sentryStackId === undefined) {\n logger.error(`[Profiling] Hermes Stack ID ${sample.stack_id} not found when mapping to Sentry Stack ID.`);\n sample.stack_id = UNKNOWN_STACK_ID;\n } else {\n sample.stack_id = sentryStackId;\n }\n }\n\n const thread_metadata: Record<ThreadId, { name?: string; priority?: number }> = {};\n for (const jsThreadId of jsThreads) {\n thread_metadata[jsThreadId] = {\n name: JS_THREAD_NAME,\n priority: JS_THREAD_PRIORITY,\n };\n }\n const active_thread_id = Object.keys(thread_metadata)[0] || PLACEHOLDER_THREAD_ID_STRING;\n\n return {\n samples,\n frames,\n stacks,\n thread_metadata,\n active_thread_id,\n };\n}\n\n/**\n * Maps Hermes samples to Sentry samples.\n * Calculates the elapsed time since the first sample based on the absolute timestamps of the Hermes samples.\n * Hermes stack frame IDs represent the last (leaf, furthest from the main func) frame of the call stack.\n * @returns the mapped Sentry samples, the set of Hermes stack frame IDs, and the set of JS thread IDs\n */\nexport function mapSamples(\n hermesSamples: Hermes.Sample[],\n maxElapsedSinceStartNs: number = MAX_PROFILE_DURATION_NS,\n): {\n samples: ThreadCpuSample[];\n hermesStacks: Set<Hermes.StackFrameId>;\n jsThreads: Set<ThreadId>;\n} {\n const samples: ThreadCpuSample[] = [];\n const jsThreads = new Set<ThreadId>();\n const hermesStacks = new Set<Hermes.StackFrameId>();\n\n const firstSample = hermesSamples[0];\n if (!firstSample) {\n logger.warn('[Profiling] No samples found in profile.');\n return {\n samples,\n hermesStacks,\n jsThreads,\n };\n }\n\n const start = Number(firstSample.ts);\n for (const hermesSample of hermesSamples) {\n jsThreads.add(hermesSample.tid);\n hermesStacks.add(hermesSample.sf);\n\n const elapsed_since_start_ns = (Number(hermesSample.ts) - start) * 1e3;\n if (elapsed_since_start_ns >= maxElapsedSinceStartNs) {\n logger.warn(\n `[Profiling] Sample has elapsed time since start ${elapsed_since_start_ns}ns ` +\n `greater than the max elapsed time ${maxElapsedSinceStartNs}ns.`,\n );\n break;\n }\n\n samples.push({\n stack_id: hermesSample.sf,\n thread_id: hermesSample.tid,\n elapsed_since_start_ns: elapsed_since_start_ns.toFixed(0),\n });\n }\n\n return {\n samples,\n hermesStacks,\n jsThreads,\n };\n}\n\n/**\n * Maps Hermes StackFrames tree represented as an JS object to a Sentry frames array.\n * Converts line and columns strings to numbers.\n * @returns the mapped Sentry frames\n */\nfunction mapFrames(hermesStackFrames: Record<Hermes.StackFrameId, Hermes.StackFrame>): {\n frames: ThreadCpuFrame[];\n hermesStackFrameIdToSentryFrameIdMap: Map<Hermes.StackFrameId, FrameId>;\n} {\n const frames: ThreadCpuFrame[] = [];\n const hermesStackFrameIdToSentryFrameIdMap = new Map<Hermes.StackFrameId, FrameId>();\n for (const key in hermesStackFrames) {\n // asc order based on the key is not guaranteed\n if (!Object.prototype.hasOwnProperty.call(hermesStackFrames, key)) {\n continue;\n }\n\n const hermesStackFrame = hermesStackFrames[key];\n if (hermesStackFrame) {\n hermesStackFrameIdToSentryFrameIdMap.set(Number(key), frames.length);\n frames.push(parseHermesJSStackFrame(hermesStackFrame));\n }\n }\n\n return {\n frames,\n hermesStackFrameIdToSentryFrameIdMap,\n };\n}\n\n/**\n * Maps Hermes stack frame IDs to Sentry stack arrays.\n * Hermes stack frame IDs represent the last (leaf, furthest from the main func) frame of the call stack.\n * @returns the mapped Sentry stacks and a map from Hermes stack IDs to Sentry stack IDs (indices in the stacks array)\n */\nfunction mapStacks(\n hermesStacks: Set<Hermes.StackFrameId>,\n hermesStackFrames: Record<Hermes.StackFrameId, Hermes.StackFrame>,\n hermesStackFrameIdToSentryFrameIdMap: Map<Hermes.StackFrameId, FrameId>,\n): {\n stacks: ThreadCpuStack[];\n hermesStackToSentryStackMap: Map<Hermes.StackFrameId, StackId>;\n} {\n const hermesStackToSentryStackMap = new Map<Hermes.StackFrameId, StackId>();\n const stacks: ThreadCpuStack[] = [];\n for (const hermesStackFunctionFrameId of hermesStacks) {\n const stackId = stacks.length;\n hermesStackToSentryStackMap.set(hermesStackFunctionFrameId, stackId);\n const stack: ThreadCpuStack = [];\n let currentHermesFrameId: Hermes.StackFrameId | undefined = hermesStackFunctionFrameId;\n while (currentHermesFrameId !== undefined) {\n const sentryFrameId = hermesStackFrameIdToSentryFrameIdMap.get(currentHermesFrameId);\n sentryFrameId !== undefined && stack.push(sentryFrameId);\n currentHermesFrameId = hermesStackFrames[currentHermesFrameId]?.parent;\n }\n stacks.push(stack);\n }\n\n return {\n stacks,\n hermesStackToSentryStackMap,\n };\n}\n\n/**\n * Parses Hermes StackFrame to Sentry StackFrame.\n * For native frames only function name is returned, for Hermes bytecode the line and column are calculated.\n */\nexport function parseHermesJSStackFrame(frame: Hermes.StackFrame): ThreadCpuFrame {\n if (frame.category !== 'JavaScript') {\n // Native\n if (frame.name === '[root]') {\n return { function: frame.name, in_app: false };\n }\n return { function: frame.name };\n }\n\n if (frame.funcVirtAddr !== undefined && frame.offset !== undefined) {\n // Hermes Bytecode\n return {\n function: frame.name,\n abs_path: DEFAULT_BUNDLE_NAME,\n // https://github.com/krystofwoldrich/metro/blob/417e6f276ff9422af6039fc4d1bce41fcf7d9f46/packages/metro-symbolicate/src/Symbolication.js#L298-L301\n // Hermes lineno is hardcoded 1, currently only one bundle symbolication is supported by metro-symbolicate and thus by us.\n lineno: 1,\n // Hermes colno is 0-based, while Sentry is 1-based\n colno: Number(frame.funcVirtAddr) + Number(frame.offset) + 1,\n };\n }\n\n // JavaScript\n const indexOfLeftParenthesis = frame.name.indexOf('(');\n return {\n function: indexOfLeftParenthesis !== -1 ? frame.name.substring(0, indexOfLeftParenthesis) || undefined : frame.name,\n abs_path: DEFAULT_BUNDLE_NAME,\n lineno: frame.line !== undefined ? Number(frame.line) : undefined,\n colno: frame.column !== undefined ? Number(frame.column) : undefined,\n };\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"debugid.d.ts","sourceRoot":"","sources":["../../../src/js/profiling/debugid.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAK/C;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,UAAU,EAAE,
|
|
1
|
+
{"version":3,"file":"debugid.d.ts","sourceRoot":"","sources":["../../../src/js/profiling/debugid.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAK/C;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,UAAU,EAAE,CAsC/C"}
|
|
@@ -17,11 +17,19 @@ export function getDebugMetadata() {
|
|
|
17
17
|
}
|
|
18
18
|
if (debugIdsKeys.length > 1) {
|
|
19
19
|
logger.warn('[Profiling] Multiple debug images found, but only one one bundle is supported. Using the first one...');
|
|
20
|
+
return [];
|
|
21
|
+
}
|
|
22
|
+
if (!debugIdsKeys[0]) {
|
|
23
|
+
return [];
|
|
24
|
+
}
|
|
25
|
+
const debugId = debugIdMap[debugIdsKeys[0]];
|
|
26
|
+
if (!debugId) {
|
|
27
|
+
return [];
|
|
20
28
|
}
|
|
21
29
|
return [
|
|
22
30
|
{
|
|
23
31
|
code_file: DEFAULT_BUNDLE_NAME,
|
|
24
|
-
debug_id:
|
|
32
|
+
debug_id: debugId,
|
|
25
33
|
type: 'sourcemap',
|
|
26
34
|
},
|
|
27
35
|
];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"debugid.js","sourceRoot":"","sources":["../../../src/js/profiling/debugid.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAElD,OAAO,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAE/C;;GAEG;AACH,MAAM,UAAU,gBAAgB;IAC9B,IAAI,CAAC,mBAAmB,EAAE;QACxB,OAAO,EAAE,CAAC;KACX;IAED,MAAM,UAAU,GAAG,UAAU,CAAC,eAAe,CAAC;IAC9C,IAAI,CAAC,UAAU,EAAE;QACf,OAAO,EAAE,CAAC;KACX;IAED,MAAM,YAAY,GAAG,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IAC7C,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE;QACxB,OAAO,EAAE,CAAC;KACX;IAED,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE;QAC3B,MAAM,CAAC,IAAI,CACT,uGAAuG,CACxG,CAAC;
|
|
1
|
+
{"version":3,"file":"debugid.js","sourceRoot":"","sources":["../../../src/js/profiling/debugid.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAElD,OAAO,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAE/C;;GAEG;AACH,MAAM,UAAU,gBAAgB;IAC9B,IAAI,CAAC,mBAAmB,EAAE;QACxB,OAAO,EAAE,CAAC;KACX;IAED,MAAM,UAAU,GAAG,UAAU,CAAC,eAAe,CAAC;IAC9C,IAAI,CAAC,UAAU,EAAE;QACf,OAAO,EAAE,CAAC;KACX;IAED,MAAM,YAAY,GAAG,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IAC7C,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE;QACxB,OAAO,EAAE,CAAC;KACX;IAED,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE;QAC3B,MAAM,CAAC,IAAI,CACT,uGAAuG,CACxG,CAAC;QACF,OAAO,EAAE,CAAC;KACX;IAED,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE;QACpB,OAAO,EAAE,CAAC;KACX;IAED,MAAM,OAAO,GAAG,UAAU,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC;IAC5C,IAAI,CAAC,OAAO,EAAE;QACZ,OAAO,EAAE,CAAC;KACX;IAED,OAAO;QACL;YACE,SAAS,EAAE,mBAAmB;YAC9B,QAAQ,EAAE,OAAO;YACjB,IAAI,EAAE,WAAW;SAClB;KACF,CAAC;AACJ,CAAC","sourcesContent":["import type { DebugImage } from '@sentry/core';\nimport { GLOBAL_OBJ, logger } from '@sentry/core';\n\nimport { DEFAULT_BUNDLE_NAME } from './hermes';\n\n/**\n * Returns debug meta images of the loaded bundle.\n */\nexport function getDebugMetadata(): DebugImage[] {\n if (!DEFAULT_BUNDLE_NAME) {\n return [];\n }\n\n const debugIdMap = GLOBAL_OBJ._sentryDebugIds;\n if (!debugIdMap) {\n return [];\n }\n\n const debugIdsKeys = Object.keys(debugIdMap);\n if (!debugIdsKeys.length) {\n return [];\n }\n\n if (debugIdsKeys.length > 1) {\n logger.warn(\n '[Profiling] Multiple debug images found, but only one one bundle is supported. Using the first one...',\n );\n return [];\n }\n\n if (!debugIdsKeys[0]) {\n return [];\n }\n\n const debugId = debugIdMap[debugIdsKeys[0]];\n if (!debugId) {\n return [];\n }\n\n return [\n {\n code_file: DEFAULT_BUNDLE_NAME,\n debug_id: debugId,\n type: 'sourcemap',\n },\n ];\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hermes.d.ts","sourceRoot":"","sources":["../../../src/js/profiling/hermes.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,YAAY,GAAG,MAAM,CAAC;AAClC,MAAM,MAAM,qBAAqB,GAAG,MAAM,CAAC;AAE3C,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,EAAE,EAAE,qBAAqB,CAAC;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE;QACJ,IAAI,CAAC,EAAE,MAAM,CAAC;KACf,CAAC;CACH;AAED,MAAM,WAAW,MAAM;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,qBAAqB,CAAC;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,EAAE,EAAE,YAAY,CAAC;CAClB;AAED,MAAM,WAAW,UAAU;IAEzB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC;IAGhB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IAGpB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,OAAO;IACtB,WAAW,EAAE,UAAU,EAAE,CAAC;IAC1B,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;CACzC;AAED,eAAO,MAAM,mBAAmB,
|
|
1
|
+
{"version":3,"file":"hermes.d.ts","sourceRoot":"","sources":["../../../src/js/profiling/hermes.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,YAAY,GAAG,MAAM,CAAC;AAClC,MAAM,MAAM,qBAAqB,GAAG,MAAM,CAAC;AAE3C,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,EAAE,EAAE,qBAAqB,CAAC;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE;QACJ,IAAI,CAAC,EAAE,MAAM,CAAC;KACf,CAAC;CACH;AAED,MAAM,WAAW,MAAM;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,qBAAqB,CAAC;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,EAAE,EAAE,YAAY,CAAC;CAClB;AAED,MAAM,WAAW,UAAU;IAEzB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC;IAGhB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IAGpB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,OAAO;IACtB,WAAW,EAAE,UAAU,EAAE,CAAC;IAC1B,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;CACzC;AAED,eAAO,MAAM,mBAAmB,oBACuF,CAAC"}
|
|
@@ -78,12 +78,13 @@ export const hermesProfilingIntegration = (initOptions = defaultOptions) => {
|
|
|
78
78
|
_startNewProfile(activeSpan);
|
|
79
79
|
};
|
|
80
80
|
const _shouldStartProfiling = (activeSpan) => {
|
|
81
|
+
var _a;
|
|
81
82
|
if (!spanIsSampled(activeSpan)) {
|
|
82
83
|
logger.log('[Profiling] Transaction is not sampled, skipping profiling');
|
|
83
84
|
return false;
|
|
84
85
|
}
|
|
85
86
|
const client = getClient();
|
|
86
|
-
const options = client
|
|
87
|
+
const options = (_a = client === null || client === void 0 ? void 0 : client.getOptions) === null || _a === void 0 ? void 0 : _a.call(client);
|
|
87
88
|
const profilesSampleRate = options && typeof options.profilesSampleRate === 'number' ? options.profilesSampleRate : undefined;
|
|
88
89
|
if (profilesSampleRate === undefined) {
|
|
89
90
|
logger.log('[Profiling] Profiling disabled, enable it by setting `profilesSampleRate` option to SDK init call.');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"integration.js","sourceRoot":"","sources":["../../../src/js/profiling/integration.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable complexity */\nimport type { Envelope, Event, Integration, Span, ThreadCpuProfile } from '@sentry/core';\nimport { getActiveSpan, getClient, logger, spanIsSampled, uuid4 } from '@sentry/core';\nimport { Platform } from 'react-native';\n\nimport type { ReactNativeClient } from '../client';\nimport { isHermesEnabled } from '../utils/environment';\nimport { isRootSpan } from '../utils/span';\nimport { NATIVE } from '../wrapper';\nimport { PROFILE_QUEUE } from './cache';\nimport { MAX_PROFILE_DURATION_MS } from './constants';\nimport { convertToSentryProfile } from './convertHermesProfile';\nimport type { NativeAndroidProfileEvent, NativeProfileEvent } from './nativeTypes';\nimport type { AndroidCombinedProfileEvent, CombinedProfileEvent, HermesProfileEvent, ProfileEvent } from './types';\nimport {\n addProfilesToEnvelope,\n createHermesProfilingEvent,\n enrichCombinedProfileWithEventContext,\n findProfiledTransactionsFromEnvelope,\n} from './utils';\n\nconst INTEGRATION_NAME = 'HermesProfiling';\n\nconst MS_TO_NS: number = 1e6;\n\nexport interface HermesProfilingOptions {\n /**\n * Enable or disable profiling of native (iOS and Android) threads\n *\n * @default true\n */\n platformProfilers?: boolean;\n}\n\nconst defaultOptions: Required<HermesProfilingOptions> = {\n platformProfilers: true,\n};\n\n/**\n * Profiling integration creates a profile for each transaction and adds it to the event envelope.\n *\n * @experimental\n */\nexport const hermesProfilingIntegration = (initOptions: HermesProfilingOptions = defaultOptions): Integration => {\n const usePlatformProfilers = initOptions.platformProfilers ?? true;\n let _currentProfile:\n | {\n span_id: string;\n profile_id: string;\n startTimestampNs: number;\n }\n | undefined;\n let _currentProfileTimeout: ReturnType<typeof setTimeout> | undefined;\n let isReady: boolean = false;\n\n const setupOnce = (): void => {\n if (isReady) {\n return;\n }\n isReady = true;\n\n if (!isHermesEnabled()) {\n logger.log('[Profiling] Hermes is not enabled, not adding profiling integration.');\n return;\n }\n\n const client = getClient();\n\n if (!client || typeof client.on !== 'function') {\n return;\n }\n\n _startCurrentProfileForActiveTransaction();\n client.on('spanStart', _startCurrentProfile);\n\n client.on('spanEnd', _finishCurrentProfileForSpan);\n\n client.on('beforeEnvelope', (envelope: Envelope) => {\n if (!PROFILE_QUEUE.size()) {\n return;\n }\n\n const profiledTransactions = findProfiledTransactionsFromEnvelope(envelope);\n if (!profiledTransactions.length) {\n logger.log('[Profiling] no profiled transactions found in envelope');\n return;\n }\n\n const profilesToAddToEnvelope: ProfileEvent[] = [];\n for (const profiledTransaction of profiledTransactions) {\n const profile = _createProfileEventFor(profiledTransaction);\n if (profile) {\n profilesToAddToEnvelope.push(profile);\n }\n }\n addProfilesToEnvelope(envelope, profilesToAddToEnvelope);\n });\n };\n\n const _startCurrentProfileForActiveTransaction = (): void => {\n if (_currentProfile) {\n return;\n }\n const activeSpan = getActiveSpan();\n activeSpan && _startCurrentProfile(activeSpan);\n };\n\n const _startCurrentProfile = (activeSpan: Span): void => {\n if (!isRootSpan(activeSpan)) {\n return;\n }\n\n _finishCurrentProfile();\n\n const shouldStartProfiling = _shouldStartProfiling(activeSpan);\n if (!shouldStartProfiling) {\n return;\n }\n\n _currentProfileTimeout = setTimeout(_finishCurrentProfile, MAX_PROFILE_DURATION_MS);\n _startNewProfile(activeSpan);\n };\n\n const _shouldStartProfiling = (activeSpan: Span): boolean => {\n if (!spanIsSampled(activeSpan)) {\n logger.log('[Profiling] Transaction is not sampled, skipping profiling');\n return false;\n }\n\n const client = getClient<ReactNativeClient>();\n const options = client && client.getOptions();\n\n const profilesSampleRate =\n options && typeof options.profilesSampleRate === 'number' ? options.profilesSampleRate : undefined;\n if (profilesSampleRate === undefined) {\n logger.log('[Profiling] Profiling disabled, enable it by setting `profilesSampleRate` option to SDK init call.');\n return false;\n }\n\n // Check if we should sample this profile\n if (Math.random() > profilesSampleRate) {\n logger.log('[Profiling] Skip profiling transaction due to sampling.');\n return false;\n }\n\n return true;\n };\n\n /**\n * Starts a new profile and links it to the transaction.\n */\n const _startNewProfile = (activeSpan: Span): void => {\n const profileStartTimestampNs = startProfiling(usePlatformProfilers);\n if (!profileStartTimestampNs) {\n return;\n }\n\n _currentProfile = {\n span_id: activeSpan.spanContext().spanId,\n profile_id: uuid4(),\n startTimestampNs: profileStartTimestampNs,\n };\n activeSpan.setAttribute('profile_id', _currentProfile.profile_id);\n logger.log('[Profiling] started profiling: ', _currentProfile.profile_id);\n };\n\n /**\n * Stops current profile if the ending span is the currently profiled span.\n */\n const _finishCurrentProfileForSpan = (span: Span): void => {\n if (!isRootSpan(span)) {\n return;\n }\n\n if (span.spanContext().spanId !== _currentProfile?.span_id) {\n logger.log(\n `[Profiling] Span (${span.spanContext().spanId}) ended is not the currently profiled span (${\n _currentProfile?.span_id\n }). Not stopping profiling.`,\n );\n return;\n }\n\n _finishCurrentProfile();\n };\n\n /**\n * Stops profiling and adds the profile to the queue to be processed on beforeEnvelope.\n */\n const _finishCurrentProfile = (): void => {\n _clearCurrentProfileTimeout();\n if (_currentProfile === undefined) {\n return;\n }\n\n const profile = stopProfiling(_currentProfile.startTimestampNs);\n if (!profile) {\n logger.warn('[Profiling] Stop failed. Cleaning up...');\n _currentProfile = undefined;\n return;\n }\n\n PROFILE_QUEUE.add(_currentProfile.profile_id, profile);\n\n logger.log('[Profiling] finished profiling: ', _currentProfile.profile_id);\n _currentProfile = undefined;\n };\n\n const _createProfileEventFor = (profiledTransaction: Event): ProfileEvent | null => {\n const profile_id = profiledTransaction?.contexts?.trace?.data?.profile_id;\n\n if (typeof profile_id !== 'string') {\n logger.log('[Profiling] cannot find profile for a transaction without a profile context');\n return null;\n }\n\n // Remove the profile from the transaction context before sending, relay will take care of the rest.\n if (profiledTransaction?.contexts?.trace?.data?.profile_id) {\n delete profiledTransaction.contexts.trace.data.profile_id;\n }\n\n const profile = PROFILE_QUEUE.get(profile_id);\n PROFILE_QUEUE.delete(profile_id);\n\n if (!profile) {\n logger.log(`[Profiling] cannot find profile ${profile_id} for transaction ${profiledTransaction.event_id}`);\n return null;\n }\n\n const profileWithEvent = enrichCombinedProfileWithEventContext(profile_id, profile, profiledTransaction);\n logger.log(`[Profiling] Created profile ${profile_id} for transaction ${profiledTransaction.event_id}`);\n\n return profileWithEvent;\n };\n\n const _clearCurrentProfileTimeout = (): void => {\n _currentProfileTimeout !== undefined && clearTimeout(_currentProfileTimeout);\n _currentProfileTimeout = undefined;\n };\n\n return {\n name: INTEGRATION_NAME,\n setupOnce,\n };\n};\n\n/**\n * Starts Profilers and returns the timestamp when profiling started in nanoseconds.\n */\nexport function startProfiling(platformProfilers: boolean): number | null {\n const started = NATIVE.startProfiling(platformProfilers);\n if (!started) {\n return null;\n }\n\n return Date.now() * MS_TO_NS;\n}\n\n/**\n * Stops Profilers and returns collected combined profile.\n */\nexport function stopProfiling(\n profileStartTimestampNs: number,\n): CombinedProfileEvent | AndroidCombinedProfileEvent | null {\n const collectedProfiles = NATIVE.stopProfiling();\n if (!collectedProfiles) {\n return null;\n }\n const profileEndTimestampNs = Date.now() * MS_TO_NS;\n\n const hermesProfile = convertToSentryProfile(collectedProfiles.hermesProfile);\n if (!hermesProfile) {\n return null;\n }\n\n const hermesProfileEvent = createHermesProfilingEvent(hermesProfile);\n if (!hermesProfileEvent) {\n return null;\n }\n\n if (collectedProfiles.androidProfile) {\n const durationNs = profileEndTimestampNs - profileStartTimestampNs;\n return createAndroidWithHermesProfile(hermesProfileEvent, collectedProfiles.androidProfile, durationNs);\n } else if (collectedProfiles.nativeProfile) {\n return addNativeProfileToHermesProfile(hermesProfileEvent, collectedProfiles.nativeProfile);\n }\n\n return hermesProfileEvent;\n}\n\n/**\n * Creates Android profile event with attached javascript profile.\n */\nexport function createAndroidWithHermesProfile(\n hermes: HermesProfileEvent,\n nativeAndroid: NativeAndroidProfileEvent,\n durationNs: number,\n): AndroidCombinedProfileEvent {\n return {\n ...nativeAndroid,\n platform: 'android',\n js_profile: hermes.profile,\n duration_ns: durationNs.toString(10),\n active_thread_id: hermes.transaction.active_thread_id,\n };\n}\n\n/**\n * Merges Hermes and Native profile events into one.\n */\nexport function addNativeProfileToHermesProfile(\n hermes: HermesProfileEvent,\n native: NativeProfileEvent,\n): CombinedProfileEvent {\n return {\n ...hermes,\n profile: addNativeThreadCpuProfileToHermes(hermes.profile, native.profile, hermes.transaction.active_thread_id),\n ...(native.debug_meta?.images ? { debug_meta: { images: native.debug_meta.images } } : {}),\n measurements: native.measurements,\n };\n}\n\n/**\n * Merges Hermes And Native profiles into one.\n */\nexport function addNativeThreadCpuProfileToHermes(\n hermes: ThreadCpuProfile,\n native: ThreadCpuProfile,\n hermes_active_thread_id: string | undefined,\n): CombinedProfileEvent['profile'] {\n // assumes thread ids are unique\n hermes.thread_metadata = { ...native.thread_metadata, ...hermes.thread_metadata };\n // assumes queue ids are unique\n hermes.queue_metadata = { ...native.queue_metadata, ...hermes.queue_metadata };\n\n // recalculate frames and stacks using offset\n const framesOffset = hermes.frames.length;\n const stacksOffset = hermes.stacks.length;\n\n if (native.frames) {\n for (const frame of native.frames) {\n hermes.frames.push({\n function: frame.function,\n instruction_addr: frame.instruction_addr,\n platform: Platform.OS === 'ios' ? 'cocoa' : undefined,\n });\n }\n }\n hermes.stacks = [\n ...(hermes.stacks || []),\n ...(native.stacks || []).map(stack => stack.map(frameId => frameId + framesOffset)),\n ];\n hermes.samples = [\n ...(hermes.samples || []),\n ...(native.samples || [])\n .filter(sample => sample.thread_id !== hermes_active_thread_id)\n .map(sample => ({\n ...sample,\n stack_id: stacksOffset + sample.stack_id,\n })),\n ];\n\n return hermes;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"integration.js","sourceRoot":"","sources":["../../../src/js/profiling/integration.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable complexity */\nimport type { Envelope, Event, Integration, Span, ThreadCpuProfile } from '@sentry/core';\nimport { getActiveSpan, getClient, logger, spanIsSampled, uuid4 } from '@sentry/core';\nimport { Platform } from 'react-native';\n\nimport type { ReactNativeClient } from '../client';\nimport { isHermesEnabled } from '../utils/environment';\nimport { isRootSpan } from '../utils/span';\nimport { NATIVE } from '../wrapper';\nimport { PROFILE_QUEUE } from './cache';\nimport { MAX_PROFILE_DURATION_MS } from './constants';\nimport { convertToSentryProfile } from './convertHermesProfile';\nimport type { NativeAndroidProfileEvent, NativeProfileEvent } from './nativeTypes';\nimport type { AndroidCombinedProfileEvent, CombinedProfileEvent, HermesProfileEvent, ProfileEvent } from './types';\nimport {\n addProfilesToEnvelope,\n createHermesProfilingEvent,\n enrichCombinedProfileWithEventContext,\n findProfiledTransactionsFromEnvelope,\n} from './utils';\n\nconst INTEGRATION_NAME = 'HermesProfiling';\n\nconst MS_TO_NS: number = 1e6;\n\nexport interface HermesProfilingOptions {\n /**\n * Enable or disable profiling of native (iOS and Android) threads\n *\n * @default true\n */\n platformProfilers?: boolean;\n}\n\nconst defaultOptions: Required<HermesProfilingOptions> = {\n platformProfilers: true,\n};\n\n/**\n * Profiling integration creates a profile for each transaction and adds it to the event envelope.\n *\n * @experimental\n */\nexport const hermesProfilingIntegration = (initOptions: HermesProfilingOptions = defaultOptions): Integration => {\n const usePlatformProfilers = initOptions.platformProfilers ?? true;\n let _currentProfile:\n | {\n span_id: string;\n profile_id: string;\n startTimestampNs: number;\n }\n | undefined;\n let _currentProfileTimeout: ReturnType<typeof setTimeout> | undefined;\n let isReady: boolean = false;\n\n const setupOnce = (): void => {\n if (isReady) {\n return;\n }\n isReady = true;\n\n if (!isHermesEnabled()) {\n logger.log('[Profiling] Hermes is not enabled, not adding profiling integration.');\n return;\n }\n\n const client = getClient();\n\n if (!client || typeof client.on !== 'function') {\n return;\n }\n\n _startCurrentProfileForActiveTransaction();\n client.on('spanStart', _startCurrentProfile);\n\n client.on('spanEnd', _finishCurrentProfileForSpan);\n\n client.on('beforeEnvelope', (envelope: Envelope) => {\n if (!PROFILE_QUEUE.size()) {\n return;\n }\n\n const profiledTransactions = findProfiledTransactionsFromEnvelope(envelope);\n if (!profiledTransactions.length) {\n logger.log('[Profiling] no profiled transactions found in envelope');\n return;\n }\n\n const profilesToAddToEnvelope: ProfileEvent[] = [];\n for (const profiledTransaction of profiledTransactions) {\n const profile = _createProfileEventFor(profiledTransaction);\n if (profile) {\n profilesToAddToEnvelope.push(profile);\n }\n }\n addProfilesToEnvelope(envelope, profilesToAddToEnvelope);\n });\n };\n\n const _startCurrentProfileForActiveTransaction = (): void => {\n if (_currentProfile) {\n return;\n }\n const activeSpan = getActiveSpan();\n activeSpan && _startCurrentProfile(activeSpan);\n };\n\n const _startCurrentProfile = (activeSpan: Span): void => {\n if (!isRootSpan(activeSpan)) {\n return;\n }\n\n _finishCurrentProfile();\n\n const shouldStartProfiling = _shouldStartProfiling(activeSpan);\n if (!shouldStartProfiling) {\n return;\n }\n\n _currentProfileTimeout = setTimeout(_finishCurrentProfile, MAX_PROFILE_DURATION_MS);\n _startNewProfile(activeSpan);\n };\n\n const _shouldStartProfiling = (activeSpan: Span): boolean => {\n if (!spanIsSampled(activeSpan)) {\n logger.log('[Profiling] Transaction is not sampled, skipping profiling');\n return false;\n }\n\n const client = getClient<ReactNativeClient>();\n const options = client?.getOptions?.();\n\n const profilesSampleRate =\n options && typeof options.profilesSampleRate === 'number' ? options.profilesSampleRate : undefined;\n if (profilesSampleRate === undefined) {\n logger.log('[Profiling] Profiling disabled, enable it by setting `profilesSampleRate` option to SDK init call.');\n return false;\n }\n\n // Check if we should sample this profile\n if (Math.random() > profilesSampleRate) {\n logger.log('[Profiling] Skip profiling transaction due to sampling.');\n return false;\n }\n\n return true;\n };\n\n /**\n * Starts a new profile and links it to the transaction.\n */\n const _startNewProfile = (activeSpan: Span): void => {\n const profileStartTimestampNs = startProfiling(usePlatformProfilers);\n if (!profileStartTimestampNs) {\n return;\n }\n\n _currentProfile = {\n span_id: activeSpan.spanContext().spanId,\n profile_id: uuid4(),\n startTimestampNs: profileStartTimestampNs,\n };\n activeSpan.setAttribute('profile_id', _currentProfile.profile_id);\n logger.log('[Profiling] started profiling: ', _currentProfile.profile_id);\n };\n\n /**\n * Stops current profile if the ending span is the currently profiled span.\n */\n const _finishCurrentProfileForSpan = (span: Span): void => {\n if (!isRootSpan(span)) {\n return;\n }\n\n if (span.spanContext().spanId !== _currentProfile?.span_id) {\n logger.log(\n `[Profiling] Span (${span.spanContext().spanId}) ended is not the currently profiled span (${\n _currentProfile?.span_id\n }). Not stopping profiling.`,\n );\n return;\n }\n\n _finishCurrentProfile();\n };\n\n /**\n * Stops profiling and adds the profile to the queue to be processed on beforeEnvelope.\n */\n const _finishCurrentProfile = (): void => {\n _clearCurrentProfileTimeout();\n if (_currentProfile === undefined) {\n return;\n }\n\n const profile = stopProfiling(_currentProfile.startTimestampNs);\n if (!profile) {\n logger.warn('[Profiling] Stop failed. Cleaning up...');\n _currentProfile = undefined;\n return;\n }\n\n PROFILE_QUEUE.add(_currentProfile.profile_id, profile);\n\n logger.log('[Profiling] finished profiling: ', _currentProfile.profile_id);\n _currentProfile = undefined;\n };\n\n const _createProfileEventFor = (profiledTransaction: Event): ProfileEvent | null => {\n const profile_id = profiledTransaction?.contexts?.trace?.data?.profile_id;\n\n if (typeof profile_id !== 'string') {\n logger.log('[Profiling] cannot find profile for a transaction without a profile context');\n return null;\n }\n\n // Remove the profile from the transaction context before sending, relay will take care of the rest.\n if (profiledTransaction?.contexts?.trace?.data?.profile_id) {\n delete profiledTransaction.contexts.trace.data.profile_id;\n }\n\n const profile = PROFILE_QUEUE.get(profile_id);\n PROFILE_QUEUE.delete(profile_id);\n\n if (!profile) {\n logger.log(`[Profiling] cannot find profile ${profile_id} for transaction ${profiledTransaction.event_id}`);\n return null;\n }\n\n const profileWithEvent = enrichCombinedProfileWithEventContext(profile_id, profile, profiledTransaction);\n logger.log(`[Profiling] Created profile ${profile_id} for transaction ${profiledTransaction.event_id}`);\n\n return profileWithEvent;\n };\n\n const _clearCurrentProfileTimeout = (): void => {\n _currentProfileTimeout !== undefined && clearTimeout(_currentProfileTimeout);\n _currentProfileTimeout = undefined;\n };\n\n return {\n name: INTEGRATION_NAME,\n setupOnce,\n };\n};\n\n/**\n * Starts Profilers and returns the timestamp when profiling started in nanoseconds.\n */\nexport function startProfiling(platformProfilers: boolean): number | null {\n const started = NATIVE.startProfiling(platformProfilers);\n if (!started) {\n return null;\n }\n\n return Date.now() * MS_TO_NS;\n}\n\n/**\n * Stops Profilers and returns collected combined profile.\n */\nexport function stopProfiling(\n profileStartTimestampNs: number,\n): CombinedProfileEvent | AndroidCombinedProfileEvent | null {\n const collectedProfiles = NATIVE.stopProfiling();\n if (!collectedProfiles) {\n return null;\n }\n const profileEndTimestampNs = Date.now() * MS_TO_NS;\n\n const hermesProfile = convertToSentryProfile(collectedProfiles.hermesProfile);\n if (!hermesProfile) {\n return null;\n }\n\n const hermesProfileEvent = createHermesProfilingEvent(hermesProfile);\n if (!hermesProfileEvent) {\n return null;\n }\n\n if (collectedProfiles.androidProfile) {\n const durationNs = profileEndTimestampNs - profileStartTimestampNs;\n return createAndroidWithHermesProfile(hermesProfileEvent, collectedProfiles.androidProfile, durationNs);\n } else if (collectedProfiles.nativeProfile) {\n return addNativeProfileToHermesProfile(hermesProfileEvent, collectedProfiles.nativeProfile);\n }\n\n return hermesProfileEvent;\n}\n\n/**\n * Creates Android profile event with attached javascript profile.\n */\nexport function createAndroidWithHermesProfile(\n hermes: HermesProfileEvent,\n nativeAndroid: NativeAndroidProfileEvent,\n durationNs: number,\n): AndroidCombinedProfileEvent {\n return {\n ...nativeAndroid,\n platform: 'android',\n js_profile: hermes.profile,\n duration_ns: durationNs.toString(10),\n active_thread_id: hermes.transaction.active_thread_id,\n };\n}\n\n/**\n * Merges Hermes and Native profile events into one.\n */\nexport function addNativeProfileToHermesProfile(\n hermes: HermesProfileEvent,\n native: NativeProfileEvent,\n): CombinedProfileEvent {\n return {\n ...hermes,\n profile: addNativeThreadCpuProfileToHermes(hermes.profile, native.profile, hermes.transaction.active_thread_id),\n ...(native.debug_meta?.images ? { debug_meta: { images: native.debug_meta.images } } : {}),\n measurements: native.measurements,\n };\n}\n\n/**\n * Merges Hermes And Native profiles into one.\n */\nexport function addNativeThreadCpuProfileToHermes(\n hermes: ThreadCpuProfile,\n native: ThreadCpuProfile,\n hermes_active_thread_id: string | undefined,\n): CombinedProfileEvent['profile'] {\n // assumes thread ids are unique\n hermes.thread_metadata = { ...native.thread_metadata, ...hermes.thread_metadata };\n // assumes queue ids are unique\n hermes.queue_metadata = { ...native.queue_metadata, ...hermes.queue_metadata };\n\n // recalculate frames and stacks using offset\n const framesOffset = hermes.frames.length;\n const stacksOffset = hermes.stacks.length;\n\n if (native.frames) {\n for (const frame of native.frames) {\n hermes.frames.push({\n function: frame.function,\n instruction_addr: frame.instruction_addr,\n platform: Platform.OS === 'ios' ? 'cocoa' : undefined,\n });\n }\n }\n hermes.stacks = [\n ...(hermes.stacks || []),\n ...(native.stacks || []).map(stack => stack.map(frameId => frameId + framesOffset)),\n ];\n hermes.samples = [\n ...(hermes.samples || []),\n ...(native.samples || [])\n .filter(sample => sample.thread_id !== hermes_active_thread_id)\n .map(sample => ({\n ...sample,\n stack_id: stacksOffset + sample.stack_id,\n })),\n ];\n\n return hermes;\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/js/profiling/utils.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAKtE,OAAO,KAAK,EACV,2BAA2B,EAC3B,mBAAmB,EACnB,oBAAoB,EACpB,kBAAkB,EAClB,YAAY,EACZ,mBAAmB,EACpB,MAAM,SAAS,CAAC;AAEjB;;GAEG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,IAAI,mBAAmB,GAAG;IAAE,UAAU,EAAE,MAAM,CAAA;CAAE,CAWjH;AAED;;;;GAIG;AACH,wBAAgB,oCAAoC,CAAC,QAAQ,EAAE,QAAQ,GAAG,KAAK,EAAE,CAqBhF;AAED;;;;GAIG;AACH,wBAAgB,qCAAqC,CACnD,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,oBAAoB,GAAG,2BAA2B,EAC3D,KAAK,EAAE,KAAK,GACX,YAAY,GAAG,IAAI,CAoDrB;AAED;;GAEG;AACH,wBAAgB,oCAAoC,CAClD,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,2BAA2B,EACpC,KAAK,EAAE,KAAK,GACX,mBAAmB,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/js/profiling/utils.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAKtE,OAAO,KAAK,EACV,2BAA2B,EAC3B,mBAAmB,EACnB,oBAAoB,EACpB,kBAAkB,EAClB,YAAY,EACZ,mBAAmB,EACpB,MAAM,SAAS,CAAC;AAEjB;;GAEG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,IAAI,mBAAmB,GAAG;IAAE,UAAU,EAAE,MAAM,CAAA;CAAE,CAWjH;AAED;;;;GAIG;AACH,wBAAgB,oCAAoC,CAAC,QAAQ,EAAE,QAAQ,GAAG,KAAK,EAAE,CAqBhF;AAED;;;;GAIG;AACH,wBAAgB,qCAAqC,CACnD,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,oBAAoB,GAAG,2BAA2B,EAC3D,KAAK,EAAE,KAAK,GACX,YAAY,GAAG,IAAI,CAoDrB;AAED;;GAEG;AACH,wBAAgB,oCAAoC,CAClD,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,2BAA2B,EACpC,KAAK,EAAE,KAAK,GACX,mBAAmB,GAAG,IAAI,CAmC5B;AAED;;GAEG;AACH,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,mBAAmB,GAAG,kBAAkB,CAS3F;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,YAAY,EAAE,GAAG,QAAQ,CAU5F"}
|
|
@@ -46,17 +46,18 @@ export function findProfiledTransactionsFromEnvelope(envelope) {
|
|
|
46
46
|
* @returns {ProfileEvent | null}
|
|
47
47
|
*/
|
|
48
48
|
export function enrichCombinedProfileWithEventContext(profile_id, profile, event) {
|
|
49
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u;
|
|
49
50
|
if ('js_profile' in profile) {
|
|
50
51
|
return enrichAndroidProfileWithEventContext(profile_id, profile, event);
|
|
51
52
|
}
|
|
52
53
|
if (!profile.profile || !isValidProfile(profile.profile)) {
|
|
53
54
|
return null;
|
|
54
55
|
}
|
|
55
|
-
const trace_id = (event.contexts
|
|
56
|
+
const trace_id = ((_b = (_a = event.contexts) === null || _a === void 0 ? void 0 : _a.trace) === null || _b === void 0 ? void 0 : _b.trace_id) || '';
|
|
56
57
|
// Log a warning if the profile has an invalid traceId (should be uuidv4).
|
|
57
58
|
// All profiles and transactions are rejected if this is the case and we want to
|
|
58
59
|
// warn users that this is happening if they enable debug flag
|
|
59
|
-
if (trace_id
|
|
60
|
+
if ((trace_id === null || trace_id === void 0 ? void 0 : trace_id.length) !== 32) {
|
|
60
61
|
if (__DEV__) {
|
|
61
62
|
logger.log(`[Profiling] Invalid traceId: ${trace_id} on profiled event`);
|
|
62
63
|
}
|
|
@@ -65,35 +66,32 @@ export function enrichCombinedProfileWithEventContext(profile_id, profile, event
|
|
|
65
66
|
name: 'hermes',
|
|
66
67
|
version: '', // TODO: get hermes version
|
|
67
68
|
}, timestamp: event.start_timestamp ? new Date(event.start_timestamp * 1000).toISOString() : new Date().toISOString(), release: event.release || '', environment: event.environment || getDefaultEnvironment(), os: {
|
|
68
|
-
name: (event.contexts
|
|
69
|
-
version: (event.contexts
|
|
70
|
-
build_number: (event.contexts
|
|
69
|
+
name: ((_d = (_c = event.contexts) === null || _c === void 0 ? void 0 : _c.os) === null || _d === void 0 ? void 0 : _d.name) || '',
|
|
70
|
+
version: ((_f = (_e = event.contexts) === null || _e === void 0 ? void 0 : _e.os) === null || _f === void 0 ? void 0 : _f.version) || '',
|
|
71
|
+
build_number: ((_h = (_g = event.contexts) === null || _g === void 0 ? void 0 : _g.os) === null || _h === void 0 ? void 0 : _h.build) || '',
|
|
71
72
|
}, device: {
|
|
72
|
-
locale: (event.contexts
|
|
73
|
-
model: (event.contexts
|
|
74
|
-
manufacturer: (event.contexts
|
|
75
|
-
architecture: (event.contexts
|
|
76
|
-
is_emulator: (event.contexts
|
|
73
|
+
locale: (((_j = event.contexts) === null || _j === void 0 ? void 0 : _j.device) && event.contexts.device.locale) || '',
|
|
74
|
+
model: ((_l = (_k = event.contexts) === null || _k === void 0 ? void 0 : _k.device) === null || _l === void 0 ? void 0 : _l.model) || '',
|
|
75
|
+
manufacturer: ((_o = (_m = event.contexts) === null || _m === void 0 ? void 0 : _m.device) === null || _o === void 0 ? void 0 : _o.manufacturer) || '',
|
|
76
|
+
architecture: ((_q = (_p = event.contexts) === null || _p === void 0 ? void 0 : _p.device) === null || _q === void 0 ? void 0 : _q.arch) || '',
|
|
77
|
+
is_emulator: ((_s = (_r = event.contexts) === null || _r === void 0 ? void 0 : _r.device) === null || _s === void 0 ? void 0 : _s.simulator) || false,
|
|
77
78
|
}, transaction: {
|
|
78
79
|
name: event.transaction || '',
|
|
79
80
|
id: event.event_id || '',
|
|
80
81
|
trace_id,
|
|
81
|
-
active_thread_id: (profile.transaction
|
|
82
|
+
active_thread_id: ((_t = profile.transaction) === null || _t === void 0 ? void 0 : _t.active_thread_id) || '',
|
|
82
83
|
}, debug_meta: {
|
|
83
|
-
images: [...getDebugMetadata(), ...((profile.debug_meta
|
|
84
|
+
images: [...getDebugMetadata(), ...(((_u = profile.debug_meta) === null || _u === void 0 ? void 0 : _u.images) || [])],
|
|
84
85
|
} });
|
|
85
86
|
}
|
|
86
87
|
/**
|
|
87
88
|
* Creates Android profiling envelope item.
|
|
88
89
|
*/
|
|
89
90
|
export function enrichAndroidProfileWithEventContext(profile_id, profile, event) {
|
|
91
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q;
|
|
90
92
|
return Object.assign(Object.assign({}, profile), { debug_meta: {
|
|
91
93
|
images: getDebugMetadata(),
|
|
92
|
-
}, build_id: profile.build_id || '', device_cpu_frequencies: [], device_is_emulator: (event.contexts
|
|
93
|
-
event.contexts.device &&
|
|
94
|
-
event.contexts.device.memory_size &&
|
|
95
|
-
Number(event.contexts.device.memory_size).toString(10)) ||
|
|
96
|
-
'', environment: event.environment || getDefaultEnvironment(), profile_id, timestamp: event.start_timestamp ? new Date(event.start_timestamp * 1000).toISOString() : new Date().toISOString(), release: event.release || '', dist: event.dist || '', transaction_id: event.event_id || '', transaction_name: event.transaction || '', trace_id: (event.contexts && event.contexts.trace && event.contexts.trace.trace_id) || '', version_name: event.release || '', version_code: event.dist || '' });
|
|
94
|
+
}, build_id: profile.build_id || '', device_cpu_frequencies: [], device_is_emulator: ((_b = (_a = event.contexts) === null || _a === void 0 ? void 0 : _a.device) === null || _b === void 0 ? void 0 : _b.simulator) || false, device_locale: (((_c = event.contexts) === null || _c === void 0 ? void 0 : _c.device) && event.contexts.device.locale) || '', device_manufacturer: ((_e = (_d = event.contexts) === null || _d === void 0 ? void 0 : _d.device) === null || _e === void 0 ? void 0 : _e.manufacturer) || '', device_model: ((_g = (_f = event.contexts) === null || _f === void 0 ? void 0 : _f.device) === null || _g === void 0 ? void 0 : _g.model) || '', device_os_name: ((_j = (_h = event.contexts) === null || _h === void 0 ? void 0 : _h.os) === null || _j === void 0 ? void 0 : _j.name) || '', device_os_version: ((_l = (_k = event.contexts) === null || _k === void 0 ? void 0 : _k.os) === null || _l === void 0 ? void 0 : _l.version) || '', device_physical_memory_bytes: (((_o = (_m = event.contexts) === null || _m === void 0 ? void 0 : _m.device) === null || _o === void 0 ? void 0 : _o.memory_size) && Number(event.contexts.device.memory_size).toString(10)) || '', environment: event.environment || getDefaultEnvironment(), profile_id, timestamp: event.start_timestamp ? new Date(event.start_timestamp * 1000).toISOString() : new Date().toISOString(), release: event.release || '', dist: event.dist || '', transaction_id: event.event_id || '', transaction_name: event.transaction || '', trace_id: ((_q = (_p = event.contexts) === null || _p === void 0 ? void 0 : _p.trace) === null || _q === void 0 ? void 0 : _q.trace_id) || '', version_name: event.release || '', version_code: event.dist || '' });
|
|
97
95
|
}
|
|
98
96
|
/**
|
|
99
97
|
* Creates profiling event compatible carrier Object from raw Hermes profile.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../src/js/profiling/utils.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable complexity */\nimport type { Envelope, Event, ThreadCpuProfile } from '@sentry/core';\nimport { forEachEnvelopeItem, logger } from '@sentry/core';\n\nimport { getDefaultEnvironment } from '../utils/environment';\nimport { getDebugMetadata } from './debugid';\nimport type {\n AndroidCombinedProfileEvent,\n AndroidProfileEvent,\n CombinedProfileEvent,\n HermesProfileEvent,\n ProfileEvent,\n RawThreadCpuProfile,\n} from './types';\n\n/**\n *\n */\nexport function isValidProfile(profile: ThreadCpuProfile): profile is RawThreadCpuProfile & { profile_id: string } {\n if (profile.samples.length <= 1) {\n if (__DEV__) {\n // Log a warning if the profile has less than 2 samples so users can know why\n // they are not seeing any profiling data and we cant avoid the back and forth\n // of asking them to provide us with a dump of the profile data.\n logger.log('[Profiling] Discarding profile because it contains less than 2 samples');\n }\n return false;\n }\n return true;\n}\n\n/**\n * Finds transactions with profile_id context in the envelope\n * @param envelope\n * @returns\n */\nexport function findProfiledTransactionsFromEnvelope(envelope: Envelope): Event[] {\n const events: Event[] = [];\n\n forEachEnvelopeItem(envelope, (item, type) => {\n if (type !== 'transaction') {\n return;\n }\n\n // First item is the type\n for (let j = 1; j < item.length; j++) {\n const event = item[j];\n\n // @ts-expect-error accessing private property\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n if (event.contexts?.trace?.data?.profile_id) {\n events.push(item[j] as Event);\n }\n }\n });\n\n return events;\n}\n\n/**\n * Creates a profiling envelope item, if the profile does not pass validation, returns null.\n * @param event\n * @returns {ProfileEvent | null}\n */\nexport function enrichCombinedProfileWithEventContext(\n profile_id: string,\n profile: CombinedProfileEvent | AndroidCombinedProfileEvent,\n event: Event,\n): ProfileEvent | null {\n if ('js_profile' in profile) {\n return enrichAndroidProfileWithEventContext(profile_id, profile, event);\n }\n\n if (!profile.profile || !isValidProfile(profile.profile)) {\n return null;\n }\n\n const trace_id = (event.contexts && event.contexts.trace && event.contexts.trace.trace_id) || '';\n\n // Log a warning if the profile has an invalid traceId (should be uuidv4).\n // All profiles and transactions are rejected if this is the case and we want to\n // warn users that this is happening if they enable debug flag\n if (trace_id && trace_id.length !== 32) {\n if (__DEV__) {\n logger.log(`[Profiling] Invalid traceId: ${trace_id} on profiled event`);\n }\n }\n\n return {\n ...profile,\n event_id: profile_id,\n runtime: {\n name: 'hermes',\n version: '', // TODO: get hermes version\n },\n timestamp: event.start_timestamp ? new Date(event.start_timestamp * 1000).toISOString() : new Date().toISOString(),\n release: event.release || '',\n environment: event.environment || getDefaultEnvironment(),\n os: {\n name: (event.contexts && event.contexts.os && event.contexts.os.name) || '',\n version: (event.contexts && event.contexts.os && event.contexts.os.version) || '',\n build_number: (event.contexts && event.contexts.os && event.contexts.os.build) || '',\n },\n device: {\n locale: (event.contexts && event.contexts.device && (event.contexts.device.locale as string)) || '',\n model: (event.contexts && event.contexts.device && event.contexts.device.model) || '',\n manufacturer: (event.contexts && event.contexts.device && event.contexts.device.manufacturer) || '',\n architecture: (event.contexts && event.contexts.device && event.contexts.device.arch) || '',\n is_emulator: (event.contexts && event.contexts.device && event.contexts.device.simulator) || false,\n },\n transaction: {\n name: event.transaction || '',\n id: event.event_id || '',\n trace_id,\n active_thread_id: (profile.transaction && profile.transaction.active_thread_id) || '',\n },\n debug_meta: {\n images: [...getDebugMetadata(), ...((profile.debug_meta && profile.debug_meta.images) || [])],\n },\n };\n}\n\n/**\n * Creates Android profiling envelope item.\n */\nexport function enrichAndroidProfileWithEventContext(\n profile_id: string,\n profile: AndroidCombinedProfileEvent,\n event: Event,\n): AndroidProfileEvent | null {\n return {\n ...profile,\n debug_meta: {\n images: getDebugMetadata(),\n },\n build_id: profile.build_id || '',\n\n device_cpu_frequencies: [],\n device_is_emulator: (event.contexts && event.contexts.device && event.contexts.device.simulator) || false,\n device_locale: (event.contexts && event.contexts.device && (event.contexts.device.locale as string)) || '',\n device_manufacturer: (event.contexts && event.contexts.device && event.contexts.device.manufacturer) || '',\n device_model: (event.contexts && event.contexts.device && event.contexts.device.model) || '',\n device_os_name: (event.contexts && event.contexts.os && event.contexts.os.name) || '',\n device_os_version: (event.contexts && event.contexts.os && event.contexts.os.version) || '',\n\n device_physical_memory_bytes:\n (event.contexts &&\n event.contexts.device &&\n event.contexts.device.memory_size &&\n Number(event.contexts.device.memory_size).toString(10)) ||\n '',\n\n environment: event.environment || getDefaultEnvironment(),\n\n profile_id,\n\n timestamp: event.start_timestamp ? new Date(event.start_timestamp * 1000).toISOString() : new Date().toISOString(),\n\n release: event.release || '',\n dist: event.dist || '',\n\n transaction_id: event.event_id || '',\n transaction_name: event.transaction || '',\n trace_id: (event.contexts && event.contexts.trace && event.contexts.trace.trace_id) || '',\n\n version_name: event.release || '',\n version_code: event.dist || '',\n };\n}\n\n/**\n * Creates profiling event compatible carrier Object from raw Hermes profile.\n */\nexport function createHermesProfilingEvent(profile: RawThreadCpuProfile): HermesProfileEvent {\n return {\n platform: 'javascript',\n version: '1',\n profile,\n transaction: {\n active_thread_id: profile.active_thread_id,\n },\n };\n}\n\n/**\n * Adds items to envelope if they are not already present - mutates the envelope.\n * @param envelope\n */\nexport function addProfilesToEnvelope(envelope: Envelope, profiles: ProfileEvent[]): Envelope {\n if (!profiles.length) {\n return envelope;\n }\n\n for (const profile of profiles) {\n // @ts-expect-error untyped envelope\n envelope[1].push([{ type: 'profile' }, profile]);\n }\n return envelope;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../src/js/profiling/utils.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable complexity */\nimport type { Envelope, Event, ThreadCpuProfile } from '@sentry/core';\nimport { forEachEnvelopeItem, logger } from '@sentry/core';\n\nimport { getDefaultEnvironment } from '../utils/environment';\nimport { getDebugMetadata } from './debugid';\nimport type {\n AndroidCombinedProfileEvent,\n AndroidProfileEvent,\n CombinedProfileEvent,\n HermesProfileEvent,\n ProfileEvent,\n RawThreadCpuProfile,\n} from './types';\n\n/**\n *\n */\nexport function isValidProfile(profile: ThreadCpuProfile): profile is RawThreadCpuProfile & { profile_id: string } {\n if (profile.samples.length <= 1) {\n if (__DEV__) {\n // Log a warning if the profile has less than 2 samples so users can know why\n // they are not seeing any profiling data and we cant avoid the back and forth\n // of asking them to provide us with a dump of the profile data.\n logger.log('[Profiling] Discarding profile because it contains less than 2 samples');\n }\n return false;\n }\n return true;\n}\n\n/**\n * Finds transactions with profile_id context in the envelope\n * @param envelope\n * @returns\n */\nexport function findProfiledTransactionsFromEnvelope(envelope: Envelope): Event[] {\n const events: Event[] = [];\n\n forEachEnvelopeItem(envelope, (item, type) => {\n if (type !== 'transaction') {\n return;\n }\n\n // First item is the type\n for (let j = 1; j < item.length; j++) {\n const event = item[j];\n\n // @ts-expect-error accessing private property\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n if (event.contexts?.trace?.data?.profile_id) {\n events.push(item[j] as Event);\n }\n }\n });\n\n return events;\n}\n\n/**\n * Creates a profiling envelope item, if the profile does not pass validation, returns null.\n * @param event\n * @returns {ProfileEvent | null}\n */\nexport function enrichCombinedProfileWithEventContext(\n profile_id: string,\n profile: CombinedProfileEvent | AndroidCombinedProfileEvent,\n event: Event,\n): ProfileEvent | null {\n if ('js_profile' in profile) {\n return enrichAndroidProfileWithEventContext(profile_id, profile, event);\n }\n\n if (!profile.profile || !isValidProfile(profile.profile)) {\n return null;\n }\n\n const trace_id = event.contexts?.trace?.trace_id || '';\n\n // Log a warning if the profile has an invalid traceId (should be uuidv4).\n // All profiles and transactions are rejected if this is the case and we want to\n // warn users that this is happening if they enable debug flag\n if (trace_id?.length !== 32) {\n if (__DEV__) {\n logger.log(`[Profiling] Invalid traceId: ${trace_id} on profiled event`);\n }\n }\n\n return {\n ...profile,\n event_id: profile_id,\n runtime: {\n name: 'hermes',\n version: '', // TODO: get hermes version\n },\n timestamp: event.start_timestamp ? new Date(event.start_timestamp * 1000).toISOString() : new Date().toISOString(),\n release: event.release || '',\n environment: event.environment || getDefaultEnvironment(),\n os: {\n name: event.contexts?.os?.name || '',\n version: event.contexts?.os?.version || '',\n build_number: event.contexts?.os?.build || '',\n },\n device: {\n locale: (event.contexts?.device && (event.contexts.device.locale as string)) || '',\n model: event.contexts?.device?.model || '',\n manufacturer: event.contexts?.device?.manufacturer || '',\n architecture: event.contexts?.device?.arch || '',\n is_emulator: event.contexts?.device?.simulator || false,\n },\n transaction: {\n name: event.transaction || '',\n id: event.event_id || '',\n trace_id,\n active_thread_id: profile.transaction?.active_thread_id || '',\n },\n debug_meta: {\n images: [...getDebugMetadata(), ...(profile.debug_meta?.images || [])],\n },\n };\n}\n\n/**\n * Creates Android profiling envelope item.\n */\nexport function enrichAndroidProfileWithEventContext(\n profile_id: string,\n profile: AndroidCombinedProfileEvent,\n event: Event,\n): AndroidProfileEvent | null {\n return {\n ...profile,\n debug_meta: {\n images: getDebugMetadata(),\n },\n build_id: profile.build_id || '',\n\n device_cpu_frequencies: [],\n device_is_emulator: event.contexts?.device?.simulator || false,\n device_locale: (event.contexts?.device && (event.contexts.device.locale as string)) || '',\n device_manufacturer: event.contexts?.device?.manufacturer || '',\n device_model: event.contexts?.device?.model || '',\n device_os_name: event.contexts?.os?.name || '',\n device_os_version: event.contexts?.os?.version || '',\n\n device_physical_memory_bytes:\n (event.contexts?.device?.memory_size && Number(event.contexts.device.memory_size).toString(10)) || '',\n\n environment: event.environment || getDefaultEnvironment(),\n\n profile_id,\n\n timestamp: event.start_timestamp ? new Date(event.start_timestamp * 1000).toISOString() : new Date().toISOString(),\n\n release: event.release || '',\n dist: event.dist || '',\n\n transaction_id: event.event_id || '',\n transaction_name: event.transaction || '',\n trace_id: event.contexts?.trace?.trace_id || '',\n\n version_name: event.release || '',\n version_code: event.dist || '',\n };\n}\n\n/**\n * Creates profiling event compatible carrier Object from raw Hermes profile.\n */\nexport function createHermesProfilingEvent(profile: RawThreadCpuProfile): HermesProfileEvent {\n return {\n platform: 'javascript',\n version: '1',\n profile,\n transaction: {\n active_thread_id: profile.active_thread_id,\n },\n };\n}\n\n/**\n * Adds items to envelope if they are not already present - mutates the envelope.\n * @param envelope\n */\nexport function addProfilesToEnvelope(envelope: Envelope, profiles: ProfileEvent[]): Envelope {\n if (!profiles.length) {\n return envelope;\n }\n\n for (const profile of profiles) {\n // @ts-expect-error untyped envelope\n envelope[1].push([{ type: 'profile' }, profile]);\n }\n return envelope;\n}\n"]}
|
|
@@ -22,7 +22,7 @@ const UnmaskFallback = (viewProps) => {
|
|
|
22
22
|
warn('Unmask');
|
|
23
23
|
return React.createElement(View, Object.assign({}, viewProps));
|
|
24
24
|
};
|
|
25
|
-
const hasViewManagerConfig = (nativeComponentName) => UIManager.hasViewManagerConfig
|
|
25
|
+
const hasViewManagerConfig = (nativeComponentName) => { var _a; return (_a = UIManager.hasViewManagerConfig) === null || _a === void 0 ? void 0 : _a.call(UIManager, nativeComponentName); };
|
|
26
26
|
const Mask = (() => {
|
|
27
27
|
if (isExpoGo() || !hasViewManagerConfig(MaskNativeComponentName)) {
|
|
28
28
|
logger.warn(`[SentrySessionReplay] Can't load ${MaskNativeComponentName}.`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CustomMask.js","sourceRoot":"","sources":["../../../src/js/replay/CustomMask.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACtC,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAE/C,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAEhD,MAAM,uBAAuB,GAGzB,OAAO,CAAC,gEAAgE,CAAC,CAAC;AAE9E,MAAM,uBAAuB,GAAG,oBAAoB,CAAC;AACrD,MAAM,yBAAyB,GAAG,sBAAsB,CAAC;AAEzD,MAAM,WAAW,GAAG,CAAC,SAAiB,EAAU,EAAE,CAAC,yBAAyB,SAAS,2DAA2D,SAAS,+EAA+E,CAAC;AAEzO,MAAM,IAAI,GAAG,CAAC,SAAiB,EAAQ,EAAE;IACvC,UAAU,CAAC,GAAG,EAAE;QACd,gGAAgG;QAChG,4CAA4C;QAC5C,sCAAsC;QACtC,OAAO,CAAC,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC,CAAC;IACvC,CAAC,EAAE,CAAC,CAAC,CAAC;AACR,CAAC,CAAC;AAEF,MAAM,YAAY,GAAG,CAAC,SAAoB,EAAsB,EAAE;IAChE,IAAI,CAAC,MAAM,CAAC,CAAC;IACb,OAAO,oBAAC,IAAI,oBAAK,SAAS,EAAI,CAAC;AACjC,CAAC,CAAC;AAEF,MAAM,cAAc,GAAG,CAAC,SAAoB,EAAsB,EAAE;IAClE,IAAI,CAAC,QAAQ,CAAC,CAAC;IACf,OAAO,oBAAC,IAAI,oBAAK,SAAS,EAAI,CAAC;AACjC,CAAC,CAAC;AAEF,MAAM,oBAAoB,GAAG,CAAC,mBAA2B,EAAW,EAAE,
|
|
1
|
+
{"version":3,"file":"CustomMask.js","sourceRoot":"","sources":["../../../src/js/replay/CustomMask.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACtC,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAE/C,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAEhD,MAAM,uBAAuB,GAGzB,OAAO,CAAC,gEAAgE,CAAC,CAAC;AAE9E,MAAM,uBAAuB,GAAG,oBAAoB,CAAC;AACrD,MAAM,yBAAyB,GAAG,sBAAsB,CAAC;AAEzD,MAAM,WAAW,GAAG,CAAC,SAAiB,EAAU,EAAE,CAAC,yBAAyB,SAAS,2DAA2D,SAAS,+EAA+E,CAAC;AAEzO,MAAM,IAAI,GAAG,CAAC,SAAiB,EAAQ,EAAE;IACvC,UAAU,CAAC,GAAG,EAAE;QACd,gGAAgG;QAChG,4CAA4C;QAC5C,sCAAsC;QACtC,OAAO,CAAC,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC,CAAC;IACvC,CAAC,EAAE,CAAC,CAAC,CAAC;AACR,CAAC,CAAC;AAEF,MAAM,YAAY,GAAG,CAAC,SAAoB,EAAsB,EAAE;IAChE,IAAI,CAAC,MAAM,CAAC,CAAC;IACb,OAAO,oBAAC,IAAI,oBAAK,SAAS,EAAI,CAAC;AACjC,CAAC,CAAC;AAEF,MAAM,cAAc,GAAG,CAAC,SAAoB,EAAsB,EAAE;IAClE,IAAI,CAAC,QAAQ,CAAC,CAAC;IACf,OAAO,oBAAC,IAAI,oBAAK,SAAS,EAAI,CAAC;AACjC,CAAC,CAAC;AAEF,MAAM,oBAAoB,GAAG,CAAC,mBAA2B,EAAW,EAAE,WAAC,OAAA,MAAA,SAAS,CAAC,oBAAoB,0DAAG,mBAAmB,CAAC,CAAA,EAAA,CAAC;AAE7H,MAAM,IAAI,GAAG,CAAC,GAA8D,EAAE;IAC5E,IAAI,QAAQ,EAAE,IAAI,CAAC,oBAAoB,CAAC,uBAAuB,CAAC,EAAE;QAChE,MAAM,CAAC,IAAI,CAAC,oCAAoC,uBAAuB,GAAG,CAAC,CAAC;QAC5E,OAAO,YAAY,CAAC;KACrB;IAED,qDAAqD;IACrD,8KAA8K;IAC9K,OAAO,uBAAuB,CAAC,GAAG,CAAC,uBAAuB,EAAE,GAAG,EAAE,CAAC,CAAC;QACjE,eAAe,EAAE,uBAAuB;KACzC,CAAC,CAAC,CAAC;AACN,CAAC,CAAC,EAAE,CAAA;AAEJ,MAAM,MAAM,GAAG,CAAC,GAA8D,EAAE;IAC9E,IAAI,QAAQ,EAAE,IAAI,CAAC,oBAAoB,CAAC,yBAAyB,CAAC,EAAE;QAClE,MAAM,CAAC,IAAI,CAAC,oCAAoC,yBAAyB,GAAG,CAAC,CAAC;QAC9E,OAAO,cAAc,CAAC;KACvB;IAED,qDAAqD;IACrD,8KAA8K;IAC9K,OAAO,uBAAuB,CAAC,GAAG,CAAC,yBAAyB,EAAE,GAAG,EAAE,CAAC,CAAC;QACnE,eAAe,EAAE,yBAAyB;KAC3C,CAAC,CAAC,CAAC;AACN,CAAC,CAAC,EAAE,CAAC;AAEL,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,YAAY,EAAE,cAAc,EAAE,CAAC","sourcesContent":["import { logger } from '@sentry/core';\nimport * as React from 'react';\nimport type { HostComponent, ViewProps } from 'react-native';\nimport { UIManager, View } from 'react-native';\n\nimport { isExpoGo } from '../utils/environment';\n\nconst NativeComponentRegistry: {\n get<T, C extends Record<string, unknown>>(componentName: string, createViewConfig: () => C): HostComponent<T>;\n// eslint-disable-next-line @typescript-eslint/no-var-requires\n} = require('react-native/Libraries/NativeComponent/NativeComponentRegistry');\n\nconst MaskNativeComponentName = 'RNSentryReplayMask';\nconst UnmaskNativeComponentName = 'RNSentryReplayUnmask';\n\nconst warnMessage = (component: string): string => `[SentrySessionReplay] ${component} component is not supported on the current platform. If ${component} should be supported, please ensure that the application build is up to date.`;\n\nconst warn = (component: string): void => {\n setTimeout(() => {\n // Missing mask component could cause leaking PII, we have to ensure that the warning is visible\n // even if the app is running without debug.\n // eslint-disable-next-line no-console\n console.warn(warnMessage(component));\n }, 0);\n};\n\nconst MaskFallback = (viewProps: ViewProps): React.ReactElement => {\n warn('Mask');\n return <View {...viewProps} />;\n};\n\nconst UnmaskFallback = (viewProps: ViewProps): React.ReactElement => {\n warn('Unmask');\n return <View {...viewProps} />;\n};\n\nconst hasViewManagerConfig = (nativeComponentName: string): boolean => UIManager.hasViewManagerConfig?.(nativeComponentName);\n\nconst Mask = ((): HostComponent<ViewProps> | React.ComponentType<ViewProps> => {\n if (isExpoGo() || !hasViewManagerConfig(MaskNativeComponentName)) {\n logger.warn(`[SentrySessionReplay] Can't load ${MaskNativeComponentName}.`);\n return MaskFallback;\n }\n\n // Based on @react-native/babel-plugin-codegen output\n // https://github.com/facebook/react-native/blob/b32c6c2cc1bc566a85a883901dbf5e23b5a75b61/packages/react-native-codegen/src/generators/components/GenerateViewConfigJs.js#L139\n return NativeComponentRegistry.get(MaskNativeComponentName, () => ({\n uiViewClassName: MaskNativeComponentName,\n }));\n})()\n\nconst Unmask = ((): HostComponent<ViewProps> | React.ComponentType<ViewProps> => {\n if (isExpoGo() || !hasViewManagerConfig(UnmaskNativeComponentName)) {\n logger.warn(`[SentrySessionReplay] Can't load ${UnmaskNativeComponentName}.`);\n return UnmaskFallback;\n }\n\n // Based on @react-native/babel-plugin-codegen output\n // https://github.com/facebook/react-native/blob/b32c6c2cc1bc566a85a883901dbf5e23b5a75b61/packages/react-native-codegen/src/generators/components/GenerateViewConfigJs.js#L139\n return NativeComponentRegistry.get(UnmaskNativeComponentName, () => ({\n uiViewClassName: UnmaskNativeComponentName,\n }));\n})();\n\nexport { Mask, Unmask, MaskFallback, UnmaskFallback };\n"]}
|
|
@@ -49,8 +49,9 @@ export const mobileReplayIntegration = (initOptions = defaultOptions) => {
|
|
|
49
49
|
}
|
|
50
50
|
const options = Object.assign(Object.assign({}, defaultOptions), initOptions);
|
|
51
51
|
function processEvent(event) {
|
|
52
|
+
var _a;
|
|
52
53
|
return __awaiter(this, void 0, void 0, function* () {
|
|
53
|
-
const hasException = event.exception
|
|
54
|
+
const hasException = ((_a = event.exception) === null || _a === void 0 ? void 0 : _a.values) && event.exception.values.length > 0;
|
|
54
55
|
if (!hasException) {
|
|
55
56
|
// Event is not an error, will not capture replay
|
|
56
57
|
return event;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mobilereplay.js","sourceRoot":"","sources":["../../../src/js/replay/mobilereplay.ts"],"names":[],"mappings":";;;;;;;;;AACA,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAEtC,OAAO,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AACtC,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAChD,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AACpC,OAAO,EAAE,mCAAmC,EAAE,MAAM,YAAY,CAAC;AAEjE,MAAM,CAAC,MAAM,8BAA8B,GAAG,cAAc,CAAC;AAmD7D,MAAM,cAAc,GAAkC;IACpD,WAAW,EAAE,IAAI;IACjB,aAAa,EAAE,IAAI;IACnB,cAAc,EAAE,IAAI;IACpB,8BAA8B,EAAE,KAAK;IACrC,uBAAuB,EAAE,KAAK;CAC/B,CAAC;AAMF;;;;;;;;;;;;;;;GAeG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,cAAmC,cAAc,EAA2B,EAAE;IACpH,IAAI,QAAQ,EAAE,EAAE;QACd,MAAM,CAAC,IAAI,CACT,YAAY,8BAA8B,gFAAgF,CAC3H,CAAC;KACH;IACD,IAAI,WAAW,EAAE,EAAE;QACjB,MAAM,CAAC,IAAI,CAAC,YAAY,8BAA8B,qCAAqC,CAAC,CAAC;KAC9F;IAED,IAAI,QAAQ,EAAE,IAAI,WAAW,EAAE,EAAE;QAC/B,OAAO,2BAA2B,EAAE,CAAC;KACtC;IAED,MAAM,OAAO,mCAAQ,cAAc,GAAK,WAAW,CAAE,CAAC;IAEtD,SAAe,YAAY,CAAC,KAAY
|
|
1
|
+
{"version":3,"file":"mobilereplay.js","sourceRoot":"","sources":["../../../src/js/replay/mobilereplay.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Client, DynamicSamplingContext, Event, Integration } from '@sentry/core';\nimport { logger } from '@sentry/core';\n\nimport { isHardCrash } from '../misc';\nimport { hasHooks } from '../utils/clientutils';\nimport { isExpoGo, notMobileOs } from '../utils/environment';\nimport { NATIVE } from '../wrapper';\nimport { enrichXhrBreadcrumbsForMobileReplay } from './xhrUtils';\n\nexport const MOBILE_REPLAY_INTEGRATION_NAME = 'MobileReplay';\n\nexport interface MobileReplayOptions {\n /**\n * Mask all text in recordings\n *\n * @default true\n */\n maskAllText?: boolean;\n\n /**\n * Mask all images in recordings\n *\n * @default true\n */\n maskAllImages?: boolean;\n\n /**\n * Mask all vector graphics in recordings\n * Supports `react-native-svg`\n *\n * @default true\n */\n maskAllVectors?: boolean;\n\n /**\n * Enables the up to 5x faster experimental view renderer used by the Session Replay integration on iOS.\n *\n * Enabling this flag will reduce the amount of time it takes to render each frame of the session replay on the main thread, therefore reducing\n * interruptions and visual lag.\n *\n * - Experiment: This is an experimental feature and is therefore disabled by default.\n *\n * @default false\n */\n enableExperimentalViewRenderer?: boolean;\n\n /**\n * Enables up to 5x faster but incomplete view rendering used by the Session Replay integration on iOS.\n *\n * Enabling this flag will reduce the amount of time it takes to render each frame of the session replay on the main thread, therefore reducing\n * interruptions and visual lag.\n *\n * - Note: This flag can only be used together with `enableExperimentalViewRenderer` with up to 20% faster render times.\n * - Experiment: This is an experimental feature and is therefore disabled by default.\n *\n * @default false\n */\n enableFastViewRendering?: boolean;\n}\n\nconst defaultOptions: Required<MobileReplayOptions> = {\n maskAllText: true,\n maskAllImages: true,\n maskAllVectors: true,\n enableExperimentalViewRenderer: false,\n enableFastViewRendering: false,\n};\n\ntype MobileReplayIntegration = Integration & {\n options: Required<MobileReplayOptions>;\n};\n\n/**\n * The Mobile Replay Integration, let's you adjust the default mobile replay options.\n * To be passed to `Sentry.init` with `replaysOnErrorSampleRate` or `replaysSessionSampleRate`.\n *\n * ```javascript\n * Sentry.init({\n * replaysOnErrorSampleRate: 1.0,\n * replaysSessionSampleRate: 1.0,\n * integrations: [mobileReplayIntegration({\n * // Adjust the default options\n * })],\n * });\n * ```\n *\n * @experimental\n */\nexport const mobileReplayIntegration = (initOptions: MobileReplayOptions = defaultOptions): MobileReplayIntegration => {\n if (isExpoGo()) {\n logger.warn(\n `[Sentry] ${MOBILE_REPLAY_INTEGRATION_NAME} is not supported in Expo Go. Use EAS Build or \\`expo prebuild\\` to enable it.`,\n );\n }\n if (notMobileOs()) {\n logger.warn(`[Sentry] ${MOBILE_REPLAY_INTEGRATION_NAME} is not supported on this platform.`);\n }\n\n if (isExpoGo() || notMobileOs()) {\n return mobileReplayIntegrationNoop();\n }\n\n const options = { ...defaultOptions, ...initOptions };\n\n async function processEvent(event: Event): Promise<Event> {\n const hasException = event.exception?.values && event.exception.values.length > 0;\n if (!hasException) {\n // Event is not an error, will not capture replay\n return event;\n }\n\n const recordingReplayId = NATIVE.getCurrentReplayId();\n if (recordingReplayId) {\n logger.debug(\n `[Sentry] ${MOBILE_REPLAY_INTEGRATION_NAME} assign already recording replay ${recordingReplayId} for event ${event.event_id}.`,\n );\n return event;\n }\n\n const replayId = await NATIVE.captureReplay(isHardCrash(event));\n if (!replayId) {\n logger.debug(`[Sentry] ${MOBILE_REPLAY_INTEGRATION_NAME} not sampled for event ${event.event_id}.`);\n return event;\n }\n\n return event;\n }\n\n function setup(client: Client): void {\n if (!hasHooks(client)) {\n return;\n }\n\n client.on('createDsc', (dsc: DynamicSamplingContext) => {\n if (dsc.replay_id) {\n return;\n }\n\n // TODO: For better performance, we should emit replayId changes on native, and hold the replayId value in JS\n const currentReplayId = NATIVE.getCurrentReplayId();\n if (currentReplayId) {\n dsc.replay_id = currentReplayId;\n }\n });\n\n client.on('beforeAddBreadcrumb', enrichXhrBreadcrumbsForMobileReplay);\n }\n\n // TODO: When adding manual API, ensure overlap with the web replay so users can use the same API interchangeably\n // https://github.com/getsentry/sentry-javascript/blob/develop/packages/replay-internal/src/integration.ts#L45\n return {\n name: MOBILE_REPLAY_INTEGRATION_NAME,\n setupOnce() {\n /* Noop */\n },\n setup,\n processEvent,\n options: options,\n };\n};\n\nconst mobileReplayIntegrationNoop = (): MobileReplayIntegration => {\n return {\n name: MOBILE_REPLAY_INTEGRATION_NAME,\n setupOnce() {\n /* Noop */\n },\n options: defaultOptions,\n };\n};\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scopeSync.d.ts","sourceRoot":"","sources":["../../src/js/scopeSync.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAc,KAAK,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"scopeSync.d.ts","sourceRoot":"","sources":["../../src/js/scopeSync.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAc,KAAK,EAAE,MAAM,cAAc,CAAC;AActD;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,CAiErD"}
|
package/dist/js/scopeSync.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { logger } from '@sentry/react';
|
|
1
2
|
import { DEFAULT_BREADCRUMB_LEVEL } from './breadcrumb';
|
|
2
3
|
import { fillTyped } from './utils/fill';
|
|
3
4
|
import { convertToNormalizedObject } from './utils/normalize';
|
|
@@ -44,7 +45,12 @@ export function enableSyncToNative(scope) {
|
|
|
44
45
|
const mergedBreadcrumb = Object.assign(Object.assign({}, breadcrumb), { level: breadcrumb.level || DEFAULT_BREADCRUMB_LEVEL, data: breadcrumb.data ? convertToNormalizedObject(breadcrumb.data) : undefined });
|
|
45
46
|
original.call(scope, mergedBreadcrumb, maxBreadcrumbs);
|
|
46
47
|
const finalBreadcrumb = scope.getLastBreadcrumb();
|
|
47
|
-
|
|
48
|
+
if (finalBreadcrumb) {
|
|
49
|
+
NATIVE.addBreadcrumb(finalBreadcrumb);
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
logger.warn('[ScopeSync] Last created breadcrumb is undefined. Skipping sync to native.');
|
|
53
|
+
}
|
|
48
54
|
return scope;
|
|
49
55
|
});
|
|
50
56
|
fillTyped(scope, 'clearBreadcrumbs', original => () => {
|
package/dist/js/scopeSync.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scopeSync.js","sourceRoot":"","sources":["../../src/js/scopeSync.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"scopeSync.js","sourceRoot":"","sources":["../../src/js/scopeSync.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Breadcrumb, Scope } from '@sentry/core';\nimport { logger } from '@sentry/react';\n\nimport { DEFAULT_BREADCRUMB_LEVEL } from './breadcrumb';\nimport { fillTyped } from './utils/fill';\nimport { convertToNormalizedObject } from './utils/normalize';\nimport { NATIVE } from './wrapper';\n\n/**\n * This WeakMap is used to keep track of which scopes have been synced to the native SDKs.\n * This ensures that we don't double sync the same scope.\n */\nconst syncedToNativeMap = new WeakMap<Scope, true>();\n\n/**\n * Hooks into the scope set methods and sync new data added to the given scope with the native SDKs.\n */\nexport function enableSyncToNative(scope: Scope): void {\n if (syncedToNativeMap.has(scope)) {\n return;\n }\n syncedToNativeMap.set(scope, true);\n\n fillTyped(scope, 'setUser', original => (user): Scope => {\n NATIVE.setUser(user);\n return original.call(scope, user);\n });\n\n fillTyped(scope, 'setTag', original => (key, value): Scope => {\n NATIVE.setTag(key, value as string);\n return original.call(scope, key, value);\n });\n\n fillTyped(scope, 'setTags', original => (tags): Scope => {\n // As native only has setTag, we just loop through each tag key.\n Object.keys(tags).forEach(key => {\n NATIVE.setTag(key, tags[key] as string);\n });\n return original.call(scope, tags);\n });\n\n fillTyped(scope, 'setExtras', original => (extras): Scope => {\n Object.keys(extras).forEach(key => {\n NATIVE.setExtra(key, extras[key]);\n });\n return original.call(scope, extras);\n });\n\n fillTyped(scope, 'setExtra', original => (key, value): Scope => {\n NATIVE.setExtra(key, value);\n return original.call(scope, key, value);\n });\n\n fillTyped(scope, 'addBreadcrumb', original => (breadcrumb, maxBreadcrumbs): Scope => {\n const mergedBreadcrumb: Breadcrumb = {\n ...breadcrumb,\n level: breadcrumb.level || DEFAULT_BREADCRUMB_LEVEL,\n data: breadcrumb.data ? convertToNormalizedObject(breadcrumb.data) : undefined,\n };\n\n original.call(scope, mergedBreadcrumb, maxBreadcrumbs);\n\n const finalBreadcrumb = scope.getLastBreadcrumb();\n if (finalBreadcrumb) {\n NATIVE.addBreadcrumb(finalBreadcrumb);\n } else {\n logger.warn('[ScopeSync] Last created breadcrumb is undefined. Skipping sync to native.');\n }\n\n return scope;\n });\n\n fillTyped(scope, 'clearBreadcrumbs', original => (): Scope => {\n NATIVE.clearBreadcrumbs();\n return original.call(scope);\n });\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n fillTyped(scope, 'setContext', original => (key: string, context: { [key: string]: any } | null): Scope => {\n NATIVE.setContext(key, context);\n return original.call(scope, key, context);\n });\n}\n"]}
|
package/dist/js/sdk.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sdk.d.ts","sourceRoot":"","sources":["../../src/js/sdk.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAA2C,KAAK,EAAsB,YAAY,EAAE,MAAM,cAAc,CAAC;AAMrH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAM/B,OAAO,KAAK,EAA4B,kBAAkB,EAAE,yBAAyB,EAAE,MAAM,WAAW,CAAC;AA6BzG;;GAEG;AACH,wBAAgB,IAAI,CAAC,aAAa,EAAE,kBAAkB,GAAG,IAAI,CAuG5D;AAED;;GAEG;AACH,wBAAgB,IAAI,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACpD,aAAa,EAAE,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,EACrC,OAAO,CAAC,EAAE,yBAAyB,GAClC,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,
|
|
1
|
+
{"version":3,"file":"sdk.d.ts","sourceRoot":"","sources":["../../src/js/sdk.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAA2C,KAAK,EAAsB,YAAY,EAAE,MAAM,cAAc,CAAC;AAMrH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAM/B,OAAO,KAAK,EAA4B,kBAAkB,EAAE,yBAAyB,EAAE,MAAM,WAAW,CAAC;AA6BzG;;GAEG;AACH,wBAAgB,IAAI,CAAC,aAAa,EAAE,kBAAkB,GAAG,IAAI,CAuG5D;AAED;;GAEG;AACH,wBAAgB,IAAI,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACpD,aAAa,EAAE,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,EACrC,OAAO,CAAC,EAAE,yBAAyB,GAClC,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,CAoBxB;AAED;;;GAGG;AACH,wBAAgB,WAAW,IAAI,IAAI,CAElC;AAED;;;GAGG;AACH,wBAAsB,KAAK,IAAI,OAAO,CAAC,OAAO,CAAC,CAe9C;AAED;;GAEG;AACH,wBAAsB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAU3C;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,YAAY,GAAG,IAAI,CAQhE;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,SAAS,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,CAAC,GAAG,CAAC,GAAG,SAAS,CAUzE;AAED;;GAEG;AACH,wBAAsB,cAAc,IAAI,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAE9D"}
|