@sentry/nextjs
Version:
Official Sentry SDK for Next.js
68 lines (65 loc) • 2.69 kB
JavaScript
import { createContextKey, trace, context } from '@opentelemetry/api';
import { ATTR_NEXT_SPAN_NAME, ATTR_NEXT_SPAN_TYPE } from '../common/nextSpanAttributes.js';
const APP_RENDER_BODY_SPAN_TYPE = "AppRender.getBodyResult";
const PRERENDER_ROUTE_SPAN_NAME_PREFIX = "prerender route";
const PRERENDER_CONTEXT_KEY = createContextKey("sentry.nextjs.prerender");
const prerenderSpans = /* @__PURE__ */ new WeakSet();
function isPrerenderSpanStart(name, options) {
const attributes = options?.attributes;
const spanName = attributes?.[ATTR_NEXT_SPAN_NAME] ?? name;
return attributes?.[ATTR_NEXT_SPAN_TYPE] === APP_RENDER_BODY_SPAN_TYPE && typeof spanName === "string" && spanName.startsWith(PRERENDER_ROUTE_SPAN_NAME_PREFIX);
}
function isPrerenderContext(ctx) {
if (ctx.getValue(PRERENDER_CONTEXT_KEY) === true) {
return true;
}
const span = trace.getSpan(ctx);
return !!span && prerenderSpans.has(span);
}
function wrapTracer(tracer) {
return {
startSpan: (name, options, ctx) => {
const span = tracer.startSpan(name, options, ctx);
if (isPrerenderSpanStart(name, options)) {
prerenderSpans.add(span);
}
return span;
},
startActiveSpan: (name, ...args) => {
const startActiveSpan = tracer.startActiveSpan.bind(tracer);
const options = typeof args[0] === "function" ? void 0 : args[0];
if (!isPrerenderSpanStart(name, options)) {
return startActiveSpan(name, ...args);
}
const explicitContext = args.length === 3 ? args[1] : void 0;
if (explicitContext) {
return startActiveSpan(name, args[0], explicitContext.setValue(PRERENDER_CONTEXT_KEY, true), args[2]);
}
return context.with(context.active().setValue(PRERENDER_CONTEXT_KEY, true), () => startActiveSpan(name, ...args));
}
};
}
const markedProviders = /* @__PURE__ */ new WeakSet();
function markPrerendersOnTracerProvider(provider) {
if (markedProviders.has(provider)) {
return;
}
markedProviders.add(provider);
const wrappedTracers = /* @__PURE__ */ new WeakMap();
const getTracer = provider.getTracer.bind(provider);
provider.getTracer = (...args) => {
const tracer = getTracer(...args);
let wrapped = wrappedTracers.get(tracer);
if (!wrapped) {
wrapped = wrapTracer(tracer);
wrappedTracers.set(tracer, wrapped);
}
return wrapped;
};
}
function getGlobalTracerProvider() {
const provider = trace.getTracerProvider();
return "getDelegate" in provider ? provider.getDelegate() : provider;
}
export { getGlobalTracerProvider, isPrerenderContext, isPrerenderSpanStart, markPrerendersOnTracerProvider };
//# sourceMappingURL=prerenderContext.js.map