@sentry/react-native 5.9.2 → 5.11.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.
Files changed (61) hide show
  1. package/CHANGELOG.md +87 -0
  2. package/RNSentry.podspec +1 -1
  3. package/android/build.gradle +8 -1
  4. package/android/src/main/java/io/sentry/react/RNSentryModuleImpl.java +3 -0
  5. package/dist/js/client.d.ts.map +1 -1
  6. package/dist/js/client.js +1 -2
  7. package/dist/js/client.js.map +1 -1
  8. package/dist/js/integrations/reactnativeinfo.d.ts +1 -0
  9. package/dist/js/integrations/reactnativeinfo.d.ts.map +1 -1
  10. package/dist/js/integrations/reactnativeinfo.js +31 -1
  11. package/dist/js/integrations/reactnativeinfo.js.map +1 -1
  12. package/dist/js/integrations/screenshot.d.ts +4 -2
  13. package/dist/js/integrations/screenshot.d.ts.map +1 -1
  14. package/dist/js/integrations/screenshot.js +16 -2
  15. package/dist/js/integrations/screenshot.js.map +1 -1
  16. package/dist/js/options.d.ts +8 -1
  17. package/dist/js/options.d.ts.map +1 -1
  18. package/dist/js/options.js.map +1 -1
  19. package/dist/js/sdk.d.ts +1 -1
  20. package/dist/js/sdk.d.ts.map +1 -1
  21. package/dist/js/sdk.js +1 -2
  22. package/dist/js/sdk.js.map +1 -1
  23. package/dist/js/tools/ModulesCollector.js +1 -1
  24. package/dist/js/tools/ModulesCollector.js.map +1 -1
  25. package/dist/js/tools/sentryMetroSerializer.d.ts +9 -0
  26. package/dist/js/tools/sentryMetroSerializer.d.ts.map +1 -0
  27. package/dist/js/tools/sentryMetroSerializer.js +146 -0
  28. package/dist/js/tools/sentryMetroSerializer.js.map +1 -0
  29. package/dist/js/tools/utils.d.ts +43 -0
  30. package/dist/js/tools/utils.d.ts.map +1 -0
  31. package/dist/js/tools/utils.js +39 -0
  32. package/dist/js/tools/utils.js.map +1 -0
  33. package/dist/js/tools/vendor/metro/utils.d.ts +23 -0
  34. package/dist/js/tools/vendor/metro/utils.d.ts.map +1 -0
  35. package/dist/js/tools/vendor/metro/utils.js +50 -0
  36. package/dist/js/tools/vendor/metro/utils.js.map +1 -0
  37. package/dist/js/tracing/reactnativetracing.d.ts +11 -0
  38. package/dist/js/tracing/reactnativetracing.d.ts.map +1 -1
  39. package/dist/js/tracing/reactnativetracing.js +49 -22
  40. package/dist/js/tracing/reactnativetracing.js.map +1 -1
  41. package/dist/js/tracing/transaction.d.ts +5 -1
  42. package/dist/js/tracing/transaction.d.ts.map +1 -1
  43. package/dist/js/tracing/transaction.js +17 -0
  44. package/dist/js/tracing/transaction.js.map +1 -1
  45. package/dist/js/version.d.ts +1 -1
  46. package/dist/js/version.d.ts.map +1 -1
  47. package/dist/js/version.js +1 -1
  48. package/dist/js/version.js.map +1 -1
  49. package/package.json +20 -40
  50. package/scripts/copy-debugid.js +52 -0
  51. package/scripts/has-sourcemap-debugid.js +31 -0
  52. package/scripts/sentry-xcode-debug-files.sh +27 -0
  53. package/scripts/sentry-xcode.sh +32 -0
  54. package/sentry.gradle +129 -69
  55. package/ts3.8/dist/js/integrations/reactnativeinfo.d.ts +1 -0
  56. package/ts3.8/dist/js/integrations/screenshot.d.ts +4 -2
  57. package/ts3.8/dist/js/options.d.ts +8 -1
  58. package/ts3.8/dist/js/sdk.d.ts +1 -1
  59. package/ts3.8/dist/js/tracing/reactnativetracing.d.ts +11 -0
  60. package/ts3.8/dist/js/tracing/transaction.d.ts +5 -1
  61. package/ts3.8/dist/js/version.d.ts +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"ModulesCollector.js","sourceRoot":"","sources":["../../../src/js/tools/ModulesCollector.ts"],"names":[],"mappings":"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","sourcesContent":["import { logger } from '@sentry/utils';\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from 'fs';\nimport { posix, sep } from 'path';\n\nlogger.enable();\n\n// eslint-disable-next-line @typescript-eslint/unbound-method\nconst { dirname, join, resolve, sep: posixSep } = posix;\n\ninterface Package {\n name?: string;\n version?: string;\n}\n\n/**\n * Collects JS modules from source paths.\n */\nexport default class ModulesCollector {\n /** Collect method */\n public static collect(sources: unknown[], modulesPaths: string[]): Record<string, string> {\n const normalizedModulesPaths = modulesPaths.map(modulesPath => resolve(modulesPath.split(sep).join(posixSep)));\n\n const infos: Record<string, string> = {};\n const seen: Record<string, true> = {};\n\n sources.forEach((path: unknown) => {\n if (typeof path !== 'string') {\n return;\n }\n\n let dir = path; // included source file path\n let candidate: Package | null = null;\n\n /** Traverse directories upward in the search of all package.json files */\n const upDirSearch = (): void => {\n const parentDir = dir;\n dir = dirname(parentDir);\n\n if (normalizedModulesPaths.includes(resolve(dir))) {\n if (candidate?.name && candidate?.version) {\n infos[candidate.name] = candidate.version;\n } else if (candidate?.name) {\n infos[candidate.name] = 'unknown';\n }\n return;\n }\n\n if (!dir || parentDir === dir || seen[dir]) {\n return;\n }\n seen[dir] = true;\n\n const pkgPath = join(dir, 'package.json');\n if (!existsSync(pkgPath)) {\n // fast-forward if the package.json doesn't exist\n return upDirSearch();\n }\n\n try {\n const info: Package = JSON.parse(readFileSync(pkgPath, 'utf8'));\n candidate = {\n name: info.name,\n version: info.version,\n };\n } catch (error) {\n logger.error(`Failed to read ${pkgPath}`);\n }\n\n return upDirSearch(); // processed package.json file, continue up search\n };\n\n upDirSearch();\n });\n\n return infos;\n }\n\n /**\n * Runs collection of modules.\n */\n public static run({\n sourceMapPath,\n outputModulesPath,\n modulesPaths,\n collect,\n }: Partial<{\n sourceMapPath: string;\n outputModulesPath: string;\n modulesPaths: string[];\n collect: (sources: unknown[], modulesPaths: string[]) => Record<string, string>;\n }>): void {\n if (!sourceMapPath) {\n logger.error('First argument `source-map-path` is missing!');\n return;\n }\n if (!outputModulesPath) {\n logger.error('Second argument `modules-output-path` is missing!');\n return;\n }\n if (!modulesPaths || modulesPaths.length === 0) {\n logger.error('Third argument `modules-paths` is missing!');\n return;\n }\n\n logger.info('Reading source map from', sourceMapPath);\n logger.info('Saving modules to', outputModulesPath);\n logger.info('Resolving modules from paths', outputModulesPath);\n\n if (!existsSync(sourceMapPath)) {\n logger.error(`Source map file does not exist at ${sourceMapPath}`);\n return;\n }\n for (const modulesPath of modulesPaths) {\n if (!existsSync(modulesPath)) {\n logger.error(`Modules path does not exist at ${modulesPath}`);\n return;\n }\n }\n\n const map: { sources?: unknown } = JSON.parse(readFileSync(sourceMapPath, 'utf8'));\n if (!map.sources || !Array.isArray(map.sources)) {\n logger.error(`Modules not collected. No sources found in the source map (${sourceMapPath})!`);\n return;\n }\n\n const sources: unknown[] = map.sources;\n const modules = collect ? collect(sources, modulesPaths) : ModulesCollector.collect(sources, modulesPaths);\n\n const outputModulesDirPath = dirname(outputModulesPath);\n if (!existsSync(outputModulesDirPath)) {\n mkdirSync(outputModulesDirPath, { recursive: true });\n }\n writeFileSync(outputModulesPath, JSON.stringify(modules, null, 2));\n logger.info(`Modules collected and saved to: ${outputModulesPath}`);\n }\n}\n"]}
1
+ {"version":3,"file":"ModulesCollector.js","sourceRoot":"","sources":["../../../src/js/tools/ModulesCollector.ts"],"names":[],"mappings":"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","sourcesContent":["import { logger } from '@sentry/utils';\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from 'fs';\nimport { posix, sep } from 'path';\n\nlogger.enable();\n\n// eslint-disable-next-line @typescript-eslint/unbound-method\nconst { dirname, join, resolve, sep: posixSep } = posix;\n\ninterface Package {\n name?: string;\n version?: string;\n}\n\n/**\n * Collects JS modules from source paths.\n */\nexport default class ModulesCollector {\n /** Collect method */\n public static collect(sources: unknown[], modulesPaths: string[]): Record<string, string> {\n const normalizedModulesPaths = modulesPaths.map(modulesPath => resolve(modulesPath.split(sep).join(posixSep)));\n\n const infos: Record<string, string> = {};\n const seen: Record<string, true> = {};\n\n sources.forEach((path: unknown) => {\n if (typeof path !== 'string') {\n return;\n }\n\n let dir = path; // included source file path\n let candidate: Package | null = null;\n\n /** Traverse directories upward in the search of all package.json files */\n const upDirSearch = (): void => {\n const parentDir = dir;\n dir = dirname(parentDir);\n\n if (normalizedModulesPaths.includes(resolve(dir))) {\n if (candidate?.name && candidate?.version) {\n infos[candidate.name] = candidate.version;\n } else if (candidate?.name) {\n infos[candidate.name] = 'unknown';\n }\n return;\n }\n\n if (!dir || parentDir === dir || seen[dir]) {\n return;\n }\n seen[dir] = true;\n\n const pkgPath = join(dir, 'package.json');\n if (!existsSync(pkgPath)) {\n // fast-forward if the package.json doesn't exist\n return upDirSearch();\n }\n\n try {\n const info: Package = JSON.parse(readFileSync(pkgPath, 'utf8'));\n candidate = {\n name: info.name,\n version: info.version,\n };\n } catch (error) {\n logger.error(`Failed to read ${pkgPath}`);\n }\n\n return upDirSearch(); // processed package.json file, continue up search\n };\n\n upDirSearch();\n });\n\n return infos;\n }\n\n /**\n * Runs collection of modules.\n */\n public static run({\n sourceMapPath,\n outputModulesPath,\n modulesPaths,\n collect,\n }: Partial<{\n sourceMapPath: string;\n outputModulesPath: string;\n modulesPaths: string[];\n collect: (sources: unknown[], modulesPaths: string[]) => Record<string, string>;\n }>): void {\n if (!sourceMapPath) {\n logger.error('First argument `source-map-path` is missing!');\n return;\n }\n if (!outputModulesPath) {\n logger.error('Second argument `modules-output-path` is missing!');\n return;\n }\n if (!modulesPaths || modulesPaths.length === 0) {\n logger.error('Third argument `modules-paths` is missing!');\n return;\n }\n\n logger.info('Reading source map from', sourceMapPath);\n logger.info('Saving modules to', outputModulesPath);\n logger.info('Resolving modules from paths', modulesPaths.join(', '));\n\n if (!existsSync(sourceMapPath)) {\n logger.error(`Source map file does not exist at ${sourceMapPath}`);\n return;\n }\n for (const modulesPath of modulesPaths) {\n if (!existsSync(modulesPath)) {\n logger.error(`Modules path does not exist at ${modulesPath}`);\n return;\n }\n }\n\n const map: { sources?: unknown } = JSON.parse(readFileSync(sourceMapPath, 'utf8'));\n if (!map.sources || !Array.isArray(map.sources)) {\n logger.error(`Modules not collected. No sources found in the source map (${sourceMapPath})!`);\n return;\n }\n\n const sources: unknown[] = map.sources;\n const modules = collect ? collect(sources, modulesPaths) : ModulesCollector.collect(sources, modulesPaths);\n\n const outputModulesDirPath = dirname(outputModulesPath);\n if (!existsSync(outputModulesDirPath)) {\n mkdirSync(outputModulesDirPath, { recursive: true });\n }\n writeFileSync(outputModulesPath, JSON.stringify(modules, null, 2));\n logger.info(`Modules collected and saved to: ${outputModulesPath}`);\n }\n}\n"]}
@@ -0,0 +1,9 @@
1
+ import type { MetroSerializer } from './utils';
2
+ /**
3
+ * Creates a Metro serializer that adds Debug ID module to the plain bundle.
4
+ * The Debug ID module is a virtual module that provides a debug ID in runtime.
5
+ *
6
+ * RAM Bundles do not support custom serializers.
7
+ */
8
+ export declare const createSentryMetroSerializer: (customSerializer?: MetroSerializer) => MetroSerializer;
9
+ //# sourceMappingURL=sentryMetroSerializer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sentryMetroSerializer.d.ts","sourceRoot":"","sources":["../../../src/js/tools/sentryMetroSerializer.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAU,eAAe,EAA4D,MAAM,SAAS,CAAC;AAYjH;;;;;GAKG;AACH,eAAO,MAAM,2BAA2B,sBAAuB,eAAe,KAAG,eAsDhF,CAAC"}
@@ -0,0 +1,146 @@
1
+ Object.defineProperty(exports, "__esModule", { value: true });
2
+ exports.createSentryMetroSerializer = void 0;
3
+ const tslib_1 = require("tslib");
4
+ const crypto = require("crypto");
5
+ const CountingSet_1 = require("metro/src/lib/CountingSet");
6
+ const countLines = require("metro/src/lib/countLines");
7
+ const utils_1 = require("./utils");
8
+ const utils_2 = require("./vendor/metro/utils");
9
+ const DEBUG_ID_PLACE_HOLDER = '__debug_id_place_holder__';
10
+ const DEBUG_ID_MODULE_PATH = '__debugid__';
11
+ const PRELUDE_MODULE_PATH = '__prelude__';
12
+ const SOURCE_MAP_COMMENT = '//# sourceMappingURL=';
13
+ const DEBUG_ID_COMMENT = '//# debugId=';
14
+ /**
15
+ * Creates a Metro serializer that adds Debug ID module to the plain bundle.
16
+ * The Debug ID module is a virtual module that provides a debug ID in runtime.
17
+ *
18
+ * RAM Bundles do not support custom serializers.
19
+ */
20
+ const createSentryMetroSerializer = (customSerializer) => {
21
+ const serializer = customSerializer || (0, utils_2.createDefaultMetroSerializer)();
22
+ return function (entryPoint, preModules, graph, options) {
23
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
24
+ if (graph.transformOptions.hot) {
25
+ return serializer(entryPoint, preModules, graph, options);
26
+ }
27
+ const debugIdModuleExists = preModules.findIndex(module => module.path === DEBUG_ID_MODULE_PATH) != -1;
28
+ if (debugIdModuleExists) {
29
+ // eslint-disable-next-line no-console
30
+ console.warn('Debug ID module found. Skipping Sentry Debug ID module...');
31
+ return serializer(entryPoint, preModules, graph, options);
32
+ }
33
+ const debugIdModule = createDebugIdModule(DEBUG_ID_PLACE_HOLDER);
34
+ options.sentryBundleCallback = createSentryBundleCallback(debugIdModule);
35
+ const modifiedPreModules = addDebugIdModule(preModules, debugIdModule);
36
+ // Run wrapped serializer
37
+ const serializerResult = serializer(entryPoint, modifiedPreModules, graph, options);
38
+ const { code: bundleCode, map: bundleMapString } = yield extractSerializerResult(serializerResult);
39
+ // Add debug id comment to the bundle
40
+ const debugId = (0, utils_1.determineDebugIdFromBundleSource)(bundleCode);
41
+ if (!debugId) {
42
+ throw new Error('Debug ID was not found in the bundle. Call `options.sentryBundleCallback` if you are using a custom serializer.');
43
+ }
44
+ // Only print debug id for command line builds => not hot reload from dev server
45
+ // eslint-disable-next-line no-console
46
+ console.log('info ' + `Bundle Debug ID: ${debugId}`);
47
+ const debugIdComment = `${DEBUG_ID_COMMENT}${debugId}`;
48
+ const indexOfSourceMapComment = bundleCode.lastIndexOf(SOURCE_MAP_COMMENT);
49
+ const bundleCodeWithDebugId = indexOfSourceMapComment === -1
50
+ ? // If source map comment is missing lets just add the debug id comment
51
+ `${bundleCode}\n${debugIdComment}`
52
+ : // If source map comment is present lets add the debug id comment before it
53
+ `${bundleCode.substring(0, indexOfSourceMapComment) + debugIdComment}\n${bundleCode.substring(indexOfSourceMapComment)}`;
54
+ const bundleMap = JSON.parse(bundleMapString);
55
+ // For now we write both fields until we know what will become the standard - if ever.
56
+ bundleMap['debug_id'] = debugId;
57
+ bundleMap['debugId'] = debugId;
58
+ return {
59
+ code: bundleCodeWithDebugId,
60
+ map: JSON.stringify(bundleMap),
61
+ };
62
+ });
63
+ };
64
+ };
65
+ exports.createSentryMetroSerializer = createSentryMetroSerializer;
66
+ /**
67
+ * This function is expected to be called after serializer creates the final bundle object
68
+ * and before the source maps are generated.
69
+ *
70
+ * It injects a debug ID into the bundle and returns the modified bundle.
71
+ *
72
+ * Access it via `options.sentryBundleCallback` in your custom serializer.
73
+ */
74
+ function createSentryBundleCallback(debugIdModule) {
75
+ return (bundle) => {
76
+ const debugId = calculateDebugId(bundle);
77
+ debugIdModule.setSource(injectDebugId(debugIdModule.getSource().toString(), debugId));
78
+ bundle.pre = injectDebugId(bundle.pre, debugId);
79
+ return bundle;
80
+ };
81
+ }
82
+ function addDebugIdModule(preModules, debugIdModule) {
83
+ const modifiedPreModules = [...preModules];
84
+ if (modifiedPreModules.length > 0 &&
85
+ modifiedPreModules[0] !== undefined &&
86
+ modifiedPreModules[0].path === PRELUDE_MODULE_PATH) {
87
+ // prelude module must be first as it measures the bundle startup time
88
+ modifiedPreModules.unshift(preModules[0]);
89
+ modifiedPreModules[1] = debugIdModule;
90
+ }
91
+ else {
92
+ modifiedPreModules.unshift(debugIdModule);
93
+ }
94
+ return modifiedPreModules;
95
+ }
96
+ function extractSerializerResult(serializerResult) {
97
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
98
+ if (typeof serializerResult === 'string') {
99
+ return { code: serializerResult, map: '{}' };
100
+ }
101
+ if ('map' in serializerResult) {
102
+ return { code: serializerResult.code, map: serializerResult.map };
103
+ }
104
+ const awaitedResult = yield serializerResult;
105
+ if (typeof awaitedResult === 'string') {
106
+ return { code: awaitedResult, map: '{}' };
107
+ }
108
+ return { code: awaitedResult.code, map: awaitedResult.map };
109
+ });
110
+ }
111
+ function createDebugIdModule(debugId) {
112
+ let debugIdCode = (0, utils_1.createDebugIdSnippet)(debugId);
113
+ return {
114
+ setSource: (code) => {
115
+ debugIdCode = code;
116
+ },
117
+ dependencies: new Map(),
118
+ getSource: () => Buffer.from(debugIdCode),
119
+ inverseDependencies: new CountingSet_1.default(),
120
+ path: DEBUG_ID_MODULE_PATH,
121
+ output: [
122
+ {
123
+ type: 'js/script/virtual',
124
+ data: {
125
+ code: debugIdCode,
126
+ lineCount: countLines(debugIdCode),
127
+ map: [],
128
+ },
129
+ },
130
+ ],
131
+ };
132
+ }
133
+ function calculateDebugId(bundle) {
134
+ const hash = crypto.createHash('md5');
135
+ hash.update(bundle.pre);
136
+ for (const [, code] of bundle.modules) {
137
+ hash.update(code);
138
+ }
139
+ hash.update(bundle.post);
140
+ const debugId = (0, utils_1.stringToUUID)(hash.digest('hex'));
141
+ return debugId;
142
+ }
143
+ function injectDebugId(code, debugId) {
144
+ return code.replace(new RegExp(DEBUG_ID_PLACE_HOLDER, 'g'), debugId);
145
+ }
146
+ //# sourceMappingURL=sentryMetroSerializer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sentryMetroSerializer.js","sourceRoot":"","sources":["../../../src/js/tools/sentryMetroSerializer.ts"],"names":[],"mappings":"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","sourcesContent":["import * as crypto from 'crypto';\nimport type { MixedOutput, Module } from 'metro';\nimport CountingSet from 'metro/src/lib/CountingSet';\nimport * as countLines from 'metro/src/lib/countLines';\n\nimport type { Bundle, MetroSerializer, MetroSerializerOutput, SerializedBundle, VirtualJSOutput } from './utils';\nimport { createDebugIdSnippet, determineDebugIdFromBundleSource, stringToUUID } from './utils';\nimport { createDefaultMetroSerializer } from './vendor/metro/utils';\n\ntype SourceMap = Record<string, unknown>;\n\nconst DEBUG_ID_PLACE_HOLDER = '__debug_id_place_holder__';\nconst DEBUG_ID_MODULE_PATH = '__debugid__';\nconst PRELUDE_MODULE_PATH = '__prelude__';\nconst SOURCE_MAP_COMMENT = '//# sourceMappingURL=';\nconst DEBUG_ID_COMMENT = '//# debugId=';\n\n/**\n * Creates a Metro serializer that adds Debug ID module to the plain bundle.\n * The Debug ID module is a virtual module that provides a debug ID in runtime.\n *\n * RAM Bundles do not support custom serializers.\n */\nexport const createSentryMetroSerializer = (customSerializer?: MetroSerializer): MetroSerializer => {\n const serializer = customSerializer || createDefaultMetroSerializer();\n return async function (entryPoint, preModules, graph, options) {\n if (graph.transformOptions.hot) {\n return serializer(entryPoint, preModules, graph, options);\n }\n\n const debugIdModuleExists = preModules.findIndex(module => module.path === DEBUG_ID_MODULE_PATH) != -1;\n if (debugIdModuleExists) {\n // eslint-disable-next-line no-console\n console.warn('Debug ID module found. Skipping Sentry Debug ID module...');\n return serializer(entryPoint, preModules, graph, options);\n }\n\n const debugIdModule = createDebugIdModule(DEBUG_ID_PLACE_HOLDER);\n options.sentryBundleCallback = createSentryBundleCallback(debugIdModule);\n const modifiedPreModules = addDebugIdModule(preModules, debugIdModule);\n\n // Run wrapped serializer\n const serializerResult = serializer(entryPoint, modifiedPreModules, graph, options);\n const { code: bundleCode, map: bundleMapString } = await extractSerializerResult(serializerResult);\n\n // Add debug id comment to the bundle\n const debugId = determineDebugIdFromBundleSource(bundleCode);\n if (!debugId) {\n throw new Error(\n 'Debug ID was not found in the bundle. Call `options.sentryBundleCallback` if you are using a custom serializer.',\n );\n }\n // Only print debug id for command line builds => not hot reload from dev server\n // eslint-disable-next-line no-console\n console.log('info ' + `Bundle Debug ID: ${debugId}`);\n\n const debugIdComment = `${DEBUG_ID_COMMENT}${debugId}`;\n const indexOfSourceMapComment = bundleCode.lastIndexOf(SOURCE_MAP_COMMENT);\n const bundleCodeWithDebugId =\n indexOfSourceMapComment === -1\n ? // If source map comment is missing lets just add the debug id comment\n `${bundleCode}\\n${debugIdComment}`\n : // If source map comment is present lets add the debug id comment before it\n `${bundleCode.substring(0, indexOfSourceMapComment) + debugIdComment}\\n${bundleCode.substring(\n indexOfSourceMapComment,\n )}`;\n\n const bundleMap: SourceMap = JSON.parse(bundleMapString);\n // For now we write both fields until we know what will become the standard - if ever.\n bundleMap['debug_id'] = debugId;\n bundleMap['debugId'] = debugId;\n\n return {\n code: bundleCodeWithDebugId,\n map: JSON.stringify(bundleMap),\n };\n };\n};\n\n/**\n * This function is expected to be called after serializer creates the final bundle object\n * and before the source maps are generated.\n *\n * It injects a debug ID into the bundle and returns the modified bundle.\n *\n * Access it via `options.sentryBundleCallback` in your custom serializer.\n */\nfunction createSentryBundleCallback(debugIdModule: Module<VirtualJSOutput> & { setSource: (code: string) => void }) {\n return (bundle: Bundle) => {\n const debugId = calculateDebugId(bundle);\n debugIdModule.setSource(injectDebugId(debugIdModule.getSource().toString(), debugId));\n bundle.pre = injectDebugId(bundle.pre, debugId);\n return bundle;\n };\n}\n\nfunction addDebugIdModule(\n preModules: readonly Module<MixedOutput>[],\n debugIdModule: Module<VirtualJSOutput>,\n): readonly Module<MixedOutput>[] {\n const modifiedPreModules = [...preModules];\n if (\n modifiedPreModules.length > 0 &&\n modifiedPreModules[0] !== undefined &&\n modifiedPreModules[0].path === PRELUDE_MODULE_PATH\n ) {\n // prelude module must be first as it measures the bundle startup time\n modifiedPreModules.unshift(preModules[0]);\n modifiedPreModules[1] = debugIdModule;\n } else {\n modifiedPreModules.unshift(debugIdModule);\n }\n return modifiedPreModules;\n}\n\nasync function extractSerializerResult(serializerResult: MetroSerializerOutput): Promise<SerializedBundle> {\n if (typeof serializerResult === 'string') {\n return { code: serializerResult, map: '{}' };\n }\n\n if ('map' in serializerResult) {\n return { code: serializerResult.code, map: serializerResult.map };\n }\n\n const awaitedResult = await serializerResult;\n if (typeof awaitedResult === 'string') {\n return { code: awaitedResult, map: '{}' };\n }\n\n return { code: awaitedResult.code, map: awaitedResult.map };\n}\n\nfunction createDebugIdModule(debugId: string): Module<VirtualJSOutput> & { setSource: (code: string) => void } {\n let debugIdCode = createDebugIdSnippet(debugId);\n\n return {\n setSource: (code: string) => {\n debugIdCode = code;\n },\n dependencies: new Map(),\n getSource: () => Buffer.from(debugIdCode),\n inverseDependencies: new CountingSet(),\n path: DEBUG_ID_MODULE_PATH,\n output: [\n {\n type: 'js/script/virtual',\n data: {\n code: debugIdCode,\n lineCount: countLines(debugIdCode),\n map: [],\n },\n },\n ],\n };\n}\n\nfunction calculateDebugId(bundle: Bundle): string {\n const hash = crypto.createHash('md5');\n hash.update(bundle.pre);\n for (const [, code] of bundle.modules) {\n hash.update(code);\n }\n hash.update(bundle.post);\n\n const debugId = stringToUUID(hash.digest('hex'));\n return debugId;\n}\n\nfunction injectDebugId(code: string, debugId: string): string {\n return code.replace(new RegExp(DEBUG_ID_PLACE_HOLDER, 'g'), debugId);\n}\n"]}
@@ -0,0 +1,43 @@
1
+ import type { Module, ReadOnlyGraph, SerializerOptions } from 'metro';
2
+ export type VirtualJSOutput = {
3
+ type: 'js/script/virtual';
4
+ data: {
5
+ code: string;
6
+ lineCount: number;
7
+ map: [];
8
+ };
9
+ };
10
+ export type Bundle = {
11
+ modules: Array<[id: number, code: string]>;
12
+ post: string;
13
+ pre: string;
14
+ };
15
+ export type SentryMetroSerializerOptionsExtras = {
16
+ sentryBundleCallback?: (bundle: Bundle) => Bundle;
17
+ };
18
+ export type SerializedBundle = {
19
+ code: string;
20
+ map: string;
21
+ };
22
+ export type MetroSerializerOutput = string | SerializedBundle | Promise<string | SerializedBundle>;
23
+ export type MetroSerializer = (entryPoint: string, preModules: ReadonlyArray<Module>, graph: ReadOnlyGraph, options: SerializerOptions & SentryMetroSerializerOptionsExtras) => MetroSerializerOutput;
24
+ /**
25
+ * Returns minified Debug ID code snippet.
26
+ */
27
+ export declare function createDebugIdSnippet(debugId: string): string;
28
+ /**
29
+ * Deterministically hashes a string and turns the hash into a uuid.
30
+ *
31
+ * https://github.com/getsentry/sentry-javascript-bundler-plugins/blob/58271f1af2ade6b3e64d393d70376ae53bc5bd2f/packages/bundler-plugin-core/src/utils.ts#L174
32
+ */
33
+ export declare function stringToUUID(str: string): string;
34
+ /**
35
+ * Looks for a particular string pattern (`sdbid-[debug ID]`) in the bundle
36
+ * source and extracts the bundle's debug ID from it.
37
+ *
38
+ * The string pattern is injected via the debug ID injection snipped.
39
+ *
40
+ * https://github.com/getsentry/sentry-javascript-bundler-plugins/blob/40f918458ed449d8b3eabaf64d13c08218213f65/packages/bundler-plugin-core/src/debug-id-upload.ts#L293-L294
41
+ */
42
+ export declare function determineDebugIdFromBundleSource(code: string): string | undefined;
43
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/js/tools/utils.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,OAAO,CAAC;AAItE,MAAM,MAAM,eAAe,GAAG;IAC5B,IAAI,EAAE,mBAAmB,CAAC;IAC1B,IAAI,EAAE;QACJ,IAAI,EAAE,MAAM,CAAC;QACb,SAAS,EAAE,MAAM,CAAC;QAClB,GAAG,EAAE,EAAE,CAAC;KACT,CAAC;CACH,CAAC;AAEF,MAAM,MAAM,MAAM,GAAG;IACnB,OAAO,EAAE,KAAK,CAAC,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC;IAC3C,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;CACb,CAAC;AAEF,MAAM,MAAM,kCAAkC,GAAG;IAC/C,oBAAoB,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,MAAM,CAAC;CACnD,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAAC;AAE7D,MAAM,MAAM,qBAAqB,GAAG,MAAM,GAAG,gBAAgB,GAAG,OAAO,CAAC,MAAM,GAAG,gBAAgB,CAAC,CAAC;AAEnG,MAAM,MAAM,eAAe,GAAG,CAC5B,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,aAAa,CAAC,MAAM,CAAC,EACjC,KAAK,EAAE,aAAa,EACpB,OAAO,EAAE,iBAAiB,GAAG,kCAAkC,KAC5D,qBAAqB,CAAC;AAE3B;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAE5D;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAahD;AAED;;;;;;;GAOG;AACH,wBAAgB,gCAAgC,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAKjF"}
@@ -0,0 +1,39 @@
1
+ Object.defineProperty(exports, "__esModule", { value: true });
2
+ exports.determineDebugIdFromBundleSource = exports.stringToUUID = exports.createDebugIdSnippet = void 0;
3
+ const crypto = require("crypto");
4
+ /**
5
+ * Returns minified Debug ID code snippet.
6
+ */
7
+ function createDebugIdSnippet(debugId) {
8
+ return `var _sentryDebugIds={},_sentryDebugIdIdentifier="";void 0===_sentryDebugIds&&(_sentryDebugIds={});try{var stack=(new Error).stack;stack&&(_sentryDebugIds[stack]="${debugId}",_sentryDebugIdIdentifier="sentry-dbid-${debugId}")}catch(e){}`;
9
+ }
10
+ exports.createDebugIdSnippet = createDebugIdSnippet;
11
+ /**
12
+ * Deterministically hashes a string and turns the hash into a uuid.
13
+ *
14
+ * https://github.com/getsentry/sentry-javascript-bundler-plugins/blob/58271f1af2ade6b3e64d393d70376ae53bc5bd2f/packages/bundler-plugin-core/src/utils.ts#L174
15
+ */
16
+ function stringToUUID(str) {
17
+ const md5sum = crypto.createHash('md5');
18
+ md5sum.update(str);
19
+ const md5Hash = md5sum.digest('hex');
20
+ // Position 16 is fixed to either 8, 9, a, or b in the uuid v4 spec (10xx in binary)
21
+ // RFC 4122 section 4.4
22
+ const v4variant = ['8', '9', 'a', 'b'][md5Hash.substring(16, 17).charCodeAt(0) % 4];
23
+ return `${md5Hash.substring(0, 8)}-${md5Hash.substring(8, 12)}-4${md5Hash.substring(13, 16)}-${v4variant}${md5Hash.substring(17, 20)}-${md5Hash.substring(20)}`.toLowerCase();
24
+ }
25
+ exports.stringToUUID = stringToUUID;
26
+ /**
27
+ * Looks for a particular string pattern (`sdbid-[debug ID]`) in the bundle
28
+ * source and extracts the bundle's debug ID from it.
29
+ *
30
+ * The string pattern is injected via the debug ID injection snipped.
31
+ *
32
+ * https://github.com/getsentry/sentry-javascript-bundler-plugins/blob/40f918458ed449d8b3eabaf64d13c08218213f65/packages/bundler-plugin-core/src/debug-id-upload.ts#L293-L294
33
+ */
34
+ function determineDebugIdFromBundleSource(code) {
35
+ const match = code.match(/sentry-dbid-([0-9a-fA-F]{8}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{12})/);
36
+ return match ? match[1] : undefined;
37
+ }
38
+ exports.determineDebugIdFromBundleSource = determineDebugIdFromBundleSource;
39
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../src/js/tools/utils.ts"],"names":[],"mappings":";;AAAA,iCAAiC;AAmCjC;;GAEG;AACH,SAAgB,oBAAoB,CAAC,OAAe;IAClD,OAAO,qKAAqK,OAAO,2CAA2C,OAAO,eAAe,CAAC;AACvP,CAAC;AAFD,oDAEC;AAED;;;;GAIG;AACH,SAAgB,YAAY,CAAC,GAAW;IACtC,MAAM,MAAM,GAAG,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;IACxC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IACnB,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAErC,oFAAoF;IACpF,uBAAuB;IACvB,MAAM,SAAS,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,CAAW,CAAC;IAE9F,OAAO,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,OAAO,CAAC,SAAS,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,OAAO,CAAC,SAAS,CACjF,EAAE,EACF,EAAE,CACH,IAAI,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,CAAC,IAAI,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,EAAE,CAAC;AACtF,CAAC;AAbD,oCAaC;AAED;;;;;;;GAOG;AACH,SAAgB,gCAAgC,CAAC,IAAY;IAC3D,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CACtB,mGAAmG,CACpG,CAAC;IACF,OAAO,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AACtC,CAAC;AALD,4EAKC","sourcesContent":["import * as crypto from 'crypto';\nimport type { Module, ReadOnlyGraph, SerializerOptions } from 'metro';\n\n// Variant of MixedOutput\n// https://github.com/facebook/metro/blob/9b85f83c9cc837d8cd897aa7723be7da5b296067/packages/metro/src/DeltaBundler/types.flow.js#L21\nexport type VirtualJSOutput = {\n type: 'js/script/virtual';\n data: {\n code: string;\n lineCount: number;\n map: [];\n };\n};\n\nexport type Bundle = {\n modules: Array<[id: number, code: string]>;\n post: string;\n pre: string;\n};\n\nexport type SentryMetroSerializerOptionsExtras = {\n sentryBundleCallback?: (bundle: Bundle) => Bundle;\n};\n\nexport type SerializedBundle = { code: string; map: string };\n\nexport type MetroSerializerOutput = string | SerializedBundle | Promise<string | SerializedBundle>;\n\nexport type MetroSerializer = (\n entryPoint: string,\n preModules: ReadonlyArray<Module>,\n graph: ReadOnlyGraph,\n options: SerializerOptions & SentryMetroSerializerOptionsExtras,\n) => MetroSerializerOutput;\n\n/**\n * Returns minified Debug ID code snippet.\n */\nexport function createDebugIdSnippet(debugId: string): string {\n return `var _sentryDebugIds={},_sentryDebugIdIdentifier=\"\";void 0===_sentryDebugIds&&(_sentryDebugIds={});try{var stack=(new Error).stack;stack&&(_sentryDebugIds[stack]=\"${debugId}\",_sentryDebugIdIdentifier=\"sentry-dbid-${debugId}\")}catch(e){}`;\n}\n\n/**\n * Deterministically hashes a string and turns the hash into a uuid.\n *\n * https://github.com/getsentry/sentry-javascript-bundler-plugins/blob/58271f1af2ade6b3e64d393d70376ae53bc5bd2f/packages/bundler-plugin-core/src/utils.ts#L174\n */\nexport function stringToUUID(str: string): string {\n const md5sum = crypto.createHash('md5');\n md5sum.update(str);\n const md5Hash = md5sum.digest('hex');\n\n // Position 16 is fixed to either 8, 9, a, or b in the uuid v4 spec (10xx in binary)\n // RFC 4122 section 4.4\n const v4variant = ['8', '9', 'a', 'b'][md5Hash.substring(16, 17).charCodeAt(0) % 4] as string;\n\n return `${md5Hash.substring(0, 8)}-${md5Hash.substring(8, 12)}-4${md5Hash.substring(\n 13,\n 16,\n )}-${v4variant}${md5Hash.substring(17, 20)}-${md5Hash.substring(20)}`.toLowerCase();\n}\n\n/**\n * Looks for a particular string pattern (`sdbid-[debug ID]`) in the bundle\n * source and extracts the bundle's debug ID from it.\n *\n * The string pattern is injected via the debug ID injection snipped.\n *\n * https://github.com/getsentry/sentry-javascript-bundler-plugins/blob/40f918458ed449d8b3eabaf64d13c08218213f65/packages/bundler-plugin-core/src/debug-id-upload.ts#L293-L294\n */\nexport function determineDebugIdFromBundleSource(code: string): string | undefined {\n const match = code.match(\n /sentry-dbid-([0-9a-fA-F]{8}\\b-[0-9a-fA-F]{4}\\b-[0-9a-fA-F]{4}\\b-[0-9a-fA-F]{4}\\b-[0-9a-fA-F]{12})/,\n );\n return match ? match[1] : undefined;\n}\n"]}
@@ -0,0 +1,23 @@
1
+ import type { Module, ReadOnlyGraph } from 'metro';
2
+ import type { MetroSerializer } from '../../utils';
3
+ /**
4
+ * This function ensures that modules in source maps are sorted in the same
5
+ * order as in a plain JS bundle.
6
+ *
7
+ * https://github.com/facebook/metro/blob/9b85f83c9cc837d8cd897aa7723be7da5b296067/packages/metro/src/Server.js#L984
8
+ */
9
+ export declare const getSortedModules: (graph: ReadOnlyGraph, { createModuleId, }: {
10
+ createModuleId: (file: string) => number;
11
+ }) => readonly Module[];
12
+ /**
13
+ * Creates the default Metro plain bundle serializer.
14
+ * Because Metro exports only the intermediate serializer functions, we need to
15
+ * assemble the final serializer ourselves. We have to work with the modules the same as Metro does
16
+ * to avoid unexpected changes in the final bundle.
17
+ *
18
+ * This is used when the user does not provide a custom serializer.
19
+ *
20
+ * https://github.com/facebook/metro/blob/9b85f83c9cc837d8cd897aa7723be7da5b296067/packages/metro/src/Server.js#L244-L277
21
+ */
22
+ export declare const createDefaultMetroSerializer: () => MetroSerializer;
23
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../../../src/js/tools/vendor/metro/utils.ts"],"names":[],"mappings":"AA0BA,OAAO,KAAK,EAAe,MAAM,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAKhE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEnD;;;;;GAKG;AACH,eAAO,MAAM,gBAAgB,UACpB,aAAa;2BAIK,MAAM,KAAK,MAAM;MAEzC,SAAS,MAAM,EAMjB,CAAC;AAEF;;;;;;;;;GASG;AACH,eAAO,MAAM,4BAA4B,QAAO,eAoB/C,CAAC"}
@@ -0,0 +1,50 @@
1
+ // Vendored / modified from @facebook/metro
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createDefaultMetroSerializer = exports.getSortedModules = void 0;
4
+ const baseJSBundle = require("metro/src/DeltaBundler/Serializers/baseJSBundle");
5
+ const sourceMapString = require("metro/src/DeltaBundler/Serializers/sourceMapString");
6
+ const bundleToString = require("metro/src/lib/bundleToString");
7
+ /**
8
+ * This function ensures that modules in source maps are sorted in the same
9
+ * order as in a plain JS bundle.
10
+ *
11
+ * https://github.com/facebook/metro/blob/9b85f83c9cc837d8cd897aa7723be7da5b296067/packages/metro/src/Server.js#L984
12
+ */
13
+ const getSortedModules = (graph, { createModuleId, }) => {
14
+ const modules = [...graph.dependencies.values()];
15
+ // Sort by IDs
16
+ return modules.sort((a, b) => createModuleId(a.path) - createModuleId(b.path));
17
+ };
18
+ exports.getSortedModules = getSortedModules;
19
+ /**
20
+ * Creates the default Metro plain bundle serializer.
21
+ * Because Metro exports only the intermediate serializer functions, we need to
22
+ * assemble the final serializer ourselves. We have to work with the modules the same as Metro does
23
+ * to avoid unexpected changes in the final bundle.
24
+ *
25
+ * This is used when the user does not provide a custom serializer.
26
+ *
27
+ * https://github.com/facebook/metro/blob/9b85f83c9cc837d8cd897aa7723be7da5b296067/packages/metro/src/Server.js#L244-L277
28
+ */
29
+ const createDefaultMetroSerializer = () => {
30
+ return (entryPoint, preModules, graph, options) => {
31
+ // baseJSBundle assigns IDs to modules in a consistent order
32
+ let bundle = baseJSBundle(entryPoint, preModules, graph, options);
33
+ if (options.sentryBundleCallback && !graph.transformOptions.hot) {
34
+ bundle = options.sentryBundleCallback(bundle);
35
+ }
36
+ const { code } = bundleToString(bundle);
37
+ if (graph.transformOptions.hot) {
38
+ // Hot means running in dev server, sourcemaps are generated on demand
39
+ return code;
40
+ }
41
+ // Always generate source maps, can't use Sentry without source maps
42
+ const map = sourceMapString([...preModules, ...(0, exports.getSortedModules)(graph, options)], {
43
+ processModuleFilter: options.processModuleFilter,
44
+ shouldAddToIgnoreList: options.shouldAddToIgnoreList,
45
+ });
46
+ return { code, map };
47
+ };
48
+ };
49
+ exports.createDefaultMetroSerializer = createDefaultMetroSerializer;
50
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../../../src/js/tools/vendor/metro/utils.ts"],"names":[],"mappings":"AAAA,2CAA2C;;;AA2B3C,gFAAgF;AAChF,sFAAsF;AACtF,+DAA+D;AAI/D;;;;;GAKG;AACI,MAAM,gBAAgB,GAAG,CAC9B,KAAoB,EACpB,EACE,cAAc,GAGf,EACkB,EAAE;IACrB,MAAM,OAAO,GAAG,CAAC,GAAG,KAAK,CAAC,YAAY,CAAC,MAAM,EAAE,CAAC,CAAC;IACjD,cAAc;IACd,OAAO,OAAO,CAAC,IAAI,CACjB,CAAC,CAAsB,EAAE,CAAsB,EAAE,EAAE,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,CACpG,CAAC;AACJ,CAAC,CAAC;AAbW,QAAA,gBAAgB,oBAa3B;AAEF;;;;;;;;;GASG;AACI,MAAM,4BAA4B,GAAG,GAAoB,EAAE;IAChE,OAAO,CAAC,UAAU,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;QAChD,4DAA4D;QAC5D,IAAI,MAAM,GAAG,YAAY,CAAC,UAAU,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;QAClE,IAAI,OAAO,CAAC,oBAAoB,IAAI,CAAC,KAAK,CAAC,gBAAgB,CAAC,GAAG,EAAE;YAC/D,MAAM,GAAG,OAAO,CAAC,oBAAoB,CAAC,MAAM,CAAC,CAAC;SAC/C;QACD,MAAM,EAAE,IAAI,EAAE,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC;QACxC,IAAI,KAAK,CAAC,gBAAgB,CAAC,GAAG,EAAE;YAC9B,sEAAsE;YACtE,OAAO,IAAI,CAAC;SACb;QAED,oEAAoE;QACpE,MAAM,GAAG,GAAG,eAAe,CAAC,CAAC,GAAG,UAAU,EAAE,GAAG,IAAA,wBAAgB,EAAC,KAAK,EAAE,OAAO,CAAC,CAAC,EAAE;YAChF,mBAAmB,EAAE,OAAO,CAAC,mBAAmB;YAChD,qBAAqB,EAAE,OAAO,CAAC,qBAAqB;SACrD,CAAC,CAAC;QACH,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC;IACvB,CAAC,CAAC;AACJ,CAAC,CAAC;AApBW,QAAA,4BAA4B,gCAoBvC","sourcesContent":["// Vendored / modified from @facebook/metro\n\n// https://github.com/facebook/metro/commit/9b85f83c9cc837d8cd897aa7723be7da5b296067\n\n// MIT License\n\n// Copyright (c) Meta Platforms, Inc. and affiliates.\n\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\nimport type { MixedOutput, Module, ReadOnlyGraph } from 'metro';\nimport * as baseJSBundle from 'metro/src/DeltaBundler/Serializers/baseJSBundle';\nimport * as sourceMapString from 'metro/src/DeltaBundler/Serializers/sourceMapString';\nimport * as bundleToString from 'metro/src/lib/bundleToString';\n\nimport type { MetroSerializer } from '../../utils';\n\n/**\n * This function ensures that modules in source maps are sorted in the same\n * order as in a plain JS bundle.\n *\n * https://github.com/facebook/metro/blob/9b85f83c9cc837d8cd897aa7723be7da5b296067/packages/metro/src/Server.js#L984\n */\nexport const getSortedModules = (\n graph: ReadOnlyGraph,\n {\n createModuleId,\n }: {\n createModuleId: (file: string) => number;\n },\n): readonly Module[] => {\n const modules = [...graph.dependencies.values()];\n // Sort by IDs\n return modules.sort(\n (a: Module<MixedOutput>, b: Module<MixedOutput>) => createModuleId(a.path) - createModuleId(b.path),\n );\n};\n\n/**\n * Creates the default Metro plain bundle serializer.\n * Because Metro exports only the intermediate serializer functions, we need to\n * assemble the final serializer ourselves. We have to work with the modules the same as Metro does\n * to avoid unexpected changes in the final bundle.\n *\n * This is used when the user does not provide a custom serializer.\n *\n * https://github.com/facebook/metro/blob/9b85f83c9cc837d8cd897aa7723be7da5b296067/packages/metro/src/Server.js#L244-L277\n */\nexport const createDefaultMetroSerializer = (): MetroSerializer => {\n return (entryPoint, preModules, graph, options) => {\n // baseJSBundle assigns IDs to modules in a consistent order\n let bundle = baseJSBundle(entryPoint, preModules, graph, options);\n if (options.sentryBundleCallback && !graph.transformOptions.hot) {\n bundle = options.sentryBundleCallback(bundle);\n }\n const { code } = bundleToString(bundle);\n if (graph.transformOptions.hot) {\n // Hot means running in dev server, sourcemaps are generated on demand\n return code;\n }\n\n // Always generate source maps, can't use Sentry without source maps\n const map = sourceMapString([...preModules, ...getSortedModules(graph, options)], {\n processModuleFilter: options.processModuleFilter,\n shouldAddToIgnoreList: options.shouldAddToIgnoreList,\n });\n return { code, map };\n };\n};\n"]}
@@ -96,6 +96,8 @@ export declare class ReactNativeTracing implements Integration {
96
96
  private _awaitingAppStartData?;
97
97
  private _appStartFinishTimestamp?;
98
98
  private _currentRoute?;
99
+ private _hasSetTracePropagationTargets;
100
+ private _hasSetTracingOrigins;
99
101
  constructor(options?: Partial<ReactNativeTracingOptions>);
100
102
  /**
101
103
  * Registers routing and request instrumentation.
@@ -121,6 +123,11 @@ export declare class ReactNativeTracing implements Integration {
121
123
  elementId: string | undefined;
122
124
  op: string;
123
125
  }): TransactionType | undefined;
126
+ /**
127
+ * Returns the App Start Duration in Milliseconds. Also returns undefined if not able do
128
+ * define the duration.
129
+ */
130
+ private _getAppStartDurationMilliseconds;
124
131
  /**
125
132
  * Instruments the app start measurements on the first route transaction.
126
133
  * Starts a route transaction if there isn't routing instrumentation.
@@ -138,5 +145,9 @@ export declare class ReactNativeTracing implements Integration {
138
145
  private _onConfirmRoute;
139
146
  /** Create routing idle transaction. */
140
147
  private _createRouteTransaction;
148
+ /**
149
+ * Start app state aware idle transaction on the scope.
150
+ */
151
+ private _startIdleTransaction;
141
152
  }
142
153
  //# sourceMappingURL=reactnativetracing.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"reactnativetracing.d.ts","sourceRoot":"","sources":["../../../src/js/tracing/reactnativetracing.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,iBAAiB,CAAC;AAErE,OAAO,KAAK,EAAE,GAAG,EAAmB,WAAW,EAAE,MAAM,cAAc,CAAC;AAEtE,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,WAAW,IAAI,eAAe,EAAsB,MAAM,eAAe,CAAC;AAKrH,OAAO,KAAK,EAAE,8BAA8B,EAAE,MAAM,mCAAmC,CAAC;AAExF,OAAO,EAAE,2BAA2B,EAAE,MAAM,gBAAgB,CAAC;AAE7D,OAAO,EAAE,4BAA4B,EAAE,MAAM,iBAAiB,CAAC;AAE/D,OAAO,KAAK,EAAE,cAAc,EAA0B,MAAM,SAAS,CAAC;AAGtE,MAAM,WAAW,yBAA0B,SAAQ,6BAA6B;IAC9E;;OAEG;IACH,WAAW,EAAE,MAAM,CAAC;IAEpB;;OAEG;IACH,sBAAsB,EAAE,MAAM,CAAC;IAE/B;;;;;;OAMG;IACH,aAAa,EAAE,MAAM,CAAC;IAEtB;;;;;;;OAOG;IACH,cAAc,EAAE,MAAM,CAAC;IAEvB;;;OAGG;IACH,sBAAsB,CAAC,EAAE,8BAA8B,CAAC;IAExD;;;;;OAKG;IACH,qCAAqC,EAAE,OAAO,CAAC;IAE/C;;;;;;;OAOG;IACH,cAAc,EAAE,cAAc,CAAC;IAE/B;;;;;OAKG;IACH,sBAAsB,EAAE,OAAO,CAAC;IAEhC;;OAEG;IACH,0BAA0B,EAAE,OAAO,CAAC;IAEpC;;OAEG;IACH,mBAAmB,EAAE,OAAO,CAAC;IAE7B;;OAEG;IACH,4BAA4B,EAAE,OAAO,CAAC;CACvC;AAgBD;;GAEG;AACH,qBAAa,kBAAmB,YAAW,WAAW;IACpD;;OAEG;IACH,OAAc,EAAE,EAAE,MAAM,CAAwB;IAChD,6CAA6C;IAC7C,OAAO,CAAC,MAAM,CAAC,YAAY,CAAiB;IAC5C;;OAEG;IACI,IAAI,EAAE,MAAM,CAAyB;IAE5C,iCAAiC;IAC1B,OAAO,EAAE,yBAAyB,CAAC;IAEnC,2BAA2B,CAAC,EAAE,2BAA2B,CAAC;IAC1D,4BAA4B,CAAC,EAAE,4BAA4B,CAAC;IAC5D,uBAAuB,EAAE,OAAO,CAAS;IAEhD,OAAO,CAAC,+BAA+B,CAAC,CAAkB;IAC1D,OAAO,CAAC,cAAc,CAAC,CAAY;IACnC,OAAO,CAAC,qBAAqB,CAAC,CAAyB;IACvD,OAAO,CAAC,wBAAwB,CAAC,CAAS;IAC1C,OAAO,CAAC,aAAa,CAAC,CAAS;gBAEZ,OAAO,GAAE,OAAO,CAAC,yBAAyB,CAAM;IAoBnE;;OAEG;IACI,SAAS,CAAC,uBAAuB,EAAE,CAAC,QAAQ,EAAE,cAAc,KAAK,IAAI,EAAE,aAAa,EAAE,MAAM,GAAG,GAAG,IAAI;IAiF7G;;OAEG;IACI,kBAAkB,CAAC,WAAW,EAAE,WAAW,GAAG,IAAI;IAQzD;;OAEG;IACI,mBAAmB,CAAC,WAAW,EAAE,WAAW,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI;IAKjF;;OAEG;IACI,gBAAgB,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI;IAInD;;;OAGG;IACI,+BAA+B,CAAC,iBAAiB,EAAE;QACxD,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;QAC9B,EAAE,EAAE,MAAM,CAAC;KACZ,GAAG,eAAe,GAAG,SAAS;IAwD/B;;;OAGG;YACW,mBAAmB;IAgCjC;;OAEG;IACH,OAAO,CAAC,gBAAgB;IA6BxB,6FAA6F;IAC7F,OAAO,CAAC,kBAAkB;IAI1B;;OAEG;IACH,OAAO,CAAC,eAAe;IAwBvB,uCAAuC;IACvC,OAAO,CAAC,uBAAuB;CAmEhC"}
1
+ {"version":3,"file":"reactnativetracing.d.ts","sourceRoot":"","sources":["../../../src/js/tracing/reactnativetracing.ts"],"names":[],"mappings":"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"}
@@ -7,8 +7,9 @@ import { NATIVE } from '../wrapper';
7
7
  import { NativeFramesInstrumentation } from './nativeframes';
8
8
  import { APP_START_COLD as APP_START_COLD_OP, APP_START_WARM as APP_START_WARM_OP, UI_LOAD } from './ops';
9
9
  import { StallTrackingInstrumentation } from './stalltracking';
10
- import { onlySampleIfChildSpans } from './transaction';
10
+ import { cancelInBackground, onlySampleIfChildSpans } from './transaction';
11
11
  import { adjustTransactionDuration, getTimeOriginMilliseconds, isNearToNow } from './utils';
12
+ const DEFAULT_TRACE_PROPAGATION_TARGETS = ['localhost', /^\/(?!\/)/];
12
13
  const defaultReactNativeTracingOptions = Object.assign(Object.assign({}, defaultRequestInstrumentationOptions), { idleTimeout: 1000, maxTransactionDuration: 600, idleTimeoutMs: 1000, finalTimeoutMs: 600000, ignoreEmptyBackNavigationTransactions: true, beforeNavigate: context => context, enableAppStartTracking: true, enableNativeFramesTracking: true, enableStallTracking: true, enableUserInteractionTracing: false });
13
14
  /**
14
15
  * Tracing integration for React Native.
@@ -21,6 +22,12 @@ export class ReactNativeTracing {
21
22
  */
22
23
  this.name = ReactNativeTracing.id;
23
24
  this.useAppStartWithProfiler = false;
25
+ this._hasSetTracePropagationTargets = !!(options &&
26
+ // eslint-disable-next-line deprecation/deprecation
27
+ options.tracePropagationTargets);
28
+ this._hasSetTracingOrigins = !!(options &&
29
+ // eslint-disable-next-line deprecation/deprecation
30
+ options.tracingOrigins);
24
31
  this.options = Object.assign(Object.assign(Object.assign({}, defaultReactNativeTracingOptions), options), { finalTimeoutMs: (_b = (_a = options.finalTimeoutMs) !== null && _a !== void 0 ? _a :
25
32
  // eslint-disable-next-line deprecation/deprecation
26
33
  (typeof options.maxTransactionDuration === 'number'
@@ -54,8 +61,13 @@ export class ReactNativeTracing {
54
61
  // ReactNativeTracing option `tracePropagationTargets` and then `tracingOrigins` (deprecated).
55
62
  //
56
63
  // If both 1 and either one of 2 or 3 are set (from above), we log out a warning.
57
- const tracePropagationTargets = clientOptionsTracePropagationTargets || thisOptionsTracePropagationTargets;
58
- if (__DEV__ && (thisOptionsTracePropagationTargets || tracingOrigins) && clientOptionsTracePropagationTargets) {
64
+ const tracePropagationTargets = clientOptionsTracePropagationTargets ||
65
+ (this._hasSetTracePropagationTargets && thisOptionsTracePropagationTargets) ||
66
+ (this._hasSetTracingOrigins && tracingOrigins) ||
67
+ DEFAULT_TRACE_PROPAGATION_TARGETS;
68
+ if (__DEV__ &&
69
+ (this._hasSetTracePropagationTargets || this._hasSetTracingOrigins) &&
70
+ clientOptionsTracePropagationTargets) {
59
71
  logger.warn('[ReactNativeTracing] The `tracePropagationTargets` option was set in the ReactNativeTracing integration and top level `Sentry.init`. The top level `Sentry.init` value is being used.');
60
72
  }
61
73
  if (enableAppStartTracking) {
@@ -86,7 +98,6 @@ export class ReactNativeTracing {
86
98
  instrumentOutgoingRequests({
87
99
  traceFetch,
88
100
  traceXHR,
89
- tracingOrigins,
90
101
  shouldCreateSpanForRequest,
91
102
  tracePropagationTargets,
92
103
  });
@@ -146,7 +157,6 @@ export class ReactNativeTracing {
146
157
  logger.warn(`[ReactNativeTracing] Did not create ${op} transaction because active transaction ${activeTransaction.name} exists on the scope.`);
147
158
  return;
148
159
  }
149
- const { idleTimeoutMs, finalTimeoutMs } = this.options;
150
160
  if (this._inflightInteractionTransaction) {
151
161
  this._inflightInteractionTransaction.cancelIdleTimeout(undefined, { restartOnChildSpanChange: false });
152
162
  this._inflightInteractionTransaction = undefined;
@@ -157,7 +167,7 @@ export class ReactNativeTracing {
157
167
  op,
158
168
  trimEnd: true,
159
169
  };
160
- this._inflightInteractionTransaction = startIdleTransaction(hub, context, idleTimeoutMs, finalTimeoutMs, true);
170
+ this._inflightInteractionTransaction = this._startIdleTransaction(context);
161
171
  this._inflightInteractionTransaction.registerBeforeFinishCallback((transaction) => {
162
172
  this._inflightInteractionTransaction = undefined;
163
173
  this.onTransactionFinish(transaction);
@@ -167,6 +177,16 @@ export class ReactNativeTracing {
167
177
  logger.log(`[ReactNativeTracing] User Interaction Tracing Created ${op} transaction ${name}.`);
168
178
  return this._inflightInteractionTransaction;
169
179
  }
180
+ /**
181
+ * Returns the App Start Duration in Milliseconds. Also returns undefined if not able do
182
+ * define the duration.
183
+ */
184
+ _getAppStartDurationMilliseconds(appStart) {
185
+ if (!this._appStartFinishTimestamp) {
186
+ return undefined;
187
+ }
188
+ return this._appStartFinishTimestamp * 1000 - appStart.appStartTime;
189
+ }
170
190
  /**
171
191
  * Instruments the app start measurements on the first route transaction.
172
192
  * Starts a route transaction if there isn't routing instrumentation.
@@ -187,11 +207,9 @@ export class ReactNativeTracing {
187
207
  this._awaitingAppStartData = appStart;
188
208
  }
189
209
  else {
190
- const appStartTimeSeconds = appStart.appStartTime / 1000;
191
210
  const idleTransaction = this._createRouteTransaction({
192
211
  name: 'App Start',
193
212
  op: UI_LOAD,
194
- startTimestamp: appStartTimeSeconds,
195
213
  });
196
214
  if (idleTransaction) {
197
215
  this._addAppStartData(idleTransaction, appStart);
@@ -203,11 +221,19 @@ export class ReactNativeTracing {
203
221
  * Adds app start measurements and starts a child span on a transaction.
204
222
  */
205
223
  _addAppStartData(transaction, appStart) {
206
- if (!this._appStartFinishTimestamp) {
224
+ const appStartDurationMilliseconds = this._getAppStartDurationMilliseconds(appStart);
225
+ if (!appStartDurationMilliseconds) {
207
226
  logger.warn('App start was never finished.');
208
227
  return;
209
228
  }
229
+ // we filter out app start more than 60s.
230
+ // this could be due to many different reasons.
231
+ // we've seen app starts with hours, days and even months.
232
+ if (appStartDurationMilliseconds >= ReactNativeTracing._maxAppStart) {
233
+ return;
234
+ }
210
235
  const appStartTimeSeconds = appStart.appStartTime / 1000;
236
+ transaction.startTimestamp = appStartTimeSeconds;
211
237
  const op = appStart.isColdStart ? APP_START_COLD_OP : APP_START_WARM_OP;
212
238
  transaction.startChild({
213
239
  description: appStart.isColdStart ? 'Cold App Start' : 'Warm App Start',
@@ -215,13 +241,6 @@ export class ReactNativeTracing {
215
241
  startTimestamp: appStartTimeSeconds,
216
242
  endTimestamp: this._appStartFinishTimestamp,
217
243
  });
218
- const appStartDurationMilliseconds = this._appStartFinishTimestamp * 1000 - appStart.appStartTime;
219
- // we filter out app start more than 60s.
220
- // this could be due to many different reasons.
221
- // we've seen app starts with hours, days and even months.
222
- if (appStartDurationMilliseconds >= ReactNativeTracing._maxAppStart) {
223
- return;
224
- }
225
244
  const measurement = appStart.isColdStart ? APP_START_COLD : APP_START_WARM;
226
245
  transaction.setMeasurement(measurement, appStartDurationMilliseconds, 'millisecond');
227
246
  }
@@ -265,11 +284,9 @@ export class ReactNativeTracing {
265
284
  this._inflightInteractionTransaction.setStatus('cancelled');
266
285
  this._inflightInteractionTransaction.finish();
267
286
  }
268
- // eslint-disable-next-line @typescript-eslint/unbound-method
269
- const { idleTimeoutMs, finalTimeoutMs } = this.options;
287
+ const { finalTimeoutMs } = this.options;
270
288
  const expandedContext = Object.assign(Object.assign({}, context), { trimEnd: true });
271
- const hub = this._getCurrentHub();
272
- const idleTransaction = startIdleTransaction(hub, expandedContext, idleTimeoutMs, finalTimeoutMs, true);
289
+ const idleTransaction = this._startIdleTransaction(expandedContext);
273
290
  this.onTransactionStart(idleTransaction);
274
291
  logger.log(`[ReactNativeTracing] Starting ${context.op} transaction "${context.name}" on scope`);
275
292
  idleTransaction.registerBeforeFinishCallback((transaction, endTimestamp) => {
@@ -277,8 +294,7 @@ export class ReactNativeTracing {
277
294
  });
278
295
  idleTransaction.registerBeforeFinishCallback(transaction => {
279
296
  if (this.options.enableAppStartTracking && this._awaitingAppStartData) {
280
- transaction.startTimestamp = this._awaitingAppStartData.appStartTime / 1000;
281
- transaction.op = 'ui.load';
297
+ transaction.op = UI_LOAD;
282
298
  this._addAppStartData(transaction, this._awaitingAppStartData);
283
299
  this._awaitingAppStartData = undefined;
284
300
  }
@@ -302,6 +318,17 @@ export class ReactNativeTracing {
302
318
  }
303
319
  return idleTransaction;
304
320
  }
321
+ /**
322
+ * Start app state aware idle transaction on the scope.
323
+ */
324
+ _startIdleTransaction(context) {
325
+ var _a;
326
+ const { idleTimeoutMs, finalTimeoutMs } = this.options;
327
+ const hub = ((_a = this._getCurrentHub) === null || _a === void 0 ? void 0 : _a.call(this)) || getCurrentHub();
328
+ const tx = startIdleTransaction(hub, context, idleTimeoutMs, finalTimeoutMs, true);
329
+ cancelInBackground(tx);
330
+ return tx;
331
+ }
305
332
  }
306
333
  /**
307
334
  * @inheritDoc