@voltro/plugin-sentry 0.86.0 → 0.88.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.
@@ -1,4 +1,4 @@
1
- //#region src/breadcrumbs.ts
1
+ // src/breadcrumbs.ts
2
2
  var e = {
3
3
  trace: "debug",
4
4
  debug: "debug",
@@ -43,5 +43,4 @@ var e = {
43
43
  }
44
44
  };
45
45
  };
46
- //#endregion
47
46
  export { n as makeBreadcrumbRing, t as toBreadcrumb };
package/dist/capture.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { Cause as e } from "effect";
2
2
  import { withheldServerError as t } from "@voltro/protocol";
3
- //#region src/capture.ts
3
+ // src/capture.ts
4
4
  var n = (t) => e.squash(t), r = (e, n, r = []) => {
5
5
  e.withScope((i) => {
6
6
  i.setTag("voltro.errorSource", n.source), n.name !== void 0 && i.setTag("voltro.name", n.name), n.traceId !== void 0 && i.setContext("trace", { trace_id: n.traceId }), n.fields !== void 0 && i.setContext("voltro", n.fields);
@@ -39,5 +39,4 @@ var n = (t) => e.squash(t), r = (e, n, r = []) => {
39
39
  e.captureException(o);
40
40
  });
41
41
  };
42
- //#endregion
43
42
  export { i as INFRASTRUCTURE_FAILURE_TAGS, r as captureServerError, c as captureToSentry, n as causeToError, a as isInfrastructureFailure, o as resolveCaptureFailures, s as shouldCapture };
package/dist/dsn.js CHANGED
@@ -1,4 +1,4 @@
1
- //#region src/dsn.ts
1
+ // src/dsn.ts
2
2
  var e = (e) => {
3
3
  if (!e) return null;
4
4
  try {
@@ -13,5 +13,4 @@ var e = (e) => {
13
13
  return null;
14
14
  }
15
15
  };
16
- //#endregion
17
16
  export { e as parseDsn };
package/dist/index.d.ts CHANGED
@@ -64,7 +64,8 @@ declare interface SentryDsn {
64
64
  *
65
65
  * Merge contract: the bag is spread FIRST, then the plugin's own keys — so
66
66
  * the plugin stays authoritative for everything it manages (`dsn`,
67
- * `skipOpenTelemetrySetup`, `tracesSampleRate`, and `environment` /
67
+ * `enableOpenTelemetrySetup` and `tracesSampleRate` (both dropped: the
68
+ * framework owns tracing), and `environment` /
68
69
  * `release` / `profilesSampleRate` when set). `integrations` is the one
69
70
  * exception: user integrations are APPENDED to the plugin's own, never
70
71
  * replacing them. */
package/dist/index.js CHANGED
@@ -2,12 +2,13 @@ import { parseDsn as e } from "./dsn.js";
2
2
  import { makeBreadcrumbRing as t, toBreadcrumb as n } from "./breadcrumbs.js";
3
3
  import { captureServerError as r, captureToSentry as i, causeToError as a, resolveCaptureFailures as o } from "./capture.js";
4
4
  import { initSentryServer as s, sentryActiveFields as c } from "./server.js";
5
- import { Effect as l } from "effect";
6
- import { pluginEnv as u } from "@voltro/env";
7
- import { addSink as d } from "@voltro/logger";
8
- import { definePlugin as f, subscribeServerErrors as p } from "@voltro/protocol";
9
- //#region src/index.ts
10
- var m = u([
5
+ import { sentryOtlpSpanProcessor as l } from "./otlpTraces.js";
6
+ import { Effect as u } from "effect";
7
+ import { pluginEnv as d } from "@voltro/env";
8
+ import { addSink as f } from "@voltro/logger";
9
+ import { definePlugin as p, subscribeServerErrors as m } from "@voltro/protocol";
10
+ // src/index.ts
11
+ var h = d([
11
12
  {
12
13
  name: "SENTRY_DSN",
13
14
  required: !1,
@@ -26,87 +27,88 @@ var m = u([
26
27
  secret: !1,
27
28
  description: "Release identifier for Sentry release health + source maps."
28
29
  }
29
- ]), h = (n = {}) => {
30
- let a = m.read("SENTRY_DSN", n.dsn), u = e(a), h = n.name ? `@voltro/plugin-sentry#${n.name}` : "@voltro/plugin-sentry";
31
- if (!u) return f({
32
- name: h,
30
+ ]), g = (n = {}) => {
31
+ let a = h.read("SENTRY_DSN", n.dsn), d = e(a), g = n.name ? `@voltro/plugin-sentry#${n.name}` : "@voltro/plugin-sentry";
32
+ if (!d) return p({
33
+ name: g,
33
34
  description: "Sentry error tracking (inactive — no valid SENTRY_DSN).",
34
- onActivate: (e) => l.sync(() => e.logger.warn("sentry inactive — no valid DSN (set `dsn` or SENTRY_DSN)")),
35
- onDeactivate: () => l.void
35
+ onActivate: (e) => u.sync(() => e.logger.warn("sentry inactive — no valid DSN (set `dsn` or SENTRY_DSN)")),
36
+ onDeactivate: () => u.void
36
37
  });
37
- let g = m.read("SENTRY_ENVIRONMENT", n.environment), _ = m.read("SENTRY_RELEASE", n.release), v = n.tracesSampleRate ?? 1, y = n.traces ?? !0, b = n.captureFailures ?? !1, x = o(b), S = t({ maxPerTrace: n.maxBreadcrumbs ?? 50 }), C, w = (e, t) => {
38
- if (C) try {
39
- i(C, e, t, S.take(t.traceId), x);
38
+ let _ = h.read("SENTRY_ENVIRONMENT", n.environment), v = h.read("SENTRY_RELEASE", n.release), y = n.tracesSampleRate ?? 1, b = n.traces ?? !0, x = n.captureFailures ?? !1, S = o(x), C = t({ maxPerTrace: n.maxBreadcrumbs ?? 50 }), w, T = (e, t) => {
39
+ if (w) try {
40
+ i(w, e, t, C.take(t.traceId), S);
40
41
  } catch {}
41
- }, T = (e, t) => e.pipe(l.tapCause((e) => l.sync(() => w(e, {
42
+ }, E = (e, t) => e.pipe(u.tapCause((e) => u.sync(() => T(e, {
42
43
  tag: t.tag,
43
44
  kind: t.kind,
44
45
  subject: t.subject,
45
46
  traceId: t.traceId,
46
47
  ...t.spanId === void 0 ? {} : { spanId: t.spanId }
47
- })))), E = [
48
+ })))), D = [
48
49
  "rpc:intercept:mutation",
49
50
  "rpc:intercept:query",
50
51
  "rpc:intercept:action",
51
52
  "rpc:intercept:workflow",
52
- `network:outbound:${u.host}`
53
- ], D, O;
54
- return f({
55
- name: h,
53
+ `network:outbound:${d.host}`
54
+ ], O, k;
55
+ return p({
56
+ name: g,
56
57
  description: "Deep Sentry integration — trace-correlated errors, breadcrumbs, and controlled performance traces.",
57
- permissions: E,
58
- declaredEnv: m.declared,
59
- interceptMutation: T,
60
- interceptQuery: T,
61
- interceptAction: T,
62
- interceptWorkflow: T,
58
+ permissions: D,
59
+ declaredEnv: h.declared,
60
+ interceptMutation: E,
61
+ interceptQuery: E,
62
+ interceptAction: E,
63
+ interceptWorkflow: E,
63
64
  contributeObservability: async (e) => {
64
65
  let t = {
65
66
  dsn: a,
66
- environment: g,
67
- release: _,
68
- tracesSampleRate: v,
69
- traces: y,
67
+ environment: _,
68
+ release: v,
69
+ tracesSampleRate: y,
70
+ traces: b,
70
71
  profiling: n.profiling,
71
72
  profilesSampleRate: n.profilesSampleRate,
72
73
  init: n.init
73
74
  }, r = await s(t, e.logger);
74
75
  if (r === void 0) return;
75
76
  let i = r.sdk;
76
- if (r.client, C = i, e.logger.info("sentry active", {
77
+ if (r.client, w = i, e.logger.info("sentry active", {
77
78
  ...c(r, t),
78
- captureFailures: typeof b == "function" ? "predicate" : b
79
- }), y) try {
80
- let { SentrySpanProcessor: e } = await import("@sentry/opentelemetry");
79
+ captureFailures: typeof x == "function" ? "predicate" : x
80
+ }), !b) return;
81
+ let o = a === void 0 ? void 0 : i.getOtlpTracesEndpoint(a);
82
+ if (o === void 0) e.logger.warn("sentry traces are on but the DSN yields no OTLP endpoint — no span export.");
83
+ else try {
81
84
  return {
82
- spanProcessors: [new e()],
85
+ spanProcessors: [await l(o, r.tracesSampleRate)],
83
86
  resourceAttributes: {
84
- ..._ ? { "service.version": _ } : {},
85
- ...g ? { "deployment.environment": g } : {}
87
+ ...v ? { "service.version": v } : {},
88
+ ..._ ? { "deployment.environment": _ } : {}
86
89
  }
87
90
  };
88
91
  } catch {
89
- e.logger.warn("sentry traces are on but @sentry/opentelemetry is not installed — no span export. Set `traces: false` to silence this, or install it (it is an optional dependency of @voltro/plugin-sentry).");
92
+ e.logger.warn("sentry traces are on but @opentelemetry/sdk-trace-base + @opentelemetry/exporter-trace-otlp-http are not installed — no span export. Set `traces: false` to silence this, or install them (they are optional dependencies of @voltro/plugin-sentry).");
90
93
  return;
91
94
  }
92
95
  },
93
- onActivate: () => l.sync(() => {
94
- D = d((e) => {
96
+ onActivate: () => u.sync(() => {
97
+ O = f((e) => {
95
98
  let t = e.fields.traceId;
96
- typeof t == "string" && t.length > 0 && S.add(t, e);
97
- }), O = p((e) => {
98
- if (C) try {
99
- r(C, e, e.traceId ? S.take(e.traceId) : []);
99
+ typeof t == "string" && t.length > 0 && C.add(t, e);
100
+ }), k = m((e) => {
101
+ if (w) try {
102
+ r(w, e, e.traceId ? C.take(e.traceId) : []);
100
103
  } catch {}
101
104
  });
102
105
  }),
103
- onDeactivate: () => l.promise(async () => {
104
- D?.(), D = void 0, O?.(), O = void 0;
106
+ onDeactivate: () => u.promise(async () => {
107
+ O?.(), O = void 0, k?.(), k = void 0;
105
108
  try {
106
109
  await (await import("@sentry/node")).close(2e3);
107
110
  } catch {}
108
111
  })
109
112
  });
110
113
  };
111
- //#endregion
112
- export { i as captureToSentry, a as causeToError, t as makeBreadcrumbRing, e as parseDsn, h as sentryPlugin, n as toBreadcrumb };
114
+ export { i as captureToSentry, a as causeToError, t as makeBreadcrumbRing, e as parseDsn, g as sentryPlugin, n as toBreadcrumb };
@@ -0,0 +1,21 @@
1
+ // src/otlpTraces.ts
2
+ var e = (e) => (t) => e >= 1 || e > 0 && Number.parseInt(t.slice(-8), 16) / 4294967296 < e, t = (t, n) => {
3
+ let r = e(n);
4
+ return {
5
+ onStart: (...[e, n]) => {
6
+ r(e.spanContext().traceId) && t.onStart(e, n);
7
+ },
8
+ onEnd: (e) => {
9
+ r(e.spanContext().traceId) && t.onEnd(e);
10
+ },
11
+ forceFlush: () => t.forceFlush(),
12
+ shutdown: () => t.shutdown()
13
+ };
14
+ }, n = async (e, n) => {
15
+ let { BatchSpanProcessor: r } = await import("@opentelemetry/sdk-trace-base"), { OTLPTraceExporter: i } = await import("@opentelemetry/exporter-trace-otlp-http");
16
+ return t(new r(new i({
17
+ url: e.url,
18
+ headers: { ...e.headers }
19
+ })), n);
20
+ };
21
+ export { e as keepTrace, t as sampledSpanProcessor, n as sentryOtlpSpanProcessor };
package/dist/server.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { parseDsn as e } from "./dsn.js";
2
- //#region src/server.ts
2
+ // src/server.ts
3
3
  var t = async (t, n) => {
4
4
  if (!e(t.dsn)) return;
5
5
  let r;
@@ -16,23 +16,22 @@ var t = async (t, n) => {
16
16
  } catch {
17
17
  n.warn("sentry profiling requested but @sentry/profiling-node is not installed");
18
18
  }
19
- let { integrations: a, ...o } = t.init ?? {};
20
- Array.isArray(a) && i.push(...a);
21
- let s = t.tracesSampleRate ?? 1, c = t.traces ?? !0, l = r.init({
22
- ...o,
19
+ let { integrations: a, tracesSampleRate: o, enableOpenTelemetrySetup: s, ...c } = t.init ?? {};
20
+ Array.isArray(a) && i.push(...a), i.push(r.openTelemetryIntegration());
21
+ let l = t.tracesSampleRate ?? 1, u = t.traces ?? !0, d = r.init({
22
+ ...c,
23
23
  dsn: t.dsn,
24
- skipOpenTelemetrySetup: !0,
25
- tracesSampleRate: s,
24
+ enableOpenTelemetrySetup: !1,
26
25
  ...t.environment ? { environment: t.environment } : {},
27
26
  ...t.release ? { release: t.release } : {},
28
27
  ...t.profiling ? { profilesSampleRate: t.profilesSampleRate ?? 1 } : {},
29
- ...i.length > 0 ? { integrations: i } : {}
28
+ integrations: i
30
29
  });
31
30
  return {
32
31
  sdk: r,
33
- client: l,
34
- tracesEnabled: c,
35
- tracesSampleRate: s
32
+ client: d,
33
+ tracesEnabled: u,
34
+ tracesSampleRate: l
36
35
  };
37
36
  }, n = (e, t) => ({
38
37
  environment: t.environment,
@@ -41,5 +40,4 @@ var t = async (t, n) => {
41
40
  profiling: !!t.profiling,
42
41
  ...e.tracesEnabled ? { tracesSampleRate: e.tracesSampleRate } : {}
43
42
  });
44
- //#endregion
45
43
  export { t as initSentryServer, n as sentryActiveFields };
package/dist/web.js CHANGED
@@ -2,7 +2,7 @@ import { resolveCaptureFailures as e } from "./capture.js";
2
2
  import { captureClientError as t, recordClientTraceSpan as n } from "./webTrace.js";
3
3
  import { reportClientError as r, subscribeClientErrors as i, subscribeClientTraces as a } from "@voltro/client";
4
4
  import { publicEnvSnapshot as o } from "@voltro/env/public";
5
- //#region src/web.ts
5
+ // src/web.ts
6
6
  var s = (e) => e.source.startsWith("rpc.") && typeof e.error?._tag == "string", c = (e) => {
7
7
  let t = o()[e];
8
8
  return typeof t == "string" && t !== "" ? t : void 0;
@@ -46,5 +46,4 @@ var s = (e) => e.source.startsWith("rpc.") && typeof e.error?._tag == "string",
46
46
  }, p = () => {
47
47
  l?.(), l = void 0, u?.(), u = void 0;
48
48
  };
49
- //#endregion
50
49
  export { t as captureClientError, p as closeSentryBrowser, d as initSentryBrowser, s as isDeclaredRpcFailure, n as recordClientTraceSpan, r as reportClientError };
package/dist/webTrace.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { reportableError as e } from "@voltro/protocol";
2
- //#region src/webTrace.ts
2
+ // src/webTrace.ts
3
3
  var t = (t, n) => {
4
4
  t.withScope((r) => {
5
5
  r.setTag("voltro.errorSource", n.source), n.pathname && r.setTag("route.pathname", n.pathname), n.componentStack && r.setContext("react", { componentStack: n.componentStack }), n.context && r.setContext("voltro", n.context), t.captureException(e(n.error));
@@ -23,5 +23,4 @@ var t = (t, n) => {
23
23
  }]
24
24
  }).end();
25
25
  };
26
- //#endregion
27
26
  export { t as captureClientError, n as recordClientTraceSpan };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@voltro/plugin-sentry",
3
- "version": "0.86.0",
3
+ "version": "0.88.0",
4
4
  "description": "Deep Sentry integration — error tracking correlated to distributed traces, breadcrumbs from the framework log sink, controlled browser performance spans, and server traces routed from the framework's OTel tracer via @sentry/node in OTel-consumer mode.",
5
5
  "keywords": [
6
6
  "voltro",
@@ -43,19 +43,20 @@
43
43
  "node": ">=24.0.0"
44
44
  },
45
45
  "dependencies": {
46
- "@voltro/client": "0.86.0",
47
- "@voltro/env": "0.86.0",
48
- "@voltro/logger": "0.86.0",
49
- "@voltro/protocol": "0.86.0"
46
+ "@voltro/client": "0.88.0",
47
+ "@voltro/env": "0.88.0",
48
+ "@voltro/logger": "0.88.0",
49
+ "@voltro/protocol": "0.88.0"
50
50
  },
51
51
  "optionalDependencies": {
52
- "@sentry/node": "^10.75.0",
53
- "@sentry/opentelemetry": "^10.75.0",
54
- "@sentry/profiling-node": "^10.75.0",
55
- "@sentry/react": "^10.75.0"
52
+ "@opentelemetry/exporter-trace-otlp-http": "^0.222.0",
53
+ "@opentelemetry/sdk-trace-base": "^2.12.0",
54
+ "@sentry/node": "^11.10.0",
55
+ "@sentry/profiling-node": "^11.10.0",
56
+ "@sentry/react": "^11.10.0"
56
57
  },
57
58
  "peerDependencies": {
58
- "effect": "4.0.1"
59
+ "effect": "4.1.0"
59
60
  },
60
61
  "publishConfig": {
61
62
  "access": "public"