@sentry/effect 10.53.1 → 10.55.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.
@@ -5,164 +5,124 @@ import * as Layer from 'effect/Layer';
5
5
  import * as Metric from 'effect/Metric';
6
6
  import * as Schedule from 'effect/Schedule';
7
7
 
8
- // Effect v3 `MetricState` implementations brand themselves with a `Symbol.for(...)` TypeId
9
- // rather than a string `_tag`. We use these globally-registered symbols to classify state
10
- // instances returned by `Metric.unsafeSnapshot()` without importing `effect/MetricState`
11
- // (the module does not exist in Effect v4).
12
- const V3_COUNTER_STATE_TYPE_ID = Symbol.for('effect/MetricState/Counter');
13
- const V3_GAUGE_STATE_TYPE_ID = Symbol.for('effect/MetricState/Gauge');
14
- const V3_HISTOGRAM_STATE_TYPE_ID = Symbol.for('effect/MetricState/Histogram');
15
- const V3_SUMMARY_STATE_TYPE_ID = Symbol.for('effect/MetricState/Summary');
16
- const V3_FREQUENCY_STATE_TYPE_ID = Symbol.for('effect/MetricState/Frequency');
17
-
8
+ const V3_COUNTER_STATE_TYPE_ID = /* @__PURE__ */ Symbol.for("effect/MetricState/Counter");
9
+ const V3_GAUGE_STATE_TYPE_ID = /* @__PURE__ */ Symbol.for("effect/MetricState/Gauge");
10
+ const V3_HISTOGRAM_STATE_TYPE_ID = /* @__PURE__ */ Symbol.for("effect/MetricState/Histogram");
11
+ const V3_SUMMARY_STATE_TYPE_ID = /* @__PURE__ */ Symbol.for("effect/MetricState/Summary");
12
+ const V3_FREQUENCY_STATE_TYPE_ID = /* @__PURE__ */ Symbol.for("effect/MetricState/Frequency");
18
13
  function labelsToAttributes(labels) {
19
14
  return labels.reduce((acc, label) => ({ ...acc, [label.key]: label.value }), {});
20
15
  }
21
-
22
16
  function getMetricIdV3(pair) {
23
- const tags = pair.metricKey.tags.map(t => `${t.key}=${t.value}`).join(',');
17
+ const tags = pair.metricKey.tags.map((t) => `${t.key}=${t.value}`).join(",");
24
18
  return `${pair.metricKey.name}:${tags}`;
25
19
  }
26
-
27
20
  function getMetricIdV4(snapshot) {
28
- const attrs = snapshot.attributes
29
- ? Object.entries(snapshot.attributes)
30
- .map(([k, v]) => `${k}=${v}`)
31
- .join(',')
32
- : '';
21
+ const attrs = snapshot.attributes ? Object.entries(snapshot.attributes).map(([k, v]) => `${k}=${v}`).join(",") : "";
33
22
  return `${snapshot.id}:${attrs}`;
34
23
  }
35
-
36
24
  function sendV3MetricToSentry(pair, previousCounterValues) {
37
25
  const { metricKey, metricState } = pair;
38
26
  const name = metricKey.name;
39
27
  const attributes = labelsToAttributes(metricKey.tags);
40
28
  const metricId = getMetricIdV3(pair);
41
-
42
- const state = metricState ;
43
-
44
- if (state[V3_COUNTER_STATE_TYPE_ID] !== undefined) {
29
+ const state = metricState;
30
+ if (state[V3_COUNTER_STATE_TYPE_ID] !== void 0) {
45
31
  const currentValue = Number(metricState.count);
46
32
  const previousValue = previousCounterValues.get(metricId) ?? 0;
47
33
  const delta = currentValue - previousValue;
48
-
49
34
  if (delta > 0) {
50
35
  metrics.count(name, delta, { attributes });
51
36
  }
52
-
53
37
  previousCounterValues.set(metricId, currentValue);
54
- } else if (state[V3_GAUGE_STATE_TYPE_ID] !== undefined) {
38
+ } else if (state[V3_GAUGE_STATE_TYPE_ID] !== void 0) {
55
39
  const value = Number(metricState.value);
56
40
  metrics.gauge(name, value, { attributes });
57
- } else if (state[V3_HISTOGRAM_STATE_TYPE_ID] !== undefined || state[V3_SUMMARY_STATE_TYPE_ID] !== undefined) {
41
+ } else if (state[V3_HISTOGRAM_STATE_TYPE_ID] !== void 0 || state[V3_SUMMARY_STATE_TYPE_ID] !== void 0) {
58
42
  metrics.gauge(`${name}.sum`, metricState.sum ?? 0, { attributes });
59
43
  metrics.gauge(`${name}.count`, Number(metricState.count ?? 0), { attributes });
60
44
  metrics.gauge(`${name}.min`, metricState.min ?? 0, { attributes });
61
45
  metrics.gauge(`${name}.max`, metricState.max ?? 0, { attributes });
62
- } else if (state[V3_FREQUENCY_STATE_TYPE_ID] !== undefined && metricState.occurrences) {
46
+ } else if (state[V3_FREQUENCY_STATE_TYPE_ID] !== void 0 && metricState.occurrences) {
63
47
  for (const [word, count] of metricState.occurrences) {
64
48
  metrics.count(name, count, {
65
- attributes: { ...attributes, word },
49
+ attributes: { ...attributes, word }
66
50
  });
67
51
  }
68
52
  }
69
53
  }
70
-
71
54
  function sendV4MetricToSentry(snapshot, previousCounterValues) {
72
55
  const name = snapshot.id;
73
56
  const attributes = snapshot.attributes ? { ...snapshot.attributes } : {};
74
57
  const metricId = getMetricIdV4(snapshot);
75
-
76
58
  switch (snapshot.type) {
77
- case 'Counter': {
59
+ case "Counter": {
78
60
  const currentValue = Number(snapshot.state.count);
79
61
  const previousValue = previousCounterValues.get(metricId) ?? 0;
80
62
  const delta = currentValue - previousValue;
81
-
82
63
  if (delta > 0) {
83
64
  metrics.count(name, delta, { attributes });
84
65
  }
85
-
86
66
  previousCounterValues.set(metricId, currentValue);
87
67
  break;
88
68
  }
89
- case 'Gauge': {
69
+ case "Gauge": {
90
70
  const value = Number(snapshot.state.value);
91
71
  metrics.gauge(name, value, { attributes });
92
72
  break;
93
73
  }
94
- case 'Histogram':
95
- case 'Summary': {
74
+ case "Histogram":
75
+ case "Summary": {
96
76
  metrics.gauge(`${name}.sum`, snapshot.state.sum ?? 0, { attributes });
97
77
  metrics.gauge(`${name}.count`, snapshot.state.count ?? 0, { attributes });
98
78
  metrics.gauge(`${name}.min`, snapshot.state.min ?? 0, { attributes });
99
79
  metrics.gauge(`${name}.max`, snapshot.state.max ?? 0, { attributes });
100
80
  break;
101
81
  }
102
- case 'Frequency': {
82
+ case "Frequency": {
103
83
  for (const [word, count] of snapshot.state.occurrences) {
104
84
  metrics.count(name, count, {
105
- attributes: { ...attributes, word },
85
+ attributes: { ...attributes, word }
106
86
  });
107
87
  }
108
88
  break;
109
89
  }
110
90
  }
111
91
  }
112
-
113
- // =============================================================================
114
- // Effect v3 snapshot function type (vendored - not exported from effect@3.x)
115
- // =============================================================================
116
-
117
- // Use bracket notation to avoid Webpack static analysis flagging missing exports
118
- // This is important for Effect v3 compatibility.
119
92
  const MetricModule = Metric;
120
- const snapshotUnsafe = MetricModule['snapshotUnsafe'] ;
121
- // @ts-expect-error - unsafeSnapshot is not exported from effect@3.x
122
- const unsafeSnapshot = MetricModule['unsafeSnapshot'] ;
123
-
93
+ const snapshotUnsafe = MetricModule["snapshotUnsafe"];
94
+ const unsafeSnapshot = MetricModule["unsafeSnapshot"];
124
95
  function flushMetricsToSentry(previousCounterValues) {
125
96
  if (snapshotUnsafe) {
126
- // Effect v4
127
97
  const snapshots = snapshotUnsafe(Context.empty());
128
98
  for (const snapshot of snapshots) {
129
99
  sendV4MetricToSentry(snapshot, previousCounterValues);
130
100
  }
131
101
  } else if (unsafeSnapshot) {
132
- // Effect v3
133
102
  const snapshots = unsafeSnapshot();
134
103
  for (const pair of snapshots) {
135
104
  sendV3MetricToSentry(pair, previousCounterValues);
136
105
  }
137
106
  }
138
107
  }
139
-
140
108
  function createMetricsReporterEffect(previousCounterValues) {
141
- const schedule = Schedule.spaced('10 seconds');
142
-
109
+ const schedule = Schedule.spaced("10 seconds");
143
110
  return Effect.repeat(
144
111
  Effect.sync(() => flushMetricsToSentry(previousCounterValues)),
145
- schedule,
112
+ schedule
146
113
  ).pipe(Effect.asVoid, Effect.interruptible);
147
114
  }
148
-
149
- /**
150
- * Effect Layer that periodically flushes metrics to Sentry.
151
- * The layer manages its own state for delta counter calculations,
152
- * which is automatically cleaned up when the layer is finalized.
153
- */
154
115
  const SentryEffectMetricsLayer = Layer.effectDiscard(
155
116
  Effect.gen(function* () {
156
- const previousCounterValues = new Map();
157
-
158
- yield* Effect.acquireRelease(Effect.void, () =>
159
- Effect.sync(() => {
117
+ const previousCounterValues = /* @__PURE__ */ new Map();
118
+ yield* Effect.acquireRelease(
119
+ Effect.void,
120
+ () => Effect.sync(() => {
160
121
  previousCounterValues.clear();
161
- }),
122
+ })
162
123
  );
163
-
164
124
  yield* Effect.forkScoped(createMetricsReporterEffect(previousCounterValues));
165
- }),
125
+ })
166
126
  );
167
127
 
168
128
  export { SentryEffectMetricsLayer };
@@ -1 +1 @@
1
- {"version":3,"file":"metrics.js","sources":["../../src/metrics.ts"],"sourcesContent":["import { metrics as sentryMetrics } from '@sentry/core';\nimport * as Context from 'effect/Context';\nimport * as Effect from 'effect/Effect';\nimport * as Layer from 'effect/Layer';\nimport * as Metric from 'effect/Metric';\nimport * as Schedule from 'effect/Schedule';\n\ntype MetricAttributes = Record<string, string>;\n\n// =============================================================================\n// Effect v3 Types (vendored - not exported from effect@3.x)\n// =============================================================================\n\ninterface V3MetricLabel {\n key: string;\n value: string;\n}\n\ninterface V3MetricPair {\n metricKey: {\n name: string;\n tags: ReadonlyArray<V3MetricLabel>;\n keyType: { _tag: string };\n };\n metricState: {\n count?: number | bigint;\n value?: number;\n sum?: number;\n min?: number;\n max?: number;\n occurrences?: Map<string, number>;\n };\n}\n\n// Effect v3 `MetricState` implementations brand themselves with a `Symbol.for(...)` TypeId\n// rather than a string `_tag`. We use these globally-registered symbols to classify state\n// instances returned by `Metric.unsafeSnapshot()` without importing `effect/MetricState`\n// (the module does not exist in Effect v4).\nconst V3_COUNTER_STATE_TYPE_ID = Symbol.for('effect/MetricState/Counter');\nconst V3_GAUGE_STATE_TYPE_ID = Symbol.for('effect/MetricState/Gauge');\nconst V3_HISTOGRAM_STATE_TYPE_ID = Symbol.for('effect/MetricState/Histogram');\nconst V3_SUMMARY_STATE_TYPE_ID = Symbol.for('effect/MetricState/Summary');\nconst V3_FREQUENCY_STATE_TYPE_ID = Symbol.for('effect/MetricState/Frequency');\n\nfunction labelsToAttributes(labels: ReadonlyArray<V3MetricLabel>): MetricAttributes {\n return labels.reduce((acc, label) => ({ ...acc, [label.key]: label.value }), {});\n}\n\nfunction getMetricIdV3(pair: V3MetricPair): string {\n const tags = pair.metricKey.tags.map(t => `${t.key}=${t.value}`).join(',');\n return `${pair.metricKey.name}:${tags}`;\n}\n\nfunction getMetricIdV4(snapshot: Metric.Metric.Snapshot): string {\n const attrs = snapshot.attributes\n ? Object.entries(snapshot.attributes)\n .map(([k, v]) => `${k}=${v}`)\n .join(',')\n : '';\n return `${snapshot.id}:${attrs}`;\n}\n\nfunction sendV3MetricToSentry(pair: V3MetricPair, previousCounterValues: Map<string, number>): void {\n const { metricKey, metricState } = pair;\n const name = metricKey.name;\n const attributes = labelsToAttributes(metricKey.tags);\n const metricId = getMetricIdV3(pair);\n\n const state = metricState as unknown as Record<symbol, unknown>;\n\n if (state[V3_COUNTER_STATE_TYPE_ID] !== undefined) {\n const currentValue = Number(metricState.count);\n const previousValue = previousCounterValues.get(metricId) ?? 0;\n const delta = currentValue - previousValue;\n\n if (delta > 0) {\n sentryMetrics.count(name, delta, { attributes });\n }\n\n previousCounterValues.set(metricId, currentValue);\n } else if (state[V3_GAUGE_STATE_TYPE_ID] !== undefined) {\n const value = Number(metricState.value);\n sentryMetrics.gauge(name, value, { attributes });\n } else if (state[V3_HISTOGRAM_STATE_TYPE_ID] !== undefined || state[V3_SUMMARY_STATE_TYPE_ID] !== undefined) {\n sentryMetrics.gauge(`${name}.sum`, metricState.sum ?? 0, { attributes });\n sentryMetrics.gauge(`${name}.count`, Number(metricState.count ?? 0), { attributes });\n sentryMetrics.gauge(`${name}.min`, metricState.min ?? 0, { attributes });\n sentryMetrics.gauge(`${name}.max`, metricState.max ?? 0, { attributes });\n } else if (state[V3_FREQUENCY_STATE_TYPE_ID] !== undefined && metricState.occurrences) {\n for (const [word, count] of metricState.occurrences) {\n sentryMetrics.count(name, count, {\n attributes: { ...attributes, word },\n });\n }\n }\n}\n\nfunction sendV4MetricToSentry(snapshot: Metric.Metric.Snapshot, previousCounterValues: Map<string, number>): void {\n const name = snapshot.id;\n const attributes: MetricAttributes = snapshot.attributes ? { ...snapshot.attributes } : {};\n const metricId = getMetricIdV4(snapshot);\n\n switch (snapshot.type) {\n case 'Counter': {\n const currentValue = Number(snapshot.state.count);\n const previousValue = previousCounterValues.get(metricId) ?? 0;\n const delta = currentValue - previousValue;\n\n if (delta > 0) {\n sentryMetrics.count(name, delta, { attributes });\n }\n\n previousCounterValues.set(metricId, currentValue);\n break;\n }\n case 'Gauge': {\n const value = Number(snapshot.state.value);\n sentryMetrics.gauge(name, value, { attributes });\n break;\n }\n case 'Histogram':\n case 'Summary': {\n sentryMetrics.gauge(`${name}.sum`, snapshot.state.sum ?? 0, { attributes });\n sentryMetrics.gauge(`${name}.count`, snapshot.state.count ?? 0, { attributes });\n sentryMetrics.gauge(`${name}.min`, snapshot.state.min ?? 0, { attributes });\n sentryMetrics.gauge(`${name}.max`, snapshot.state.max ?? 0, { attributes });\n break;\n }\n case 'Frequency': {\n for (const [word, count] of snapshot.state.occurrences) {\n sentryMetrics.count(name, count, {\n attributes: { ...attributes, word },\n });\n }\n break;\n }\n }\n}\n\n// =============================================================================\n// Effect v3 snapshot function type (vendored - not exported from effect@3.x)\n// =============================================================================\n\ntype V3UnsafeSnapshotFn = () => ReadonlyArray<V3MetricPair>;\n\n// Use bracket notation to avoid Webpack static analysis flagging missing exports\n// This is important for Effect v3 compatibility.\nconst MetricModule = Metric;\nconst snapshotUnsafe = MetricModule['snapshotUnsafe'] as typeof Metric.snapshotUnsafe | undefined;\n// @ts-expect-error - unsafeSnapshot is not exported from effect@3.x\nconst unsafeSnapshot = MetricModule['unsafeSnapshot'] as V3UnsafeSnapshotFn | undefined;\n\nfunction flushMetricsToSentry(previousCounterValues: Map<string, number>): void {\n if (snapshotUnsafe) {\n // Effect v4\n const snapshots = snapshotUnsafe(Context.empty());\n for (const snapshot of snapshots) {\n sendV4MetricToSentry(snapshot, previousCounterValues);\n }\n } else if (unsafeSnapshot) {\n // Effect v3\n const snapshots = unsafeSnapshot();\n for (const pair of snapshots) {\n sendV3MetricToSentry(pair, previousCounterValues);\n }\n }\n}\n\nfunction createMetricsReporterEffect(previousCounterValues: Map<string, number>): Effect.Effect<void, never, never> {\n const schedule = Schedule.spaced('10 seconds');\n\n return Effect.repeat(\n Effect.sync(() => flushMetricsToSentry(previousCounterValues)),\n schedule,\n ).pipe(Effect.asVoid, Effect.interruptible);\n}\n\n/**\n * Effect Layer that periodically flushes metrics to Sentry.\n * The layer manages its own state for delta counter calculations,\n * which is automatically cleaned up when the layer is finalized.\n */\nexport const SentryEffectMetricsLayer: Layer.Layer<never, never, never> = Layer.effectDiscard(\n Effect.gen(function* () {\n const previousCounterValues = new Map<string, number>();\n\n yield* Effect.acquireRelease(Effect.void, () =>\n Effect.sync(() => {\n previousCounterValues.clear();\n }),\n );\n\n yield* Effect.forkScoped(createMetricsReporterEffect(previousCounterValues));\n }),\n);\n"],"names":["sentryMetrics"],"mappings":"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"}
1
+ {"version":3,"file":"metrics.js","sources":["../../src/metrics.ts"],"sourcesContent":["import { metrics as sentryMetrics } from '@sentry/core';\nimport * as Context from 'effect/Context';\nimport * as Effect from 'effect/Effect';\nimport * as Layer from 'effect/Layer';\nimport * as Metric from 'effect/Metric';\nimport * as Schedule from 'effect/Schedule';\n\ntype MetricAttributes = Record<string, string>;\n\n// =============================================================================\n// Effect v3 Types (vendored - not exported from effect@3.x)\n// =============================================================================\n\ninterface V3MetricLabel {\n key: string;\n value: string;\n}\n\ninterface V3MetricPair {\n metricKey: {\n name: string;\n tags: ReadonlyArray<V3MetricLabel>;\n keyType: { _tag: string };\n };\n metricState: {\n count?: number | bigint;\n value?: number;\n sum?: number;\n min?: number;\n max?: number;\n occurrences?: Map<string, number>;\n };\n}\n\n// Effect v3 `MetricState` implementations brand themselves with a `Symbol.for(...)` TypeId\n// rather than a string `_tag`. We use these globally-registered symbols to classify state\n// instances returned by `Metric.unsafeSnapshot()` without importing `effect/MetricState`\n// (the module does not exist in Effect v4).\nconst V3_COUNTER_STATE_TYPE_ID = Symbol.for('effect/MetricState/Counter');\nconst V3_GAUGE_STATE_TYPE_ID = Symbol.for('effect/MetricState/Gauge');\nconst V3_HISTOGRAM_STATE_TYPE_ID = Symbol.for('effect/MetricState/Histogram');\nconst V3_SUMMARY_STATE_TYPE_ID = Symbol.for('effect/MetricState/Summary');\nconst V3_FREQUENCY_STATE_TYPE_ID = Symbol.for('effect/MetricState/Frequency');\n\nfunction labelsToAttributes(labels: ReadonlyArray<V3MetricLabel>): MetricAttributes {\n return labels.reduce((acc, label) => ({ ...acc, [label.key]: label.value }), {});\n}\n\nfunction getMetricIdV3(pair: V3MetricPair): string {\n const tags = pair.metricKey.tags.map(t => `${t.key}=${t.value}`).join(',');\n return `${pair.metricKey.name}:${tags}`;\n}\n\nfunction getMetricIdV4(snapshot: Metric.Metric.Snapshot): string {\n const attrs = snapshot.attributes\n ? Object.entries(snapshot.attributes)\n .map(([k, v]) => `${k}=${v}`)\n .join(',')\n : '';\n return `${snapshot.id}:${attrs}`;\n}\n\nfunction sendV3MetricToSentry(pair: V3MetricPair, previousCounterValues: Map<string, number>): void {\n const { metricKey, metricState } = pair;\n const name = metricKey.name;\n const attributes = labelsToAttributes(metricKey.tags);\n const metricId = getMetricIdV3(pair);\n\n const state = metricState as unknown as Record<symbol, unknown>;\n\n if (state[V3_COUNTER_STATE_TYPE_ID] !== undefined) {\n const currentValue = Number(metricState.count);\n const previousValue = previousCounterValues.get(metricId) ?? 0;\n const delta = currentValue - previousValue;\n\n if (delta > 0) {\n sentryMetrics.count(name, delta, { attributes });\n }\n\n previousCounterValues.set(metricId, currentValue);\n } else if (state[V3_GAUGE_STATE_TYPE_ID] !== undefined) {\n const value = Number(metricState.value);\n sentryMetrics.gauge(name, value, { attributes });\n } else if (state[V3_HISTOGRAM_STATE_TYPE_ID] !== undefined || state[V3_SUMMARY_STATE_TYPE_ID] !== undefined) {\n sentryMetrics.gauge(`${name}.sum`, metricState.sum ?? 0, { attributes });\n sentryMetrics.gauge(`${name}.count`, Number(metricState.count ?? 0), { attributes });\n sentryMetrics.gauge(`${name}.min`, metricState.min ?? 0, { attributes });\n sentryMetrics.gauge(`${name}.max`, metricState.max ?? 0, { attributes });\n } else if (state[V3_FREQUENCY_STATE_TYPE_ID] !== undefined && metricState.occurrences) {\n for (const [word, count] of metricState.occurrences) {\n sentryMetrics.count(name, count, {\n attributes: { ...attributes, word },\n });\n }\n }\n}\n\nfunction sendV4MetricToSentry(snapshot: Metric.Metric.Snapshot, previousCounterValues: Map<string, number>): void {\n const name = snapshot.id;\n const attributes: MetricAttributes = snapshot.attributes ? { ...snapshot.attributes } : {};\n const metricId = getMetricIdV4(snapshot);\n\n switch (snapshot.type) {\n case 'Counter': {\n const currentValue = Number(snapshot.state.count);\n const previousValue = previousCounterValues.get(metricId) ?? 0;\n const delta = currentValue - previousValue;\n\n if (delta > 0) {\n sentryMetrics.count(name, delta, { attributes });\n }\n\n previousCounterValues.set(metricId, currentValue);\n break;\n }\n case 'Gauge': {\n const value = Number(snapshot.state.value);\n sentryMetrics.gauge(name, value, { attributes });\n break;\n }\n case 'Histogram':\n case 'Summary': {\n sentryMetrics.gauge(`${name}.sum`, snapshot.state.sum ?? 0, { attributes });\n sentryMetrics.gauge(`${name}.count`, snapshot.state.count ?? 0, { attributes });\n sentryMetrics.gauge(`${name}.min`, snapshot.state.min ?? 0, { attributes });\n sentryMetrics.gauge(`${name}.max`, snapshot.state.max ?? 0, { attributes });\n break;\n }\n case 'Frequency': {\n for (const [word, count] of snapshot.state.occurrences) {\n sentryMetrics.count(name, count, {\n attributes: { ...attributes, word },\n });\n }\n break;\n }\n }\n}\n\n// =============================================================================\n// Effect v3 snapshot function type (vendored - not exported from effect@3.x)\n// =============================================================================\n\ntype V3UnsafeSnapshotFn = () => ReadonlyArray<V3MetricPair>;\n\n// Use bracket notation to avoid Webpack static analysis flagging missing exports\n// This is important for Effect v3 compatibility.\nconst MetricModule = Metric;\nconst snapshotUnsafe = MetricModule['snapshotUnsafe'] as typeof Metric.snapshotUnsafe | undefined;\n// @ts-expect-error - unsafeSnapshot is not exported from effect@3.x\nconst unsafeSnapshot = MetricModule['unsafeSnapshot'] as V3UnsafeSnapshotFn | undefined;\n\nfunction flushMetricsToSentry(previousCounterValues: Map<string, number>): void {\n if (snapshotUnsafe) {\n // Effect v4\n const snapshots = snapshotUnsafe(Context.empty());\n for (const snapshot of snapshots) {\n sendV4MetricToSentry(snapshot, previousCounterValues);\n }\n } else if (unsafeSnapshot) {\n // Effect v3\n const snapshots = unsafeSnapshot();\n for (const pair of snapshots) {\n sendV3MetricToSentry(pair, previousCounterValues);\n }\n }\n}\n\nfunction createMetricsReporterEffect(previousCounterValues: Map<string, number>): Effect.Effect<void, never, never> {\n const schedule = Schedule.spaced('10 seconds');\n\n return Effect.repeat(\n Effect.sync(() => flushMetricsToSentry(previousCounterValues)),\n schedule,\n ).pipe(Effect.asVoid, Effect.interruptible);\n}\n\n/**\n * Effect Layer that periodically flushes metrics to Sentry.\n * The layer manages its own state for delta counter calculations,\n * which is automatically cleaned up when the layer is finalized.\n */\nexport const SentryEffectMetricsLayer: Layer.Layer<never, never, never> = Layer.effectDiscard(\n Effect.gen(function* () {\n const previousCounterValues = new Map<string, number>();\n\n yield* Effect.acquireRelease(Effect.void, () =>\n Effect.sync(() => {\n previousCounterValues.clear();\n }),\n );\n\n yield* Effect.forkScoped(createMetricsReporterEffect(previousCounterValues));\n }),\n);\n"],"names":["sentryMetrics"],"mappings":"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"}
@@ -1 +1 @@
1
- {"type":"module","version":"10.53.1","sideEffects":false}
1
+ {"type":"module","version":"10.55.0","sideEffects":false}
@@ -1,35 +1,6 @@
1
1
  import { suspend, empty } from 'effect/Layer';
2
2
  import { init } from './sdk.js';
3
3
 
4
- /**
5
- * Options for the Sentry Effect server layer.
6
- */
7
-
8
- /**
9
- * Creates an Effect Layer that initializes Sentry for Node.js servers.
10
- *
11
- * To enable Effect tracing, logs, or metrics, compose with the respective layers:
12
- * - `Layer.setTracer(Sentry.SentryEffectTracer)` for tracing
13
- * - `Logger.replace(Logger.defaultLogger, Sentry.SentryEffectLogger)` for logs
14
- * - `Sentry.SentryEffectMetricsLayer` for metrics
15
- *
16
- * @example
17
- * ```typescript
18
- * import * as Sentry from '@sentry/effect/server';
19
- * import { NodeRuntime } from '@effect/platform-node';
20
- * import { Layer, Logger } from 'effect';
21
- * import { HttpLive } from './Http.js';
22
- *
23
- * const SentryLive = Layer.mergeAll(
24
- * Sentry.effectLayer({ dsn: '__DSN__' }),
25
- * Layer.setTracer(Sentry.SentryEffectTracer),
26
- * Logger.replace(Logger.defaultLogger, Sentry.SentryEffectLogger),
27
- * );
28
- *
29
- * const MainLive = HttpLive.pipe(Layer.provide(SentryLive));
30
- * MainLive.pipe(Layer.launch, NodeRuntime.runMain);
31
- * ```
32
- */
33
4
  function effectLayer(options) {
34
5
  return suspend(() => {
35
6
  init(options);
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../../src/server/index.ts"],"sourcesContent":["import type { NodeOptions } from '@sentry/node-core/light';\nimport type * as EffectLayer from 'effect/Layer';\nimport { empty as emptyLayer, suspend as suspendLayer } from 'effect/Layer';\nimport { init } from './sdk';\n\nexport { init } from './sdk';\n\n/**\n * Options for the Sentry Effect server layer.\n */\nexport type EffectServerLayerOptions = NodeOptions;\n\n/**\n * Creates an Effect Layer that initializes Sentry for Node.js servers.\n *\n * To enable Effect tracing, logs, or metrics, compose with the respective layers:\n * - `Layer.setTracer(Sentry.SentryEffectTracer)` for tracing\n * - `Logger.replace(Logger.defaultLogger, Sentry.SentryEffectLogger)` for logs\n * - `Sentry.SentryEffectMetricsLayer` for metrics\n *\n * @example\n * ```typescript\n * import * as Sentry from '@sentry/effect/server';\n * import { NodeRuntime } from '@effect/platform-node';\n * import { Layer, Logger } from 'effect';\n * import { HttpLive } from './Http.js';\n *\n * const SentryLive = Layer.mergeAll(\n * Sentry.effectLayer({ dsn: '__DSN__' }),\n * Layer.setTracer(Sentry.SentryEffectTracer),\n * Logger.replace(Logger.defaultLogger, Sentry.SentryEffectLogger),\n * );\n *\n * const MainLive = HttpLive.pipe(Layer.provide(SentryLive));\n * MainLive.pipe(Layer.launch, NodeRuntime.runMain);\n * ```\n */\nexport function effectLayer(options: EffectServerLayerOptions): EffectLayer.Layer<never, never, never> {\n return suspendLayer(() => {\n init(options);\n return emptyLayer;\n });\n}\n"],"names":["suspendLayer","emptyLayer"],"mappings":";;;AAOA;AACA;AACA;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,WAAW,CAAC,OAAO,EAAoE;AACvG,EAAE,OAAOA,OAAY,CAAC,MAAM;AAC5B,IAAI,IAAI,CAAC,OAAO,CAAC;AACjB,IAAI,OAAOC,KAAU;AACrB,EAAE,CAAC,CAAC;AACJ;;;;"}
1
+ {"version":3,"file":"index.js","sources":["../../../src/server/index.ts"],"sourcesContent":["import type { NodeOptions } from '@sentry/node-core/light';\nimport type * as EffectLayer from 'effect/Layer';\nimport { empty as emptyLayer, suspend as suspendLayer } from 'effect/Layer';\nimport { init } from './sdk';\n\nexport { init } from './sdk';\n\n/**\n * Options for the Sentry Effect server layer.\n */\nexport type EffectServerLayerOptions = NodeOptions;\n\n/**\n * Creates an Effect Layer that initializes Sentry for Node.js servers.\n *\n * To enable Effect tracing, logs, or metrics, compose with the respective layers:\n * - `Layer.setTracer(Sentry.SentryEffectTracer)` for tracing\n * - `Logger.replace(Logger.defaultLogger, Sentry.SentryEffectLogger)` for logs\n * - `Sentry.SentryEffectMetricsLayer` for metrics\n *\n * @example\n * ```typescript\n * import * as Sentry from '@sentry/effect/server';\n * import { NodeRuntime } from '@effect/platform-node';\n * import { Layer, Logger } from 'effect';\n * import { HttpLive } from './Http.js';\n *\n * const SentryLive = Layer.mergeAll(\n * Sentry.effectLayer({ dsn: '__DSN__' }),\n * Layer.setTracer(Sentry.SentryEffectTracer),\n * Logger.replace(Logger.defaultLogger, Sentry.SentryEffectLogger),\n * );\n *\n * const MainLive = HttpLive.pipe(Layer.provide(SentryLive));\n * MainLive.pipe(Layer.launch, NodeRuntime.runMain);\n * ```\n */\nexport function effectLayer(options: EffectServerLayerOptions): EffectLayer.Layer<never, never, never> {\n return suspendLayer(() => {\n init(options);\n return emptyLayer;\n });\n}\n"],"names":["suspendLayer","emptyLayer"],"mappings":";;;AAqCO,SAAS,YAAY,OAAA,EAA2E;AACrG,EAAA,OAAOA,QAAa,MAAM;AACxB,IAAA,IAAA,CAAK,OAAO,CAAA;AACZ,IAAA,OAAOC,KAAA;AAAA,EACT,CAAC,CAAA;AACH;;;;"}
@@ -1,19 +1,11 @@
1
1
  import { applySdkMetadata } from '@sentry/core';
2
2
  import { init as init$1 } from '@sentry/node-core/light';
3
3
 
4
- /**
5
- * Initializes the Sentry Effect SDK for Node.js servers.
6
- *
7
- * @param options - Configuration options for the SDK
8
- * @returns The initialized Sentry client, or undefined if initialization failed
9
- */
10
4
  function init(options) {
11
5
  const opts = {
12
- ...options,
6
+ ...options
13
7
  };
14
-
15
- applySdkMetadata(opts, 'effect', ['effect', 'node-light']);
16
-
8
+ applySdkMetadata(opts, "effect", ["effect", "node-light"]);
17
9
  return init$1(opts);
18
10
  }
19
11
 
@@ -1 +1 @@
1
- {"version":3,"file":"sdk.js","sources":["../../../src/server/sdk.ts"],"sourcesContent":["import type { Client } from '@sentry/core';\nimport { applySdkMetadata } from '@sentry/core';\nimport type { NodeOptions } from '@sentry/node-core/light';\nimport { init as initNode } from '@sentry/node-core/light';\n\n/**\n * Initializes the Sentry Effect SDK for Node.js servers.\n *\n * @param options - Configuration options for the SDK\n * @returns The initialized Sentry client, or undefined if initialization failed\n */\nexport function init(options: NodeOptions): Client | undefined {\n const opts = {\n ...options,\n };\n\n applySdkMetadata(opts, 'effect', ['effect', 'node-light']);\n\n return initNode(opts);\n}\n"],"names":["initNode"],"mappings":";;;AAKA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,IAAI,CAAC,OAAO,EAAmC;AAC/D,EAAE,MAAM,OAAO;AACf,IAAI,GAAG,OAAO;AACd,GAAG;;AAEH,EAAE,gBAAgB,CAAC,IAAI,EAAE,QAAQ,EAAE,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC;;AAE5D,EAAE,OAAOA,MAAQ,CAAC,IAAI,CAAC;AACvB;;;;"}
1
+ {"version":3,"file":"sdk.js","sources":["../../../src/server/sdk.ts"],"sourcesContent":["import type { Client } from '@sentry/core';\nimport { applySdkMetadata } from '@sentry/core';\nimport type { NodeOptions } from '@sentry/node-core/light';\nimport { init as initNode } from '@sentry/node-core/light';\n\n/**\n * Initializes the Sentry Effect SDK for Node.js servers.\n *\n * @param options - Configuration options for the SDK\n * @returns The initialized Sentry client, or undefined if initialization failed\n */\nexport function init(options: NodeOptions): Client | undefined {\n const opts = {\n ...options,\n };\n\n applySdkMetadata(opts, 'effect', ['effect', 'node-light']);\n\n return initNode(opts);\n}\n"],"names":["initNode"],"mappings":";;;AAWO,SAAS,KAAK,OAAA,EAA0C;AAC7D,EAAA,MAAM,IAAA,GAAO;AAAA,IACX,GAAG;AAAA,GACL;AAEA,EAAA,gBAAA,CAAiB,IAAA,EAAM,QAAA,EAAU,CAAC,QAAA,EAAU,YAAY,CAAC,CAAA;AAEzD,EAAA,OAAOA,OAAS,IAAI,CAAA;AACtB;;;;"}
@@ -4,170 +4,121 @@ import * as Option from 'effect/Option';
4
4
  import * as EffectTracer from 'effect/Tracer';
5
5
 
6
6
  function deriveOrigin(name) {
7
- if (name.startsWith('http.server') || name.startsWith('http.client')) {
8
- return 'auto.http.effect';
7
+ if (name.startsWith("http.server") || name.startsWith("http.client")) {
8
+ return "auto.http.effect";
9
9
  }
10
-
11
- return 'auto.function.effect';
10
+ return "auto.function.effect";
12
11
  }
13
-
14
- const SENTRY_SPAN_SYMBOL = Symbol.for('@sentry/effect.SentrySpan');
15
-
12
+ const SENTRY_SPAN_SYMBOL = /* @__PURE__ */ Symbol.for("@sentry/effect.SentrySpan");
16
13
  function nanosToHrTime(nanos) {
17
- const seconds = Number(nanos / BigInt(1000000000));
18
- const remainingNanos = Number(nanos % BigInt(1000000000));
14
+ const seconds = Number(nanos / BigInt(1e9));
15
+ const remainingNanos = Number(nanos % BigInt(1e9));
19
16
  return [seconds, remainingNanos];
20
17
  }
21
-
22
18
  function isSentrySpan(span) {
23
19
  return SENTRY_SPAN_SYMBOL in span;
24
20
  }
25
-
26
21
  function getErrorMessage(exit) {
27
22
  if (!Exit.isFailure(exit)) {
28
- return undefined;
23
+ return void 0;
29
24
  }
30
-
31
- const cause = exit.cause ;
32
-
33
- // Effect v4: cause.reasons is an array of Reason objects
34
- if (
35
- cause &&
36
- typeof cause === 'object' &&
37
- 'reasons' in cause &&
38
- Array.isArray((cause ).reasons)
39
- ) {
40
- const reasons = (cause ).reasons;
25
+ const cause = exit.cause;
26
+ if (cause && typeof cause === "object" && "reasons" in cause && Array.isArray(cause.reasons)) {
27
+ const reasons = cause.reasons;
41
28
  for (const reason of reasons) {
42
- if (reason._tag === 'Fail' && reason.error !== undefined) {
29
+ if (reason._tag === "Fail" && reason.error !== void 0) {
43
30
  return String(reason.error);
44
31
  }
45
- if (reason._tag === 'Die' && reason.defect !== undefined) {
32
+ if (reason._tag === "Die" && reason.defect !== void 0) {
46
33
  return String(reason.defect);
47
34
  }
48
35
  }
49
- return 'internal_error';
36
+ return "internal_error";
50
37
  }
51
-
52
- // Effect v3: cause has _tag directly
53
- if (cause && typeof cause === 'object' && '_tag' in cause) {
54
- const v3Cause = cause ;
55
- if (v3Cause._tag === 'Fail') {
38
+ if (cause && typeof cause === "object" && "_tag" in cause) {
39
+ const v3Cause = cause;
40
+ if (v3Cause._tag === "Fail") {
56
41
  return String(v3Cause.error);
57
42
  }
58
- if (v3Cause._tag === 'Die') {
43
+ if (v3Cause._tag === "Die") {
59
44
  return String(v3Cause.defect);
60
45
  }
61
46
  }
62
-
63
- return 'internal_error';
47
+ return "internal_error";
64
48
  }
65
-
66
- class SentrySpanWrapper {
67
-
68
- constructor(
69
- name,
70
- parent,
71
- context,
72
- links,
73
- startTime,
74
- kind,
75
- existingSpan,
76
- ) {this.name = name;this.context = context;this.kind = kind;
77
- this[SENTRY_SPAN_SYMBOL] = true ;
78
- this._tag = 'Span' ;
79
- this.attributes = new Map();
49
+ class SentrySpanWrapper {
50
+ constructor(name, parent, context, links, startTime, kind, existingSpan) {
51
+ this.name = name;
52
+ this.context = context;
53
+ this.kind = kind;
54
+ this[SENTRY_SPAN_SYMBOL] = true;
55
+ this._tag = "Span";
56
+ this.attributes = /* @__PURE__ */ new Map();
80
57
  this.parent = parent;
81
58
  this.links = [...links];
82
59
  this.sentrySpan = existingSpan;
83
60
  this.annotations = context;
84
-
85
61
  const spanContext = this.sentrySpan.spanContext();
86
62
  this.spanId = spanContext.spanId;
87
63
  this.traceId = spanContext.traceId;
88
64
  this.sampled = this.sentrySpan.isRecording();
89
65
  this.status = {
90
- _tag: 'Started',
91
- startTime,
66
+ _tag: "Started",
67
+ startTime
92
68
  };
93
69
  }
94
-
95
- attribute(key, value) {
70
+ attribute(key, value) {
96
71
  if (!this.sentrySpan.isRecording()) {
97
72
  return;
98
73
  }
99
-
100
- this.sentrySpan.setAttribute(key, value );
74
+ this.sentrySpan.setAttribute(key, value);
101
75
  this.attributes.set(key, value);
102
76
  }
103
-
104
- addLinks(links) {
77
+ addLinks(links) {
105
78
  this.links.push(...links);
106
79
  }
107
-
108
- end(endTime, exit) {
80
+ end(endTime, exit) {
109
81
  this.status = {
110
- _tag: 'Ended',
82
+ _tag: "Ended",
111
83
  endTime,
112
84
  exit,
113
- startTime: this.status.startTime,
85
+ startTime: this.status.startTime
114
86
  };
115
-
116
87
  if (!this.sentrySpan.isRecording()) {
117
88
  return;
118
89
  }
119
-
120
90
  if (Exit.isFailure(exit)) {
121
- const message = getErrorMessage(exit) ?? 'internal_error';
91
+ const message = getErrorMessage(exit) ?? "internal_error";
122
92
  this.sentrySpan.setStatus({ code: 2, message });
123
93
  } else {
124
94
  this.sentrySpan.setStatus({ code: 1 });
125
95
  }
126
-
127
96
  this.sentrySpan.end(nanosToHrTime(endTime));
128
97
  }
129
-
130
- event(name, startTime, attributes) {
98
+ event(name, startTime, attributes) {
131
99
  if (!this.sentrySpan.isRecording()) {
132
100
  return;
133
101
  }
134
-
135
- this.sentrySpan.addEvent(name, attributes , nanosToHrTime(startTime));
102
+ this.sentrySpan.addEvent(name, attributes, nanosToHrTime(startTime));
136
103
  }
137
104
  }
138
-
139
- function createSentrySpan(
140
- name,
141
- parent,
142
- context,
143
- links,
144
- startTime,
145
- kind,
146
- ) {
147
- const parentSentrySpan =
148
- Option.isSome(parent) && isSentrySpan(parent.value) ? parent.value.sentrySpan : (getActiveSpan() ?? null);
149
-
105
+ function createSentrySpan(name, parent, context, links, startTime, kind) {
106
+ const parentSentrySpan = Option.isSome(parent) && isSentrySpan(parent.value) ? parent.value.sentrySpan : getActiveSpan() ?? null;
150
107
  const newSpan = startInactiveSpan({
151
108
  name,
152
109
  startTime: nanosToHrTime(startTime),
153
110
  attributes: {
154
- [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: deriveOrigin(name),
111
+ [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: deriveOrigin(name)
155
112
  },
156
- ...(parentSentrySpan ? { parentSpan: parentSentrySpan } : {}),
113
+ ...parentSentrySpan ? { parentSpan: parentSentrySpan } : {}
157
114
  });
158
-
159
115
  return new SentrySpanWrapper(name, parent, context, links, startTime, kind, newSpan);
160
116
  }
161
-
162
- // Check if we're running Effect v4 by checking the Exit/Cause structure
163
- // In v4, causes have a 'reasons' array
164
- // In v3, causes have '_tag' directly on the cause object
165
117
  const isEffectV4 = (() => {
166
118
  try {
167
- const testExit = Exit.fail('test') ;
119
+ const testExit = Exit.fail("test");
168
120
  const cause = testExit.cause;
169
- // v4 causes have 'reasons' array, v3 causes have '_tag' directly
170
- if (cause && typeof cause === 'object' && 'reasons' in cause) {
121
+ if (cause && typeof cause === "object" && "reasons" in cause) {
171
122
  return true;
172
123
  }
173
124
  return false;
@@ -175,33 +126,22 @@ const isEffectV4 = (() => {
175
126
  return false;
176
127
  }
177
128
  })();
178
-
179
129
  const makeSentryTracerV3 = () => {
180
- // Effect v3 API: span(name, parent, context, links, startTime, kind)
181
130
  return EffectTracer.make({
182
- span(
183
- name,
184
- parent,
185
- context,
186
- links,
187
- startTime,
188
- kind,
189
- ) {
131
+ span(name, parent, context, links, startTime, kind) {
190
132
  return createSentrySpan(name, parent, context, links, startTime, kind);
191
133
  },
192
134
  context(execution, fiber) {
193
135
  const currentSpan = fiber.currentSpan;
194
- if (currentSpan === undefined || !isSentrySpan(currentSpan)) {
136
+ if (currentSpan === void 0 || !isSentrySpan(currentSpan)) {
195
137
  return execution();
196
138
  }
197
139
  return withActiveSpan(currentSpan.sentrySpan, execution);
198
- },
199
- } );
140
+ }
141
+ });
200
142
  };
201
-
202
143
  const makeSentryTracerV4 = () => {
203
- const EFFECT_EVALUATE = '~effect/Effect/evaluate' ;
204
-
144
+ const EFFECT_EVALUATE = "~effect/Effect/evaluate";
205
145
  return EffectTracer.make({
206
146
  span(options) {
207
147
  return createSentrySpan(
@@ -210,22 +150,18 @@ const makeSentryTracerV4 = () => {
210
150
  options.annotations,
211
151
  options.links,
212
152
  options.startTime,
213
- options.kind,
153
+ options.kind
214
154
  );
215
155
  },
216
156
  context(primitive, fiber) {
217
157
  const currentSpan = fiber.currentSpan;
218
- if (currentSpan === undefined || !isSentrySpan(currentSpan)) {
158
+ if (currentSpan === void 0 || !isSentrySpan(currentSpan)) {
219
159
  return primitive[EFFECT_EVALUATE](fiber);
220
160
  }
221
161
  return withActiveSpan(currentSpan.sentrySpan, () => primitive[EFFECT_EVALUATE](fiber));
222
- },
162
+ }
223
163
  });
224
164
  };
225
-
226
- /**
227
- * Effect Layer that sets up the Sentry tracer for Effect spans.
228
- */
229
165
  const SentryEffectTracer = isEffectV4 ? makeSentryTracerV4() : makeSentryTracerV3();
230
166
 
231
167
  export { SentryEffectTracer };