react-native-nitro-tracing 0.6.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/CHANGELOG.md +38 -0
- package/LICENSE +21 -0
- package/NitroTracing.podspec +32 -0
- package/README.md +75 -0
- package/android/CMakeLists.txt +49 -0
- package/android/build.gradle +133 -0
- package/android/fix-prefab.gradle +51 -0
- package/android/gradle.properties +5 -0
- package/android/proguard-rules.pro +5 -0
- package/android/src/main/AndroidManifest.xml +2 -0
- package/android/src/main/cpp/cpp-adapter.cpp +47 -0
- package/android/src/main/java/com/margelo/nitro/nitrotracing/HermesSamplingGuard.kt +43 -0
- package/android/src/main/java/com/margelo/nitro/nitrotracing/NitroTracingFrameSource.kt +36 -0
- package/android/src/main/java/com/margelo/nitro/nitrotracing/NitroTracingPackage.kt +31 -0
- package/client.ts +15 -0
- package/cpp/HermesSampling.cpp +26 -0
- package/cpp/HermesSampling.hpp +10 -0
- package/cpp/HybridRecording.cpp +66 -0
- package/cpp/HybridRecording.hpp +30 -0
- package/cpp/HybridTraceSpan.cpp +10 -0
- package/cpp/HybridTraceSpan.hpp +17 -0
- package/cpp/HybridTracing.cpp +10 -0
- package/cpp/HybridTracing.hpp +10 -0
- package/cpp/NativeConversions.cpp +77 -0
- package/cpp/NativeConversions.hpp +15 -0
- package/cpp/core/NativeSampler.cpp +152 -0
- package/cpp/core/NativeSampler.hpp +56 -0
- package/cpp/core/Recorder.cpp +218 -0
- package/cpp/core/Recorder.hpp +60 -0
- package/cpp/core/Retention.cpp +26 -0
- package/cpp/core/Retention.hpp +7 -0
- package/cpp/core/TraceJson.cpp +214 -0
- package/cpp/core/TraceJson.hpp +7 -0
- package/cpp/core/TraceTypes.hpp +62 -0
- package/expo.ts +2 -0
- package/ios/NitroTracingFrameSource.mm +35 -0
- package/lib/commonjs/client.cjs +767 -0
- package/lib/commonjs/client.cjs.map +7 -0
- package/lib/commonjs/expo.cjs +88 -0
- package/lib/commonjs/expo.cjs.map +7 -0
- package/lib/commonjs/index.cjs +28 -0
- package/lib/commonjs/index.cjs.map +7 -0
- package/lib/commonjs/performance.cjs +112 -0
- package/lib/commonjs/performance.cjs.map +7 -0
- package/lib/commonjs/plugins.cjs +477 -0
- package/lib/commonjs/plugins.cjs.map +7 -0
- package/lib/commonjs/react.cjs +3833 -0
- package/lib/commonjs/react.cjs.map +7 -0
- package/lib/commonjs/release-profiler.cjs +142 -0
- package/lib/commonjs/release-profiler.cjs.map +7 -0
- package/lib/commonjs/sentry.cjs +188 -0
- package/lib/commonjs/sentry.cjs.map +7 -0
- package/lib/module/client.mjs +768 -0
- package/lib/module/client.mjs.map +7 -0
- package/lib/module/expo.mjs +62 -0
- package/lib/module/expo.mjs.map +7 -0
- package/lib/module/index.mjs +7 -0
- package/lib/module/index.mjs.map +7 -0
- package/lib/module/performance.mjs +89 -0
- package/lib/module/performance.mjs.map +7 -0
- package/lib/module/plugins.mjs +461 -0
- package/lib/module/plugins.mjs.map +7 -0
- package/lib/module/react.mjs +3851 -0
- package/lib/module/react.mjs.map +7 -0
- package/lib/module/release-profiler.mjs +137 -0
- package/lib/module/release-profiler.mjs.map +7 -0
- package/lib/module/sentry.mjs +165 -0
- package/lib/module/sentry.mjs.map +7 -0
- package/lib/typescript/client.d.ts +4 -0
- package/lib/typescript/expo.d.ts +2 -0
- package/lib/typescript/performance.d.ts +2 -0
- package/lib/typescript/plugins.d.ts +12 -0
- package/lib/typescript/react.d.ts +5 -0
- package/lib/typescript/release-profiler.d.ts +2 -0
- package/lib/typescript/sentry.d.ts +2 -0
- package/lib/typescript/src/client/TracingSink.d.ts +10 -0
- package/lib/typescript/src/client/createTraceClient.d.ts +82 -0
- package/lib/typescript/src/client/playground.d.ts +12 -0
- package/lib/typescript/src/expo/ExpoAdapter.d.ts +15 -0
- package/lib/typescript/src/expo/index.d.ts +2 -0
- package/lib/typescript/src/index.d.ts +6 -0
- package/lib/typescript/src/plugins/TracePlugin.d.ts +22 -0
- package/lib/typescript/src/plugins/errors.d.ts +15 -0
- package/lib/typescript/src/plugins/nativeMetrics.d.ts +13 -0
- package/lib/typescript/src/plugins/navigation.d.ts +29 -0
- package/lib/typescript/src/plugins/network.d.ts +23 -0
- package/lib/typescript/src/plugins/orderSpans.d.ts +3 -0
- package/lib/typescript/src/plugins/performance.d.ts +13 -0
- package/lib/typescript/src/plugins/releaseProfiler.d.ts +25 -0
- package/lib/typescript/src/plugins/runtimeMetrics.d.ts +17 -0
- package/lib/typescript/src/plugins/sentry.d.ts +15 -0
- package/lib/typescript/src/plugins/startPlugins.d.ts +4 -0
- package/lib/typescript/src/react/DetailView.d.ts +11 -0
- package/lib/typescript/src/react/ExplorerFilters.d.ts +9 -0
- package/lib/typescript/src/react/ExplorerView.d.ts +9 -0
- package/lib/typescript/src/react/InspectorControls.d.ts +229 -0
- package/lib/typescript/src/react/InspectorHeader.d.ts +8 -0
- package/lib/typescript/src/react/InspectorSheet.d.ts +16 -0
- package/lib/typescript/src/react/MetricsView.d.ts +7 -0
- package/lib/typescript/src/react/SummaryView.d.ts +11 -0
- package/lib/typescript/src/react/TimelineView.d.ts +8 -0
- package/lib/typescript/src/react/TraceInspector.d.ts +11 -0
- package/lib/typescript/src/react/TraceOverlay.d.ts +17 -0
- package/lib/typescript/src/react/explorerModel.d.ts +38 -0
- package/lib/typescript/src/react/labels.d.ts +203 -0
- package/lib/typescript/src/react/native.d.ts +42 -0
- package/lib/typescript/src/react/readSnapshot.d.ts +4 -0
- package/lib/typescript/src/react/store.d.ts +9 -0
- package/lib/typescript/src/react/topics.d.ts +80 -0
- package/lib/typescript/src/react/useAppReadyMetric.d.ts +3 -0
- package/lib/typescript/src/react/useLiveRecording.d.ts +4 -0
- package/lib/typescript/src/react/useTraceViewer.d.ts +140 -0
- package/lib/typescript/src/react/viewerModel.d.ts +59 -0
- package/lib/typescript/src/specs/Recording.nitro.d.ts +31 -0
- package/lib/typescript/src/specs/TraceSpan.nitro.d.ts +14 -0
- package/lib/typescript/src/specs/Tracing.nitro.d.ts +17 -0
- package/lib/typescript/src/types/CompletedSpanOptions.d.ts +15 -0
- package/lib/typescript/src/types/EventContext.d.ts +8 -0
- package/lib/typescript/src/types/MarkEvent.d.ts +4 -0
- package/lib/typescript/src/types/MarkOptions.d.ts +6 -0
- package/lib/typescript/src/types/MetricEvent.d.ts +8 -0
- package/lib/typescript/src/types/MetricOptions.d.ts +10 -0
- package/lib/typescript/src/types/NativeSamplingOptions.d.ts +7 -0
- package/lib/typescript/src/types/ReadOptions.d.ts +7 -0
- package/lib/typescript/src/types/RecordingOptions.d.ts +11 -0
- package/lib/typescript/src/types/RecordingStats.d.ts +25 -0
- package/lib/typescript/src/types/SpanEvent.d.ts +13 -0
- package/lib/typescript/src/types/SpanOptions.d.ts +6 -0
- package/lib/typescript/src/types/SpanOutcome.d.ts +2 -0
- package/lib/typescript/src/types/TraceAttribute.d.ts +7 -0
- package/lib/typescript/src/types/TraceAttributes.d.ts +3 -0
- package/lib/typescript/src/types/TraceContext.d.ts +10 -0
- package/lib/typescript/src/types/TracePage.d.ts +18 -0
- package/lib/typescript/src/types.d.ts +17 -0
- package/nitro.json +20 -0
- package/nitrogen/generated/.gitattributes +1 -0
- package/nitrogen/generated/android/NitroTracing+autolinking.cmake +83 -0
- package/nitrogen/generated/android/NitroTracing+autolinking.gradle +27 -0
- package/nitrogen/generated/android/NitroTracingOnLoad.cpp +49 -0
- package/nitrogen/generated/android/NitroTracingOnLoad.hpp +34 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrotracing/NitroTracingOnLoad.kt +35 -0
- package/nitrogen/generated/ios/NitroTracing+autolinking.rb +62 -0
- package/nitrogen/generated/ios/NitroTracing-Swift-Cxx-Bridge.cpp +17 -0
- package/nitrogen/generated/ios/NitroTracing-Swift-Cxx-Bridge.hpp +27 -0
- package/nitrogen/generated/ios/NitroTracing-Swift-Cxx-Umbrella.hpp +38 -0
- package/nitrogen/generated/ios/NitroTracingAutolinking.mm +35 -0
- package/nitrogen/generated/ios/NitroTracingAutolinking.swift +16 -0
- package/nitrogen/generated/shared/c++/CompletedSpanOptions.hpp +122 -0
- package/nitrogen/generated/shared/c++/HybridRecordingSpec.cpp +31 -0
- package/nitrogen/generated/shared/c++/HybridRecordingSpec.hpp +100 -0
- package/nitrogen/generated/shared/c++/HybridTraceSpanSpec.cpp +23 -0
- package/nitrogen/generated/shared/c++/HybridTraceSpanSpec.hpp +65 -0
- package/nitrogen/generated/shared/c++/HybridTracingSpec.cpp +22 -0
- package/nitrogen/generated/shared/c++/HybridTracingSpec.hpp +68 -0
- package/nitrogen/generated/shared/c++/MarkEvent.hpp +102 -0
- package/nitrogen/generated/shared/c++/MarkOptions.hpp +99 -0
- package/nitrogen/generated/shared/c++/MetricEvent.hpp +110 -0
- package/nitrogen/generated/shared/c++/MetricOptions.hpp +107 -0
- package/nitrogen/generated/shared/c++/NativeSamplingOptions.hpp +87 -0
- package/nitrogen/generated/shared/c++/ReadOptions.hpp +87 -0
- package/nitrogen/generated/shared/c++/RecordingOptions.hpp +95 -0
- package/nitrogen/generated/shared/c++/RecordingStats.hpp +123 -0
- package/nitrogen/generated/shared/c++/SpanEvent.hpp +121 -0
- package/nitrogen/generated/shared/c++/SpanOptions.hpp +99 -0
- package/nitrogen/generated/shared/c++/SpanOutcome.hpp +84 -0
- package/nitrogen/generated/shared/c++/TraceAttribute.hpp +87 -0
- package/nitrogen/generated/shared/c++/TracePage.hpp +111 -0
- package/package.json +236 -0
- package/performance.ts +2 -0
- package/plugins.ts +24 -0
- package/react-native.config.js +16 -0
- package/react.ts +10 -0
- package/release-profiler.ts +6 -0
- package/sentry.ts +2 -0
- package/src/client/TracingSink.ts +25 -0
- package/src/client/createTraceClient.ts +439 -0
- package/src/client/playground.ts +143 -0
- package/src/expo/ExpoAdapter.ts +71 -0
- package/src/expo/index.ts +2 -0
- package/src/index.ts +8 -0
- package/src/plugins/TracePlugin.ts +22 -0
- package/src/plugins/errors.ts +69 -0
- package/src/plugins/nativeMetrics.ts +26 -0
- package/src/plugins/navigation.ts +111 -0
- package/src/plugins/network.ts +178 -0
- package/src/plugins/orderSpans.ts +22 -0
- package/src/plugins/performance.ts +120 -0
- package/src/plugins/releaseProfiler.ts +123 -0
- package/src/plugins/runtimeMetrics.ts +131 -0
- package/src/plugins/sentry.ts +176 -0
- package/src/plugins/startPlugins.ts +58 -0
- package/src/react/DetailView.tsx +514 -0
- package/src/react/ExplorerFilters.tsx +151 -0
- package/src/react/ExplorerView.tsx +243 -0
- package/src/react/InspectorControls.tsx +651 -0
- package/src/react/InspectorHeader.tsx +171 -0
- package/src/react/InspectorSheet.tsx +89 -0
- package/src/react/MetricsView.tsx +182 -0
- package/src/react/SummaryView.tsx +121 -0
- package/src/react/TimelineView.tsx +87 -0
- package/src/react/TraceInspector.tsx +196 -0
- package/src/react/TraceOverlay.tsx +585 -0
- package/src/react/explorerModel.ts +285 -0
- package/src/react/labels.ts +234 -0
- package/src/react/native.tsx +159 -0
- package/src/react/readSnapshot.ts +58 -0
- package/src/react/store.ts +31 -0
- package/src/react/topics.ts +427 -0
- package/src/react/useAppReadyMetric.ts +10 -0
- package/src/react/useLiveRecording.ts +43 -0
- package/src/react/useTraceViewer.ts +333 -0
- package/src/react/viewerModel.ts +172 -0
- package/src/specs/Recording.nitro.ts +40 -0
- package/src/specs/TraceSpan.nitro.ts +14 -0
- package/src/specs/Tracing.nitro.ts +14 -0
- package/src/types/CompletedSpanOptions.ts +15 -0
- package/src/types/EventContext.ts +8 -0
- package/src/types/MarkEvent.ts +3 -0
- package/src/types/MarkOptions.ts +6 -0
- package/src/types/MetricEvent.ts +8 -0
- package/src/types/MetricOptions.ts +10 -0
- package/src/types/NativeSamplingOptions.ts +7 -0
- package/src/types/ReadOptions.ts +7 -0
- package/src/types/RecordingOptions.ts +11 -0
- package/src/types/RecordingStats.ts +25 -0
- package/src/types/SpanEvent.ts +13 -0
- package/src/types/SpanOptions.ts +6 -0
- package/src/types/SpanOutcome.ts +2 -0
- package/src/types/TraceAttribute.ts +7 -0
- package/src/types/TraceAttributes.ts +4 -0
- package/src/types/TraceContext.ts +10 -0
- package/src/types/TracePage.ts +18 -0
- package/src/types.ts +17 -0
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __esm = (fn, res, err) => function __init() {
|
|
7
|
+
if (err) throw err[0];
|
|
8
|
+
try {
|
|
9
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
10
|
+
} catch (e) {
|
|
11
|
+
throw err = [e], e;
|
|
12
|
+
}
|
|
13
|
+
};
|
|
14
|
+
var __export = (target, all) => {
|
|
15
|
+
for (var name in all)
|
|
16
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
17
|
+
};
|
|
18
|
+
var __copyProps = (to, from, except, desc) => {
|
|
19
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
20
|
+
for (let key of __getOwnPropNames(from))
|
|
21
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
22
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
23
|
+
}
|
|
24
|
+
return to;
|
|
25
|
+
};
|
|
26
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
27
|
+
|
|
28
|
+
// src/index.ts
|
|
29
|
+
var src_exports = {};
|
|
30
|
+
__export(src_exports, {
|
|
31
|
+
Tracing: () => Tracing
|
|
32
|
+
});
|
|
33
|
+
var import_react_native_nitro_modules, Tracing;
|
|
34
|
+
var init_src = __esm({
|
|
35
|
+
"src/index.ts"() {
|
|
36
|
+
"use strict";
|
|
37
|
+
import_react_native_nitro_modules = require("react-native-nitro-modules");
|
|
38
|
+
Tracing = import_react_native_nitro_modules.NitroModules.createHybridObject("Tracing");
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
// release-profiler.ts
|
|
43
|
+
var release_profiler_exports = {};
|
|
44
|
+
__export(release_profiler_exports, {
|
|
45
|
+
createReleaseProfilerPlugin: () => createReleaseProfilerPlugin
|
|
46
|
+
});
|
|
47
|
+
module.exports = __toCommonJS(release_profiler_exports);
|
|
48
|
+
|
|
49
|
+
// src/plugins/releaseProfiler.ts
|
|
50
|
+
var owner;
|
|
51
|
+
var stopHermesSampler = () => {
|
|
52
|
+
try {
|
|
53
|
+
const { Tracing: Tracing2 } = (init_src(), __toCommonJS(src_exports));
|
|
54
|
+
Tracing2.disableHermesSampling();
|
|
55
|
+
} catch {
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
function createReleaseProfilerPlugin(api, options = {}) {
|
|
59
|
+
const identity = {};
|
|
60
|
+
let context;
|
|
61
|
+
let active = false;
|
|
62
|
+
let span;
|
|
63
|
+
let path;
|
|
64
|
+
let stopping;
|
|
65
|
+
const plugin = {
|
|
66
|
+
id: "release-profiler",
|
|
67
|
+
start(next) {
|
|
68
|
+
if (context)
|
|
69
|
+
throw new Error("Release profiler plugin is already attached");
|
|
70
|
+
context = next;
|
|
71
|
+
return {
|
|
72
|
+
async stop() {
|
|
73
|
+
try {
|
|
74
|
+
if (active) await plugin.stopProfiling();
|
|
75
|
+
} finally {
|
|
76
|
+
context = void 0;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
},
|
|
81
|
+
startProfiling() {
|
|
82
|
+
if (!context)
|
|
83
|
+
throw new Error("Attach release-profiler plugin before profiling");
|
|
84
|
+
if (owner) throw new Error("A release profiler session is already active");
|
|
85
|
+
if (api.startProfiling() === false)
|
|
86
|
+
throw new Error("Hermes sampling profiler is unavailable in this build");
|
|
87
|
+
owner = identity;
|
|
88
|
+
active = true;
|
|
89
|
+
path = void 0;
|
|
90
|
+
try {
|
|
91
|
+
span = context.recording.startSpan({
|
|
92
|
+
name: "hermes.profile",
|
|
93
|
+
correlationId: "",
|
|
94
|
+
attributes: [{ key: "source", value: "release-profiler" }]
|
|
95
|
+
});
|
|
96
|
+
} catch (error) {
|
|
97
|
+
context.reportError(error);
|
|
98
|
+
}
|
|
99
|
+
},
|
|
100
|
+
stopProfiling() {
|
|
101
|
+
if (stopping) return stopping;
|
|
102
|
+
if (!active)
|
|
103
|
+
return Promise.reject(
|
|
104
|
+
new Error("No release profiler session is active")
|
|
105
|
+
);
|
|
106
|
+
stopping = Promise.resolve().then(async () => {
|
|
107
|
+
try {
|
|
108
|
+
path = await api.stopProfiling(false);
|
|
109
|
+
span?.end("success");
|
|
110
|
+
try {
|
|
111
|
+
context?.recording.mark({
|
|
112
|
+
name: "hermes.profile.saved",
|
|
113
|
+
correlationId: "",
|
|
114
|
+
attributes: [
|
|
115
|
+
{ key: "source", value: "release-profiler" },
|
|
116
|
+
{ key: "path", value: path.slice(0, 512) }
|
|
117
|
+
]
|
|
118
|
+
});
|
|
119
|
+
} catch (error) {
|
|
120
|
+
context?.reportError(error);
|
|
121
|
+
}
|
|
122
|
+
return path;
|
|
123
|
+
} catch (error) {
|
|
124
|
+
span?.end("error");
|
|
125
|
+
throw error;
|
|
126
|
+
} finally {
|
|
127
|
+
;
|
|
128
|
+
(options.stopSampler ?? stopHermesSampler)();
|
|
129
|
+
active = false;
|
|
130
|
+
if (owner === identity) owner = void 0;
|
|
131
|
+
span = void 0;
|
|
132
|
+
stopping = void 0;
|
|
133
|
+
}
|
|
134
|
+
});
|
|
135
|
+
return stopping;
|
|
136
|
+
},
|
|
137
|
+
isProfiling: () => active,
|
|
138
|
+
getProfilePath: () => path
|
|
139
|
+
};
|
|
140
|
+
return plugin;
|
|
141
|
+
}
|
|
142
|
+
//# sourceMappingURL=release-profiler.cjs.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/index.ts", "../../release-profiler.ts", "../../src/plugins/releaseProfiler.ts"],
|
|
4
|
+
"sourcesContent": ["import { NitroModules } from 'react-native-nitro-modules'\nimport type { Tracing as TracingFactory } from './specs/Tracing.nitro'\n/** Native recording factory. See Recording for ownership and cleanup. */\nexport const Tracing =\n NitroModules.createHybridObject<TracingFactory>('Tracing')\nexport type { Recording } from './specs/Recording.nitro'\nexport type { TraceSpan } from './specs/TraceSpan.nitro'\nexport type * from './types'\n", "export { createReleaseProfilerPlugin } from './src/plugins/releaseProfiler'\nexport type {\n ReleaseProfilerApi,\n ReleaseProfilerOptions,\n ReleaseProfilerPlugin,\n} from './src/plugins/releaseProfiler'\n", "import type { TraceSpan } from '../specs/TraceSpan.nitro'\nimport type { PluginContext, TracePlugin } from './TracePlugin'\n/** Injected optional react-native-release-profiler module; never imported by core. */\nexport interface ReleaseProfilerApi {\n /** Start the process-wide Hermes sampler; false means unavailable. */\n startProfiling(): boolean | void\n /** Stop and save a local profile artifact. */\n stopProfiling(saveToDownloads?: boolean): Promise<string>\n}\n/** Manually controlled profiler integration. Sampling never starts on plugin setup. */\nexport interface ReleaseProfilerPlugin extends TracePlugin {\n /** Start one session owned by this plugin. */\n startProfiling(): void\n /** Finish profiling and return the artifact's local path. */\n stopProfiling(): Promise<string>\n /** Whether this plugin owns an active or stopping profile. */\n isProfiling(): boolean\n /** Last successful artifact; not sent to remote exporters. */\n getProfilePath(): string | undefined\n}\n// Hermes profiling is process-wide, so two plugin instances must not compete.\nlet owner: object | undefined\n/** Stops Hermes sampling for real; on RN 0.85 Android the profiler's own stop restarts it. */\nconst stopHermesSampler = () => {\n try {\n const { Tracing } = require('../index') as typeof import('../index')\n Tracing.disableHermesSampling()\n } catch {\n // No native module (tests, non-native hosts): nothing is sampling.\n }\n}\nexport interface ReleaseProfilerOptions {\n /** Runs after every stop. Defaults to Tracing.disableHermesSampling(). */\n stopSampler?: () => void\n}\n/** Attach manual Hermes profile controls to a recording. */\nexport function createReleaseProfilerPlugin(\n api: ReleaseProfilerApi,\n options: ReleaseProfilerOptions = {}\n): ReleaseProfilerPlugin {\n const identity = {}\n let context: PluginContext | undefined\n let active = false\n let span: TraceSpan | undefined\n let path: string | undefined\n let stopping: Promise<string> | undefined\n const plugin: ReleaseProfilerPlugin = {\n id: 'release-profiler',\n start(next) {\n if (context)\n throw new Error('Release profiler plugin is already attached')\n context = next\n return {\n async stop() {\n try {\n if (active) await plugin.stopProfiling()\n } finally {\n context = undefined\n }\n },\n }\n },\n startProfiling() {\n if (!context)\n throw new Error('Attach release-profiler plugin before profiling')\n if (owner) throw new Error('A release profiler session is already active')\n if (api.startProfiling() === false)\n throw new Error('Hermes sampling profiler is unavailable in this build')\n owner = identity\n active = true\n path = undefined\n try {\n span = context.recording.startSpan({\n name: 'hermes.profile',\n correlationId: '',\n attributes: [{ key: 'source', value: 'release-profiler' }],\n })\n } catch (error) {\n context.reportError(error)\n }\n },\n stopProfiling() {\n if (stopping) return stopping\n if (!active)\n return Promise.reject(\n new Error('No release profiler session is active')\n )\n stopping = Promise.resolve().then(async () => {\n try {\n path = await api.stopProfiling(false)\n span?.end('success')\n // Lets a Perfetto export point at the .cpuprofile covering the span above.\n try {\n context?.recording.mark({\n name: 'hermes.profile.saved',\n correlationId: '',\n attributes: [\n { key: 'source', value: 'release-profiler' },\n { key: 'path', value: path.slice(0, 512) },\n ],\n })\n } catch (error) {\n context?.reportError(error)\n }\n return path\n } catch (error) {\n span?.end('error')\n throw error\n } finally {\n ;(options.stopSampler ?? stopHermesSampler)()\n active = false\n if (owner === identity) owner = undefined\n span = undefined\n stopping = undefined\n }\n })\n return stopping\n },\n isProfiling: () => active,\n getProfilePath: () => path,\n }\n return plugin\n}\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA,uCAGa;AAHb;AAAA;AAAA;AAAA,wCAA6B;AAGtB,IAAM,UACX,+CAAa,mBAAmC,SAAS;AAAA;AAAA;;;ACJ3D;AAAA;AAAA;AAAA;AAAA;;;ACqBA,IAAI;AAEJ,IAAM,oBAAoB,MAAM;AAC9B,MAAI;AACF,UAAM,EAAE,SAAAA,SAAQ,IAAI;AACpB,IAAAA,SAAQ,sBAAsB;AAAA,EAChC,QAAQ;AAAA,EAER;AACF;AAMO,SAAS,4BACd,KACA,UAAkC,CAAC,GACZ;AACvB,QAAM,WAAW,CAAC;AAClB,MAAI;AACJ,MAAI,SAAS;AACb,MAAI;AACJ,MAAI;AACJ,MAAI;AACJ,QAAM,SAAgC;AAAA,IACpC,IAAI;AAAA,IACJ,MAAM,MAAM;AACV,UAAI;AACF,cAAM,IAAI,MAAM,6CAA6C;AAC/D,gBAAU;AACV,aAAO;AAAA,QACL,MAAM,OAAO;AACX,cAAI;AACF,gBAAI,OAAQ,OAAM,OAAO,cAAc;AAAA,UACzC,UAAE;AACA,sBAAU;AAAA,UACZ;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,IACA,iBAAiB;AACf,UAAI,CAAC;AACH,cAAM,IAAI,MAAM,iDAAiD;AACnE,UAAI,MAAO,OAAM,IAAI,MAAM,8CAA8C;AACzE,UAAI,IAAI,eAAe,MAAM;AAC3B,cAAM,IAAI,MAAM,uDAAuD;AACzE,cAAQ;AACR,eAAS;AACT,aAAO;AACP,UAAI;AACF,eAAO,QAAQ,UAAU,UAAU;AAAA,UACjC,MAAM;AAAA,UACN,eAAe;AAAA,UACf,YAAY,CAAC,EAAE,KAAK,UAAU,OAAO,mBAAmB,CAAC;AAAA,QAC3D,CAAC;AAAA,MACH,SAAS,OAAO;AACd,gBAAQ,YAAY,KAAK;AAAA,MAC3B;AAAA,IACF;AAAA,IACA,gBAAgB;AACd,UAAI,SAAU,QAAO;AACrB,UAAI,CAAC;AACH,eAAO,QAAQ;AAAA,UACb,IAAI,MAAM,uCAAuC;AAAA,QACnD;AACF,iBAAW,QAAQ,QAAQ,EAAE,KAAK,YAAY;AAC5C,YAAI;AACF,iBAAO,MAAM,IAAI,cAAc,KAAK;AACpC,gBAAM,IAAI,SAAS;AAEnB,cAAI;AACF,qBAAS,UAAU,KAAK;AAAA,cACtB,MAAM;AAAA,cACN,eAAe;AAAA,cACf,YAAY;AAAA,gBACV,EAAE,KAAK,UAAU,OAAO,mBAAmB;AAAA,gBAC3C,EAAE,KAAK,QAAQ,OAAO,KAAK,MAAM,GAAG,GAAG,EAAE;AAAA,cAC3C;AAAA,YACF,CAAC;AAAA,UACH,SAAS,OAAO;AACd,qBAAS,YAAY,KAAK;AAAA,UAC5B;AACA,iBAAO;AAAA,QACT,SAAS,OAAO;AACd,gBAAM,IAAI,OAAO;AACjB,gBAAM;AAAA,QACR,UAAE;AACA;AAAC,WAAC,QAAQ,eAAe,mBAAmB;AAC5C,mBAAS;AACT,cAAI,UAAU,SAAU,SAAQ;AAChC,iBAAO;AACP,qBAAW;AAAA,QACb;AAAA,MACF,CAAC;AACD,aAAO;AAAA,IACT;AAAA,IACA,aAAa,MAAM;AAAA,IACnB,gBAAgB,MAAM;AAAA,EACxB;AACA,SAAO;AACT;",
|
|
6
|
+
"names": ["Tracing"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// sentry.ts
|
|
21
|
+
var sentry_exports = {};
|
|
22
|
+
__export(sentry_exports, {
|
|
23
|
+
createSentryPlugin: () => createSentryPlugin
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(sentry_exports);
|
|
26
|
+
|
|
27
|
+
// src/plugins/orderSpans.ts
|
|
28
|
+
function orderSpans(spans) {
|
|
29
|
+
const byId = new Map(spans.map((span) => [span.spanId, span]));
|
|
30
|
+
const children = /* @__PURE__ */ new Map();
|
|
31
|
+
const ordered = [];
|
|
32
|
+
for (const span of byId.values()) {
|
|
33
|
+
if (!span.parentSpanId || !byId.has(span.parentSpanId)) ordered.push(span);
|
|
34
|
+
else {
|
|
35
|
+
const siblings = children.get(span.parentSpanId);
|
|
36
|
+
if (siblings) siblings.push(span);
|
|
37
|
+
else children.set(span.parentSpanId, [span]);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
for (let index = 0; index < ordered.length; index++) {
|
|
41
|
+
const descendants = children.get(ordered[index].spanId);
|
|
42
|
+
if (descendants) for (const child of descendants) ordered.push(child);
|
|
43
|
+
}
|
|
44
|
+
if (ordered.length !== byId.size)
|
|
45
|
+
throw new Error("Cannot export cyclic span parents");
|
|
46
|
+
return ordered;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// src/plugins/sentry.ts
|
|
50
|
+
function createSentryPlugin(options) {
|
|
51
|
+
return {
|
|
52
|
+
id: "sentry",
|
|
53
|
+
start({ recording, reportError }) {
|
|
54
|
+
const { sentry } = options;
|
|
55
|
+
const stats = recording.getStats();
|
|
56
|
+
const anchor = stats.startedAtUnixMs;
|
|
57
|
+
const client = sentry.getClient();
|
|
58
|
+
if (options.captureSpans && !client)
|
|
59
|
+
throw new Error("Initialize Sentry before enabling local capture");
|
|
60
|
+
const recordMeasurements = (data, start, anchorMs) => {
|
|
61
|
+
const end = (data.timestamp ?? data.start_timestamp) * 1e3 - anchorMs;
|
|
62
|
+
const metric = (name, value, unit) => {
|
|
63
|
+
if (typeof value !== "number" || !Number.isFinite(value)) return;
|
|
64
|
+
recording.recordMetric({
|
|
65
|
+
name,
|
|
66
|
+
value,
|
|
67
|
+
unit,
|
|
68
|
+
timestampMs: Math.max(0, end),
|
|
69
|
+
correlationId: data.trace_id,
|
|
70
|
+
attributes: [
|
|
71
|
+
{ key: "source", value: "sentry" },
|
|
72
|
+
{
|
|
73
|
+
key: "span",
|
|
74
|
+
value: (data.description || data.op || "").slice(0, 256)
|
|
75
|
+
}
|
|
76
|
+
]
|
|
77
|
+
});
|
|
78
|
+
};
|
|
79
|
+
metric("ui.frames.total", data.data?.["frames.total"], "count");
|
|
80
|
+
metric("ui.frames.slow", data.data?.["frames.slow"], "count");
|
|
81
|
+
metric("ui.frames.frozen", data.data?.["frames.frozen"], "count");
|
|
82
|
+
if (data.op === "app.start.cold" || data.op === "app.start.warm")
|
|
83
|
+
metric(data.op, end - start, "ms");
|
|
84
|
+
};
|
|
85
|
+
const unsubscribe = options.captureSpans ? client.on("spanEnd", (span) => {
|
|
86
|
+
try {
|
|
87
|
+
const data = sentry.spanToJSON(span);
|
|
88
|
+
if (data.data?.["nitro.exported"] || data.timestamp === void 0)
|
|
89
|
+
return;
|
|
90
|
+
const start = data.start_timestamp * 1e3 - anchor;
|
|
91
|
+
if (start < 0) return;
|
|
92
|
+
recording.recordSpan({
|
|
93
|
+
name: (data.description || data.op || "sentry.span").slice(
|
|
94
|
+
0,
|
|
95
|
+
128
|
|
96
|
+
),
|
|
97
|
+
correlationId: data.trace_id,
|
|
98
|
+
timestampMs: start,
|
|
99
|
+
sourceSpanId: `sentry:${data.trace_id}:${data.span_id}`,
|
|
100
|
+
sourceParentSpanId: data.parent_span_id ? `sentry:${data.trace_id}:${data.parent_span_id}` : void 0,
|
|
101
|
+
durationMs: Math.max(
|
|
102
|
+
0,
|
|
103
|
+
(data.timestamp - data.start_timestamp) * 1e3
|
|
104
|
+
),
|
|
105
|
+
outcome: data.status && data.status !== "ok" ? "error" : "success",
|
|
106
|
+
attributes: [
|
|
107
|
+
{ key: "source", value: "sentry" },
|
|
108
|
+
{ key: "sentry.span_id", value: data.span_id },
|
|
109
|
+
{
|
|
110
|
+
key: "sentry.parent_span_id",
|
|
111
|
+
value: data.parent_span_id || ""
|
|
112
|
+
}
|
|
113
|
+
]
|
|
114
|
+
});
|
|
115
|
+
recordMeasurements(data, start, anchor);
|
|
116
|
+
} catch (error) {
|
|
117
|
+
reportError(error);
|
|
118
|
+
}
|
|
119
|
+
}) : void 0;
|
|
120
|
+
return {
|
|
121
|
+
stop() {
|
|
122
|
+
unsubscribe?.();
|
|
123
|
+
},
|
|
124
|
+
async flush() {
|
|
125
|
+
if (options.exportSpans !== true) return;
|
|
126
|
+
if (!sentry.getClient())
|
|
127
|
+
throw new Error("Initialize Sentry before exporting traces");
|
|
128
|
+
const spans = [];
|
|
129
|
+
let cursor = 0;
|
|
130
|
+
while (true) {
|
|
131
|
+
const page = await recording.readEvents({
|
|
132
|
+
afterSequence: cursor,
|
|
133
|
+
limit: 1e3
|
|
134
|
+
});
|
|
135
|
+
spans.push(
|
|
136
|
+
...page.spans.filter(
|
|
137
|
+
(s) => !s.attributes.some(
|
|
138
|
+
(a) => a.key === "source" && a.value === "sentry"
|
|
139
|
+
)
|
|
140
|
+
)
|
|
141
|
+
);
|
|
142
|
+
if (page.nextSequence === cursor) break;
|
|
143
|
+
cursor = page.nextSequence;
|
|
144
|
+
}
|
|
145
|
+
const ordered = orderSpans(spans);
|
|
146
|
+
const handles = /* @__PURE__ */ new Map();
|
|
147
|
+
const keys = new Set(options.exportedAttributeKeys ?? []);
|
|
148
|
+
for (let index = 0; index < ordered.length; index++) {
|
|
149
|
+
if (index > 0 && index % 250 === 0)
|
|
150
|
+
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
151
|
+
const span = ordered[index];
|
|
152
|
+
const id = span.spanId;
|
|
153
|
+
const parentSpan = handles.get(span.parentSpanId);
|
|
154
|
+
const exported = sentry.startInactiveSpan({
|
|
155
|
+
name: span.name,
|
|
156
|
+
op: "nitro.trace",
|
|
157
|
+
startTime: (anchor + span.timestampMs) / 1e3,
|
|
158
|
+
parentSpan: parentSpan ?? null,
|
|
159
|
+
forceTransaction: !parentSpan,
|
|
160
|
+
attributes: {
|
|
161
|
+
...Object.fromEntries(
|
|
162
|
+
span.attributes.filter((a) => keys.has(a.key)).map((a) => [a.key, a.value])
|
|
163
|
+
),
|
|
164
|
+
"nitro.exported": true,
|
|
165
|
+
"nitro.span_id": id,
|
|
166
|
+
"nitro.parent_missing": Boolean(
|
|
167
|
+
span.parentSpanId && !parentSpan
|
|
168
|
+
),
|
|
169
|
+
"nitro.outcome": span.outcome
|
|
170
|
+
}
|
|
171
|
+
});
|
|
172
|
+
exported.setStatus(
|
|
173
|
+
span.outcome === "success" ? { code: 1 } : { code: 2, message: span.outcome }
|
|
174
|
+
);
|
|
175
|
+
handles.set(id, exported);
|
|
176
|
+
}
|
|
177
|
+
for (let index = ordered.length - 1; index >= 0; index--) {
|
|
178
|
+
const span = ordered[index];
|
|
179
|
+
handles.get(span.spanId).end((anchor + span.timestampMs + span.durationMs) / 1e3);
|
|
180
|
+
if (index > 0 && index % 250 === 0)
|
|
181
|
+
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
//# sourceMappingURL=sentry.cjs.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../sentry.ts", "../../src/plugins/orderSpans.ts", "../../src/plugins/sentry.ts"],
|
|
4
|
+
"sourcesContent": ["export { createSentryPlugin } from './src/plugins/sentry'\nexport type { SentryPluginOptions } from './src/plugins/sentry'\n", "import type { SpanEvent } from '../types'\n/** Parent-first order in O(n), including parents delivered after their children. */\nexport function orderSpans(spans: readonly SpanEvent[]): SpanEvent[] {\n const byId = new Map(spans.map((span) => [span.spanId, span]))\n const children = new Map<string, SpanEvent[]>()\n const ordered: SpanEvent[] = []\n for (const span of byId.values()) {\n if (!span.parentSpanId || !byId.has(span.parentSpanId)) ordered.push(span)\n else {\n const siblings = children.get(span.parentSpanId)\n if (siblings) siblings.push(span)\n else children.set(span.parentSpanId, [span])\n }\n }\n for (let index = 0; index < ordered.length; index++) {\n const descendants = children.get(ordered[index]!.spanId)\n if (descendants) for (const child of descendants) ordered.push(child)\n }\n if (ordered.length !== byId.size)\n throw new Error('Cannot export cyclic span parents')\n return ordered\n}\n", "import type * as Sentry from '@sentry/react-native'\nimport type { SpanEvent } from '../types'\nimport type { TracePlugin } from './TracePlugin'\nimport { orderSpans } from './orderSpans'\n/** Optional Sentry capabilities; SDK initialization and consent remain app-owned. */\nexport interface SentryPluginOptions {\n /** Inject an installed SDK. This module has no runtime SDK dependency. */\n sentry: Pick<typeof Sentry, 'getClient' | 'spanToJSON' | 'startInactiveSpan'>\n /** Capture observable SDK spans locally. Defaults to false; sampling applies. */\n captureSpans?: boolean\n /** Explicitly opt into sending retained span names/timing/status to Sentry on stop. Defaults to false. */\n exportSpans?: boolean\n /** Only these sanitized custom attribute keys may leave the device. Defaults to none. */\n exportedAttributeKeys?: readonly string[]\n}\n/** Optional SDK measurements and opt-in export; neither direction is enabled implicitly. */\nexport function createSentryPlugin(options: SentryPluginOptions): TracePlugin {\n return {\n id: 'sentry',\n start({ recording, reportError }) {\n const { sentry } = options\n const stats = recording.getStats()\n const anchor = stats.startedAtUnixMs\n const client = sentry.getClient()\n if (options.captureSpans && !client)\n throw new Error('Initialize Sentry before enabling local capture')\n /** Sentry as the measurement layer: its frame and app-start data use the native metric names. */\n const recordMeasurements = (\n data: ReturnType<typeof sentry.spanToJSON>,\n start: number,\n anchorMs: number\n ) => {\n const end = (data.timestamp ?? data.start_timestamp) * 1000 - anchorMs\n const metric = (name: string, value: unknown, unit: string) => {\n if (typeof value !== 'number' || !Number.isFinite(value)) return\n recording.recordMetric({\n name,\n value,\n unit,\n timestampMs: Math.max(0, end),\n correlationId: data.trace_id,\n attributes: [\n { key: 'source', value: 'sentry' },\n {\n key: 'span',\n value: (data.description || data.op || '').slice(0, 256),\n },\n ],\n })\n }\n // Set by Sentry's nativeFrames integration on spans it measured.\n metric('ui.frames.total', data.data?.['frames.total'], 'count')\n metric('ui.frames.slow', data.data?.['frames.slow'], 'count')\n metric('ui.frames.frozen', data.data?.['frames.frozen'], 'count')\n // appStart integration spans: app.start.cold / app.start.warm.\n if (data.op === 'app.start.cold' || data.op === 'app.start.warm')\n metric(data.op, end - start, 'ms')\n }\n const unsubscribe = options.captureSpans\n ? client!.on('spanEnd', (span) => {\n try {\n const data = sentry.spanToJSON(span)\n if (data.data?.['nitro.exported'] || data.timestamp === undefined)\n return\n const start = data.start_timestamp * 1000 - anchor\n if (start < 0) return\n recording.recordSpan({\n name: (data.description || data.op || 'sentry.span').slice(\n 0,\n 128\n ),\n correlationId: data.trace_id,\n timestampMs: start,\n sourceSpanId: `sentry:${data.trace_id}:${data.span_id}`,\n sourceParentSpanId: data.parent_span_id\n ? `sentry:${data.trace_id}:${data.parent_span_id}`\n : undefined,\n durationMs: Math.max(\n 0,\n (data.timestamp - data.start_timestamp) * 1000\n ),\n outcome:\n data.status && data.status !== 'ok' ? 'error' : 'success',\n attributes: [\n { key: 'source', value: 'sentry' },\n { key: 'sentry.span_id', value: data.span_id },\n {\n key: 'sentry.parent_span_id',\n value: data.parent_span_id || '',\n },\n ],\n })\n recordMeasurements(data, start, anchor)\n } catch (error) {\n reportError(error)\n }\n })\n : undefined\n return {\n stop() {\n unsubscribe?.()\n },\n async flush() {\n if (options.exportSpans !== true) return\n if (!sentry.getClient())\n throw new Error('Initialize Sentry before exporting traces')\n const spans: SpanEvent[] = []\n let cursor = 0\n while (true) {\n const page = await recording.readEvents({\n afterSequence: cursor,\n limit: 1000,\n })\n spans.push(\n ...page.spans.filter(\n (s) =>\n !s.attributes.some(\n (a) => a.key === 'source' && a.value === 'sentry'\n )\n )\n )\n if (page.nextSequence === cursor) break\n cursor = page.nextSequence\n }\n const ordered = orderSpans(spans)\n const handles = new Map<\n string,\n ReturnType<typeof sentry.startInactiveSpan>\n >()\n const keys = new Set(options.exportedAttributeKeys ?? [])\n for (let index = 0; index < ordered.length; index++) {\n if (index > 0 && index % 250 === 0)\n await new Promise<void>((resolve) => setTimeout(resolve, 0))\n const span = ordered[index]!\n const id = span.spanId\n const parentSpan = handles.get(span.parentSpanId)\n const exported = sentry.startInactiveSpan({\n name: span.name,\n op: 'nitro.trace',\n startTime: (anchor + span.timestampMs) / 1000,\n parentSpan: parentSpan ?? null,\n forceTransaction: !parentSpan,\n attributes: {\n ...Object.fromEntries(\n span.attributes\n .filter((a) => keys.has(a.key))\n .map((a) => [a.key, a.value])\n ),\n 'nitro.exported': true,\n 'nitro.span_id': id,\n 'nitro.parent_missing': Boolean(\n span.parentSpanId && !parentSpan\n ),\n 'nitro.outcome': span.outcome,\n },\n })\n exported.setStatus(\n span.outcome === 'success'\n ? { code: 1 }\n : { code: 2, message: span.outcome }\n )\n handles.set(id, exported)\n }\n for (let index = ordered.length - 1; index >= 0; index--) {\n const span = ordered[index]!\n handles\n .get(span.spanId)!\n .end((anchor + span.timestampMs + span.durationMs) / 1000)\n if (index > 0 && index % 250 === 0)\n await new Promise<void>((resolve) => setTimeout(resolve, 0))\n }\n },\n }\n },\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|