@sentry/remix
Version:
Official Sentry SDK for Remix
138 lines (134 loc) • 5.42 kB
JavaScript
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
const core = require('@sentry/core');
const server = require('@sentry/core/server');
const react = require('@sentry/react');
const React = require('react');
const debugBuild = require('../utils/debug-build.js');
const remixRouteParameterization = require('./remixRouteParameterization.js');
const attributes = require('@sentry/conventions/attributes');
const op = require('@sentry/conventions/op');
let _useEffect;
let _useLocation;
let _useMatches;
let _instrumentNavigation;
function getInitPathName() {
if (react.WINDOW.location) {
return react.WINDOW.location.pathname;
}
return void 0;
}
function getTransactionNameAndSource(pathname, routeId) {
const parameterizedRoute = pathname ? remixRouteParameterization.maybeParameterizeRemixRoute(pathname) : void 0;
if (parameterizedRoute) {
return { name: parameterizedRoute, source: "route" };
}
if (remixRouteParameterization.hasManifest()) {
return { name: pathname || routeId, source: "url" };
}
return { name: routeId, source: "route" };
}
function startPageloadSpan(client) {
const initPathName = getInitPathName();
if (!initPathName) {
return;
}
const parameterizedRoute = remixRouteParameterization.maybeParameterizeRemixRoute(initPathName);
const spanName = parameterizedRoute || initPathName;
const source = parameterizedRoute ? "route" : "url";
const spanContext = {
// With span streaming, span names have to be low cardinality, so we can't fall back to the URL.
name: source === "route" || !core.hasSpanStreamingEnabled(client) ? spanName : core.PAGELOAD_SPAN_NAME_FALLBACK,
attributes: {
[attributes.SENTRY_OP]: op.PAGELOAD,
[attributes.SENTRY_ORIGIN]: "auto.pageload.remix",
[attributes.SENTRY_SEGMENT_NAME_SOURCE]: source,
...source === "route" && { [attributes.URL_TEMPLATE]: spanName }
}
};
react.startBrowserTracingPageLoadSpan(client, spanContext);
}
function startNavigationSpan(matches, location) {
const lastMatch = matches[matches.length - 1];
const client = react.getClient();
if (!client || !lastMatch) {
return;
}
const { name, source } = getTransactionNameAndSource(location.pathname, lastMatch.id);
const spanContext = {
// With span streaming, span names have to be low cardinality, so we can't fall back to the URL.
name: source === "route" || !core.hasSpanStreamingEnabled(client) ? name : core.NAVIGATION_SPAN_NAME_FALLBACK,
attributes: {
[attributes.SENTRY_OP]: op.NAVIGATION,
[attributes.SENTRY_ORIGIN]: "auto.navigation.remix",
[attributes.SENTRY_SEGMENT_NAME_SOURCE]: source,
...source === "route" && { [attributes.URL_TEMPLATE]: name }
}
};
react.startBrowserTracingNavigationSpan(client, spanContext);
}
function withSentry(OrigApp, useEffect, useLocation, useMatches, instrumentNavigation) {
const SentryRoot = (props) => {
setGlobals({ useEffect, useLocation, useMatches, instrumentNavigation: instrumentNavigation || true });
if (!_useEffect || !_useLocation || !_useMatches) {
debugBuild.DEBUG_BUILD && !server.isNodeEnv() && core.debug.warn("Remix SDK was unable to wrap your root because of one or more missing parameters.");
return /* @__PURE__ */ React.createElement(OrigApp, { ...props });
}
let isBaseLocation = false;
const location = _useLocation();
const matches = _useMatches();
_useEffect(() => {
const lastMatch = matches?.[matches.length - 1];
if (lastMatch) {
const { name, source } = getTransactionNameAndSource(location.pathname, lastMatch.id);
core.getCurrentScope().setTransactionName(name);
const activeRootSpan = core.getActiveSpan();
if (activeRootSpan) {
const transaction = core.getRootSpan(activeRootSpan);
if (transaction) {
const client = react.getClient();
const isUnparameterizedStreamedPageload = source !== "route" && !!client && core.hasSpanStreamingEnabled(client);
transaction.updateName(isUnparameterizedStreamedPageload ? core.PAGELOAD_SPAN_NAME_FALLBACK : name);
transaction.setAttribute(attributes.SENTRY_SEGMENT_NAME_SOURCE, source);
if (source === "route") {
transaction.setAttribute(attributes.URL_TEMPLATE, name);
}
}
}
}
isBaseLocation = true;
}, []);
_useEffect(() => {
const activeRootSpan = core.getActiveSpan();
if (isBaseLocation) {
if (activeRootSpan) {
activeRootSpan.end();
}
return;
}
if (_instrumentNavigation && matches?.length) {
if (activeRootSpan) {
activeRootSpan.end();
}
startNavigationSpan(matches, location);
}
}, [location]);
isBaseLocation = false;
return /* @__PURE__ */ React.createElement(OrigApp, { ...props });
};
return SentryRoot;
}
function setGlobals({
useEffect,
useLocation,
useMatches,
instrumentNavigation
}) {
_useEffect = useEffect || _useEffect;
_useLocation = useLocation || _useLocation;
_useMatches = useMatches || _useMatches;
_instrumentNavigation = instrumentNavigation ?? _instrumentNavigation;
}
exports.setGlobals = setGlobals;
exports.startPageloadSpan = startPageloadSpan;
exports.withSentry = withSentry;
//# sourceMappingURL=performance.js.map