@od-oneapp/observability 2026.1.1301

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.
Files changed (107) hide show
  1. package/README.md +523 -0
  2. package/dist/client-next.d.mts +20 -0
  3. package/dist/client-next.d.mts.map +1 -0
  4. package/dist/client-next.mjs +64 -0
  5. package/dist/client-next.mjs.map +1 -0
  6. package/dist/client.d.mts +11 -0
  7. package/dist/client.d.mts.map +1 -0
  8. package/dist/client.mjs +47 -0
  9. package/dist/client.mjs.map +1 -0
  10. package/dist/env.d.mts +15 -0
  11. package/dist/env.d.mts.map +1 -0
  12. package/dist/env.mjs +45 -0
  13. package/dist/env.mjs.map +1 -0
  14. package/dist/factory-DkY353r8.mjs +380 -0
  15. package/dist/factory-DkY353r8.mjs.map +1 -0
  16. package/dist/hooks-useObservability.d.mts +11 -0
  17. package/dist/hooks-useObservability.d.mts.map +1 -0
  18. package/dist/hooks-useObservability.mjs +174 -0
  19. package/dist/hooks-useObservability.mjs.map +1 -0
  20. package/dist/index-CpcdzWrF.d.mts +24 -0
  21. package/dist/index-CpcdzWrF.d.mts.map +1 -0
  22. package/dist/index.d.mts +88 -0
  23. package/dist/index.d.mts.map +1 -0
  24. package/dist/index.mjs +97 -0
  25. package/dist/index.mjs.map +1 -0
  26. package/dist/manager-BxQqOPEg.d.mts +33 -0
  27. package/dist/manager-BxQqOPEg.d.mts.map +1 -0
  28. package/dist/plugin-Bfq-o3nr.d.mts +60 -0
  29. package/dist/plugin-Bfq-o3nr.d.mts.map +1 -0
  30. package/dist/plugin-Bt-ygG1m.d.mts +254 -0
  31. package/dist/plugin-Bt-ygG1m.d.mts.map +1 -0
  32. package/dist/plugin-CLFwRERa.mjs +593 -0
  33. package/dist/plugin-CLFwRERa.mjs.map +1 -0
  34. package/dist/plugin-CP895lBx.mjs +534 -0
  35. package/dist/plugin-CP895lBx.mjs.map +1 -0
  36. package/dist/plugin-CaQxviDs.d.mts +61 -0
  37. package/dist/plugin-CaQxviDs.d.mts.map +1 -0
  38. package/dist/plugin-lPdJirTY.mjs +234 -0
  39. package/dist/plugin-lPdJirTY.mjs.map +1 -0
  40. package/dist/plugins-betterstack-env.d.mts +29 -0
  41. package/dist/plugins-betterstack-env.d.mts.map +1 -0
  42. package/dist/plugins-betterstack-env.mjs +75 -0
  43. package/dist/plugins-betterstack-env.mjs.map +1 -0
  44. package/dist/plugins-betterstack.d.mts +4 -0
  45. package/dist/plugins-betterstack.mjs +4 -0
  46. package/dist/plugins-console.d.mts +37 -0
  47. package/dist/plugins-console.d.mts.map +1 -0
  48. package/dist/plugins-console.mjs +196 -0
  49. package/dist/plugins-console.mjs.map +1 -0
  50. package/dist/plugins-sentry-env.d.mts +37 -0
  51. package/dist/plugins-sentry-env.d.mts.map +1 -0
  52. package/dist/plugins-sentry-env.mjs +79 -0
  53. package/dist/plugins-sentry-env.mjs.map +1 -0
  54. package/dist/plugins-sentry-microfrontend-env.d.mts +49 -0
  55. package/dist/plugins-sentry-microfrontend-env.d.mts.map +1 -0
  56. package/dist/plugins-sentry-microfrontend-env.mjs +80 -0
  57. package/dist/plugins-sentry-microfrontend-env.mjs.map +1 -0
  58. package/dist/plugins-sentry-microfrontend.d.mts +2 -0
  59. package/dist/plugins-sentry-microfrontend.mjs +3 -0
  60. package/dist/plugins-sentry.d.mts +5 -0
  61. package/dist/plugins-sentry.mjs +6 -0
  62. package/dist/server-edge.d.mts +15 -0
  63. package/dist/server-edge.d.mts.map +1 -0
  64. package/dist/server-edge.mjs +53 -0
  65. package/dist/server-edge.mjs.map +1 -0
  66. package/dist/server-next.d.mts +17 -0
  67. package/dist/server-next.d.mts.map +1 -0
  68. package/dist/server-next.mjs +64 -0
  69. package/dist/server-next.mjs.map +1 -0
  70. package/dist/server.d.mts +11 -0
  71. package/dist/server.d.mts.map +1 -0
  72. package/dist/server.mjs +48 -0
  73. package/dist/server.mjs.map +1 -0
  74. package/dist/utils-CuGrTcD6.d.mts +77 -0
  75. package/dist/utils-CuGrTcD6.d.mts.map +1 -0
  76. package/env.ts +67 -0
  77. package/package.json +147 -0
  78. package/src/client-next.ts +131 -0
  79. package/src/client.ts +70 -0
  80. package/src/core/index.ts +15 -0
  81. package/src/core/manager.ts +361 -0
  82. package/src/core/plugin.ts +61 -0
  83. package/src/core/types.ts +151 -0
  84. package/src/factory/builder.ts +132 -0
  85. package/src/factory/index.ts +67 -0
  86. package/src/factory/presets.ts +78 -0
  87. package/src/hooks/useObservability.ts +206 -0
  88. package/src/plugins/betterstack/env.ts +101 -0
  89. package/src/plugins/betterstack/index.ts +15 -0
  90. package/src/plugins/betterstack/plugin.ts +373 -0
  91. package/src/plugins/console/index.ts +323 -0
  92. package/src/plugins/sentry/__tests__/plugin-tracing.test.ts +511 -0
  93. package/src/plugins/sentry/env.ts +93 -0
  94. package/src/plugins/sentry/index.ts +28 -0
  95. package/src/plugins/sentry/plugin.ts +953 -0
  96. package/src/plugins/sentry/types.ts +252 -0
  97. package/src/plugins/sentry-microfrontend/env.ts +105 -0
  98. package/src/plugins/sentry-microfrontend/index.ts +12 -0
  99. package/src/plugins/sentry-microfrontend/multiplexed-transport.ts +221 -0
  100. package/src/plugins/sentry-microfrontend/plugin.ts +500 -0
  101. package/src/plugins/sentry-microfrontend/sentry-types.ts +140 -0
  102. package/src/plugins/sentry-microfrontend/types.ts +130 -0
  103. package/src/plugins/sentry-microfrontend/utils.ts +326 -0
  104. package/src/server-edge.ts +113 -0
  105. package/src/server-next.ts +114 -0
  106. package/src/server.ts +71 -0
  107. package/src/shared.ts +148 -0
@@ -0,0 +1,593 @@
1
+ import { logDebug, logError, logWarn } from "@od-oneapp/shared/logs";
2
+ import { SentryPlugin } from "@integrations/sentry/observability-plugin/plugin";
3
+
4
+ //#region src/plugins/sentry-microfrontend/multiplexed-transport.ts
5
+ /**
6
+ * @fileoverview Multiplexed transport utilities for Sentry Micro Frontend Plugin
7
+ * Multiplexed transport utilities for Sentry Micro Frontend Plugin
8
+ */
9
+ /**
10
+ * Create a multiplexed transport that routes events to different Sentry projects.
11
+ *
12
+ * Creates a Sentry transport that routes events to different DSNs based on the
13
+ * backstageApp information in the event. Supports edge runtime environments.
14
+ *
15
+ * @param backstage - Array of backstage app configurations with DSNs
16
+ * @param fallbackDsn - Optional fallback DSN if no backstageApp match is found
17
+ * @param sentryClient - Optional Sentry client instance (defaults to global Sentry)
18
+ * @returns Multiplexed transport instance, or undefined if Sentry is not available
19
+ */
20
+ function createMultiplexedTransport(backstage, fallbackDsn, sentryClient) {
21
+ const Sentry = sentryClient !== void 0 ? sentryClient : typeof globalThis !== "undefined" ? globalThis.Sentry : null;
22
+ if (!Sentry?.makeMultiplexedTransport || !Sentry.makeFetchTransport) {
23
+ logWarn("Sentry multiplexed transport not available");
24
+ return;
25
+ }
26
+ return Sentry.makeMultiplexedTransport(Sentry.makeFetchTransport, (args) => {
27
+ const event = args.getEvent();
28
+ if (!event) return [];
29
+ const backstageApp = event.tags?.backstageApp ?? event.extra?.backstageApp ?? event.contexts?.microFrontend?.backstageApp;
30
+ if (backstageApp) {
31
+ const backstageAppConfig = backstage.find((z) => z.name === backstageApp);
32
+ if (backstageAppConfig?.dsn) {
33
+ const envelope = [{
34
+ dsn: backstageAppConfig.dsn,
35
+ release: backstageAppConfig.release ?? event.release
36
+ }];
37
+ if (backstageAppConfig.tags && event.tags) Object.assign(event.tags, backstageAppConfig.tags);
38
+ return envelope;
39
+ }
40
+ }
41
+ if (fallbackDsn) return [{ dsn: fallbackDsn }];
42
+ return [];
43
+ });
44
+ }
45
+ /**
46
+ * Enhance an event with Backstage app information before sending.
47
+ *
48
+ * Adds backstageApp tags, context, and extra data to a Sentry event.
49
+ * This ensures events are properly tagged for micro frontend routing.
50
+ *
51
+ * @param event - Sentry event to enhance
52
+ * @param backstageApp - Name of the backstage app
53
+ * @param additionalContext - Optional additional context to add
54
+ * @returns Enhanced event with backstageApp information
55
+ */
56
+ function enhanceEventWithBackstageApp(event, backstageApp, additionalContext) {
57
+ event.tags ??= {};
58
+ event.tags.backstageApp = backstageApp;
59
+ event.tags.microFrontend = true;
60
+ event.contexts ??= {};
61
+ event.contexts.microFrontend = {
62
+ backstageApp,
63
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
64
+ ...additionalContext
65
+ };
66
+ event.extra ??= {};
67
+ event.extra.backstageApp = backstageApp;
68
+ return event;
69
+ }
70
+ /**
71
+ * Create a beforeSend hook that adds backstageApp information.
72
+ *
73
+ * Creates a Sentry beforeSend hook that enhances events with backstageApp information
74
+ * before they are sent. Can wrap an existing beforeSend hook.
75
+ *
76
+ * @param backstageApp - Name of the backstage app
77
+ * @param originalBeforeSend - Optional original beforeSend hook to wrap
78
+ * @returns beforeSend hook function
79
+ */
80
+ function createBackstageBeforeSend(backstageApp, originalBeforeSend) {
81
+ return (event, hint) => {
82
+ enhanceEventWithBackstageApp(event, backstageApp);
83
+ if (originalBeforeSend) return originalBeforeSend(event, hint);
84
+ return event;
85
+ };
86
+ }
87
+
88
+ //#endregion
89
+ //#region src/plugins/sentry-microfrontend/sentry-types.ts
90
+ /**
91
+ * Map LogLevel to Sentry Severity.
92
+ *
93
+ * Converts the observability package's LogLevel to Sentry's SeverityLevel format.
94
+ *
95
+ * @param level - Log level from observability package
96
+ * @returns Corresponding Sentry severity level
97
+ */
98
+ function mapLogLevelToSentrySeverity(level) {
99
+ switch (level) {
100
+ case "error": return "error";
101
+ case "warning": return "warning";
102
+ case "info": return "info";
103
+ case "debug": return "debug";
104
+ default: return "info";
105
+ }
106
+ }
107
+
108
+ //#endregion
109
+ //#region src/plugins/sentry-microfrontend/utils.ts
110
+ /**
111
+ * @fileoverview Utility functions for Sentry Micro Frontend Plugin
112
+ * Utility functions for Sentry Micro Frontend Plugin
113
+ */
114
+ /**
115
+ * Detect the current micro frontend backstageApp based on URL path.
116
+ *
117
+ * Analyzes the current URL pathname to determine which micro frontend application
118
+ * is active. Supports custom path patterns and falls back to default patterns.
119
+ *
120
+ * @param customPatterns - Optional array of custom backstage app configurations with path patterns
121
+ * @returns Detected backstage app name, or undefined if not detected
122
+ *
123
+ * @example
124
+ * ```typescript
125
+ * const app = detectCurrentBackstageApp([
126
+ * { name: 'admin', pathPatterns: ['/admin', '/manage'] },
127
+ * { name: 'dashboard', pathPatterns: [/^\/dashboard/] }
128
+ * ]);
129
+ * // Returns: 'admin' if pathname starts with '/admin' or '/manage'
130
+ * ```
131
+ */
132
+ function detectCurrentBackstageApp(customPatterns) {
133
+ if (typeof globalThis === "undefined" || !globalThis.location) {
134
+ if (typeof process !== "undefined" && process.env?.NEXT_PUBLIC_BASE_PATH) return process.env.NEXT_PUBLIC_BASE_PATH.replace("/", "");
135
+ return;
136
+ }
137
+ const path = globalThis.location?.pathname;
138
+ if (!path) return;
139
+ if (customPatterns) {
140
+ for (const config of customPatterns) if (config.pathPatterns) {
141
+ for (const pattern of config.pathPatterns) if (typeof pattern === "string" && path.startsWith(pattern)) return config.name;
142
+ else if (pattern instanceof RegExp && pattern.test(path)) return config.name;
143
+ }
144
+ }
145
+ if (path.startsWith("/admin")) return "admin";
146
+ if (path.startsWith("/dashboard")) return "dashboard";
147
+ if (path.startsWith("/settings")) return "settings";
148
+ if (globalThis.__SENTRY_MICRO_FRONTEND_APP__) return globalThis.__SENTRY_MICRO_FRONTEND_APP__;
149
+ if (globalThis.__SENTRY_MICRO_FRONTEND_ZONE__) return globalThis.__SENTRY_MICRO_FRONTEND_ZONE__;
150
+ return "main";
151
+ }
152
+ /**
153
+ * Check if running in a host environment.
154
+ *
155
+ * Determines whether the current application is acting as a host for micro frontends
156
+ * or as a child micro frontend. Checks for explicit host markers and Sentry initialization state.
157
+ *
158
+ * @returns True if running as host, false if child or standalone
159
+ */
160
+ function isHostEnvironment() {
161
+ if (typeof globalThis === "undefined") return false;
162
+ if (globalThis.__SENTRY_MICRO_FRONTEND_HOST__) return true;
163
+ if (globalThis.Sentry && typeof globalThis.Sentry.getCurrentHub === "function") return false;
164
+ return false;
165
+ }
166
+ /**
167
+ * Create a Sentry scope with backstageApp-specific context.
168
+ *
169
+ * Creates a new Sentry scope configured with micro frontend tags and context.
170
+ * Includes backstageApp tag, microFrontend context, and any additional tags provided.
171
+ *
172
+ * @param backstageApp - Name of the backstage app
173
+ * @param additionalTags - Optional additional tags to set on the scope
174
+ * @returns Sentry scope instance, or null if Sentry is not available
175
+ */
176
+ function createBackstageScope(backstageApp, additionalTags) {
177
+ if (typeof globalThis === "undefined" || !globalThis.Sentry) return null;
178
+ const { Sentry } = globalThis;
179
+ if (!Sentry.Scope || typeof Sentry.Scope !== "function") return null;
180
+ try {
181
+ const scope = new Sentry.Scope();
182
+ scope.setTag("backstageApp", backstageApp);
183
+ scope.setTag("microFrontend", true);
184
+ scope.setContext("microFrontend", {
185
+ backstageApp,
186
+ isHost: globalThis.__SENTRY_MICRO_FRONTEND_HOST__ ?? false,
187
+ url: globalThis.location?.href ?? void 0
188
+ });
189
+ if (additionalTags) Object.entries(additionalTags).forEach(([key, value]) => {
190
+ scope.setTag(key, value);
191
+ });
192
+ return scope;
193
+ } catch (error) {
194
+ logError("[SentryMicroFrontendPlugin] Failed to create Backstage scope", { error });
195
+ return null;
196
+ }
197
+ }
198
+ /**
199
+ * Check if Sentry is already initialized by a parent application.
200
+ *
201
+ * Verifies whether a parent Sentry instance exists in the global scope.
202
+ * Used to determine if the current micro frontend should use the parent's Sentry
203
+ * or initialize its own instance.
204
+ *
205
+ * @returns True if parent Sentry is available, false otherwise
206
+ */
207
+ function hasParentSentry() {
208
+ if (typeof globalThis === "undefined") return false;
209
+ const { Sentry } = globalThis;
210
+ if (!Sentry) return false;
211
+ return [
212
+ "captureException",
213
+ "captureMessage",
214
+ "withScope"
215
+ ].every((method) => typeof Sentry[method] === "function");
216
+ }
217
+ /**
218
+ * Get the parent Sentry instance if available.
219
+ *
220
+ * Returns the global Sentry instance if it exists and has been initialized
221
+ * by a parent application. Returns null if no parent Sentry is available.
222
+ *
223
+ * @returns Parent Sentry SDK instance, or null if not available
224
+ */
225
+ function getParentSentry() {
226
+ if (hasParentSentry()) return globalThis.Sentry;
227
+ return null;
228
+ }
229
+ /**
230
+ * Mark the current environment as a host.
231
+ *
232
+ * Sets global flags indicating that this application is acting as a host
233
+ * for micro frontends. This affects how Sentry events are routed and tagged.
234
+ *
235
+ * @param backstageApp - Optional backstage app name to set
236
+ */
237
+ function markAsHost(backstageApp) {
238
+ if (typeof globalThis !== "undefined") {
239
+ globalThis.__SENTRY_MICRO_FRONTEND_HOST__ = true;
240
+ if (backstageApp) {
241
+ globalThis.__SENTRY_MICRO_FRONTEND_APP__ = backstageApp;
242
+ globalThis.__SENTRY_MICRO_FRONTEND_ZONE__ = backstageApp;
243
+ }
244
+ }
245
+ }
246
+ /**
247
+ * Ensure only one Sentry initialization happens (thread-safe).
248
+ *
249
+ * Prevents multiple Sentry initializations using global state tracking.
250
+ * Uses timestamps and unique IDs to detect concurrent initialization attempts.
251
+ * Throws an error if Sentry is already initialized or if concurrent initialization is detected.
252
+ *
253
+ * @throws Error if Sentry is already initialized or concurrent initialization detected
254
+ */
255
+ function ensureSingleInit() {
256
+ const initKey = "__SENTRY_INIT_STATE__";
257
+ const now = Date.now();
258
+ if (typeof globalThis !== "undefined") {
259
+ const globalState = globalThis[initKey];
260
+ if (globalState) {
261
+ const { status, timestamp, id } = globalState;
262
+ if (status === "initialized") throw new Error("Sentry has already been initialized! Use hasParentSentry() to check before initializing.");
263
+ if (status === "initializing" && now - timestamp < 5e3) throw new Error(`Sentry initialization already in progress (started ${now - timestamp}ms ago by ${id})`);
264
+ }
265
+ const initId = `${now}-${Math.random().toString(36).substr(2, 9)}`;
266
+ globalThis[initKey] = {
267
+ status: "initializing",
268
+ timestamp: now,
269
+ id: initId
270
+ };
271
+ if (globalThis[initKey].id !== initId) throw new Error("Concurrent Sentry initialization detected");
272
+ globalThis[initKey] = {
273
+ status: "initialized",
274
+ timestamp: now,
275
+ id: initId
276
+ };
277
+ globalThis.__SENTRY_INITIALIZED__ = true;
278
+ }
279
+ }
280
+
281
+ //#endregion
282
+ //#region src/plugins/sentry-microfrontend/plugin.ts
283
+ /**
284
+ * @fileoverview Sentry Micro Frontend Plugin
285
+ * Sentry Micro Frontend Plugin
286
+ *
287
+ * Extends the base Sentry plugin with micro frontend-specific functionality
288
+ */
289
+ /**
290
+ * Sentry plugin optimized for micro frontend architectures
291
+ */
292
+ /**
293
+ * Sentry plugin optimized for micro frontend architectures.
294
+ *
295
+ * Extends SentryPlugin with micro frontend-specific features:
296
+ * - Host/child/standalone mode detection
297
+ * - Multiplexed transport for routing events to different Sentry projects
298
+ * - Backstage app context management
299
+ * - Parent Sentry instance detection and reuse
300
+ */
301
+ var SentryMicroFrontendPlugin = class SentryMicroFrontendPlugin extends SentryPlugin {
302
+ mode;
303
+ backstageApp;
304
+ parentSentry;
305
+ backstageScope;
306
+ microFrontendConfig;
307
+ eventProcessorCleanup;
308
+ /**
309
+ * Create a new SentryMicroFrontendPlugin instance.
310
+ *
311
+ * @param config - Sentry micro frontend plugin configuration
312
+ */
313
+ constructor(config = {}) {
314
+ const mode = SentryMicroFrontendPlugin.determineMode(config);
315
+ const baseConfig = SentryMicroFrontendPlugin.prepareConfig(config, mode);
316
+ super(baseConfig);
317
+ this.mode = mode;
318
+ this.microFrontendConfig = config;
319
+ this.backstageApp = config.backstageApp ?? detectCurrentBackstageApp(config.backstageApps);
320
+ if (this.mode === "child") {
321
+ const parent = getParentSentry();
322
+ if (parent) {
323
+ this.parentSentry = parent;
324
+ this.enabled = true;
325
+ if (this.backstageApp && this.parentSentry.Scope) this.backstageScope = createBackstageScope(this.backstageApp, config.globalTags);
326
+ }
327
+ }
328
+ if (this.mode === "host") markAsHost(this.backstageApp);
329
+ }
330
+ /**
331
+ * Determine the operation mode based on configuration and environment.
332
+ *
333
+ * @param config - Plugin configuration
334
+ * @returns Operation mode ('host', 'child', or 'standalone')
335
+ */
336
+ static determineMode(config) {
337
+ if (config.isHost) return "host";
338
+ if (config.detectParent !== false && hasParentSentry()) return "child";
339
+ return "standalone";
340
+ }
341
+ /**
342
+ * Prepare configuration based on operation mode.
343
+ *
344
+ * Adjusts configuration settings based on whether running as host, child, or standalone.
345
+ *
346
+ * @param config - Original plugin configuration
347
+ * @param mode - Determined operation mode
348
+ * @returns Prepared configuration object
349
+ */
350
+ static prepareConfig(config, mode) {
351
+ const preparedConfig = { ...config };
352
+ if (mode === "child") preparedConfig.enabled = false;
353
+ else if (mode === "host" && config.backstageApps && config.useMultiplexedTransport !== false) {}
354
+ return preparedConfig;
355
+ }
356
+ /**
357
+ * Initialize the plugin
358
+ */
359
+ async initialize(config) {
360
+ const mergedConfig = {
361
+ ...this.microFrontendConfig,
362
+ ...config
363
+ };
364
+ if (this.mode === "child") {
365
+ if (this.parentSentry) {
366
+ this.client = this.parentSentry;
367
+ this.initialized = true;
368
+ if (this.backstageApp && mergedConfig.addBackstageContext !== false) this.configureParentSentry();
369
+ }
370
+ return;
371
+ }
372
+ if (mergedConfig.preventDuplicateInit !== false) try {
373
+ ensureSingleInit();
374
+ } catch (error) {
375
+ logError("Sentry initialization prevented", { error });
376
+ this.enabled = false;
377
+ return;
378
+ }
379
+ await super.initialize(mergedConfig);
380
+ if (this.mode === "host" && this.client && mergedConfig.backstageApps) this.setupHostMode(mergedConfig);
381
+ }
382
+ /**
383
+ * Configure parent Sentry instance for child mode
384
+ */
385
+ configureParentSentry() {
386
+ if (!this.parentSentry || !this.backstageApp) {
387
+ logWarn("[SentryMicroFrontendPlugin] Cannot configure parent Sentry: missing parentSentry or backstageApp");
388
+ return;
389
+ }
390
+ try {
391
+ const processor = (event) => {
392
+ try {
393
+ if (this.shouldProcessEvent(event)) enhanceEventWithBackstageApp(event, this.backstageApp ?? "", {
394
+ mode: this.mode,
395
+ plugin: "SentryMicroFrontendPlugin"
396
+ });
397
+ } catch (error) {
398
+ logError("[SentryMicroFrontendPlugin] Error processing event", {
399
+ error,
400
+ event
401
+ });
402
+ }
403
+ return event;
404
+ };
405
+ if (typeof this.parentSentry.addEventProcessor === "function") {
406
+ this.parentSentry.addEventProcessor(processor);
407
+ this.eventProcessorCleanup = () => {};
408
+ } else logWarn("[SentryMicroFrontendPlugin] Parent Sentry does not support addEventProcessor");
409
+ } catch (error) {
410
+ logError("[SentryMicroFrontendPlugin] Failed to configure parent Sentry", { error });
411
+ }
412
+ }
413
+ /**
414
+ * Set up host mode with multiplexed transport
415
+ */
416
+ setupHostMode(config) {
417
+ if (!config.backstageApps || !this.client) {
418
+ logWarn("[SentryMicroFrontendPlugin] Cannot setup host mode: missing backstageApps or client");
419
+ return;
420
+ }
421
+ try {
422
+ const transport = createMultiplexedTransport(config.backstageApps, config.fallbackDsn ?? config.dsn, this.client);
423
+ if (transport && typeof this.client.init === "function") {
424
+ const currentOptions = typeof this.client.getOptions === "function" ? this.client.getOptions() : {};
425
+ this.client.init({
426
+ ...currentOptions,
427
+ transport,
428
+ beforeSend: createBackstageBeforeSend(this.backstageApp ?? "main", config.beforeSend)
429
+ });
430
+ } else logWarn("[SentryMicroFrontendPlugin] Client does not support init method or transport creation failed");
431
+ } catch (error) {
432
+ logError("[SentryMicroFrontendPlugin] Failed to setup host mode", { error });
433
+ }
434
+ }
435
+ /**
436
+ * Check if we should process this event
437
+ */
438
+ shouldProcessEvent(event) {
439
+ if (event.tags?.microFrontendProcessed) return false;
440
+ if (this.backstageApp && event.tags?.backstageApp && event.tags.backstageApp !== this.backstageApp) return false;
441
+ return true;
442
+ }
443
+ /**
444
+ * Capture an exception with backstageApp context
445
+ */
446
+ captureException(error, context) {
447
+ if (!this.enabled) return;
448
+ try {
449
+ if (this.mode === "child" && this.parentSentry && this.backstageScope) if (typeof this.parentSentry.withScope === "function") this.parentSentry.withScope((scope) => {
450
+ try {
451
+ if (this.backstageScope && typeof scope.setTag === "function") {
452
+ scope.setTag("backstageApp", this.backstageApp ?? "unknown");
453
+ scope.setTag("microFrontend", true);
454
+ scope.setContext("microFrontend", {
455
+ backstageApp: this.backstageApp,
456
+ mode: this.mode
457
+ });
458
+ }
459
+ if (context && typeof scope.setContext === "function") scope.setContext("additional", context);
460
+ if (this.parentSentry && typeof this.parentSentry.captureException === "function") this.parentSentry.captureException(error);
461
+ } catch (scopeError) {
462
+ logError("[SentryMicroFrontendPlugin] Error in scope callback", { error: scopeError });
463
+ }
464
+ });
465
+ else logWarn("[SentryMicroFrontendPlugin] Parent Sentry does not support withScope");
466
+ else {
467
+ const enhancedContext = {
468
+ ...context,
469
+ microFrontend: {
470
+ backstageApp: this.backstageApp,
471
+ mode: this.mode
472
+ }
473
+ };
474
+ super.captureException(error, enhancedContext);
475
+ }
476
+ } catch (captureError) {
477
+ logError("[SentryMicroFrontendPlugin] Failed to capture exception", { error: captureError });
478
+ }
479
+ }
480
+ /**
481
+ * Capture a message with backstageApp context
482
+ */
483
+ captureMessage(message, level = "info", context) {
484
+ if (!this.enabled) return;
485
+ try {
486
+ const sentryLevel = mapLogLevelToSentrySeverity(level);
487
+ if (this.mode === "child" && this.parentSentry && this.backstageScope) if (typeof this.parentSentry.withScope === "function") this.parentSentry.withScope((scope) => {
488
+ try {
489
+ if (this.backstageScope && typeof scope.setTag === "function") {
490
+ scope.setTag("backstageApp", this.backstageApp ?? "unknown");
491
+ scope.setTag("microFrontend", true);
492
+ if (typeof scope.setContext === "function") scope.setContext("microFrontend", {
493
+ backstageApp: this.backstageApp,
494
+ mode: this.mode
495
+ });
496
+ }
497
+ if (context && typeof scope.setContext === "function") scope.setContext("additional", context);
498
+ if (this.parentSentry && typeof this.parentSentry.captureMessage === "function") this.parentSentry.captureMessage(message, sentryLevel);
499
+ } catch (scopeError) {
500
+ logError("[SentryMicroFrontendPlugin] Error in scope callback", { error: scopeError });
501
+ }
502
+ });
503
+ else logWarn("[SentryMicroFrontendPlugin] Parent Sentry does not support withScope");
504
+ else super.captureMessage(message, level, context);
505
+ } catch (captureError) {
506
+ logError("[SentryMicroFrontendPlugin] Failed to capture message", { error: captureError });
507
+ }
508
+ }
509
+ /**
510
+ * Get the current operation mode
511
+ */
512
+ getMode() {
513
+ return this.mode;
514
+ }
515
+ /**
516
+ * Get the current Backstage app identifier
517
+ */
518
+ getBackstageApp() {
519
+ return this.backstageApp;
520
+ }
521
+ /**
522
+ * @deprecated Use getBackstageApp instead.
523
+ */
524
+ getZone() {
525
+ return this.getBackstageApp();
526
+ }
527
+ /**
528
+ * Get debug information about the plugin state
529
+ */
530
+ getDebugInfo() {
531
+ return {
532
+ mode: this.mode,
533
+ backstageApp: this.backstageApp,
534
+ enabled: this.enabled,
535
+ initialized: this.initialized,
536
+ hasParentSentry: this.mode === "child" && Boolean(this.parentSentry),
537
+ clientType: this.client ? this.client.constructor.name : "none"
538
+ };
539
+ }
540
+ /**
541
+ * Clean up the plugin and release resources
542
+ */
543
+ async cleanup() {
544
+ try {
545
+ if (this.eventProcessorCleanup) {
546
+ this.eventProcessorCleanup();
547
+ this.eventProcessorCleanup = void 0;
548
+ }
549
+ if (this.backstageScope && typeof this.backstageScope.clear === "function") this.backstageScope.clear();
550
+ this.backstageScope = void 0;
551
+ this.parentSentry = void 0;
552
+ await super.cleanup();
553
+ this.initialized = false;
554
+ this.enabled = false;
555
+ logDebug("[SentryMicroFrontendPlugin] Cleanup completed");
556
+ } catch (error) {
557
+ logError("[SentryMicroFrontendPlugin] Error during cleanup", { error });
558
+ }
559
+ }
560
+ /**
561
+ * Destroy the plugin (alias for cleanup)
562
+ */
563
+ async destroy() {
564
+ await this.cleanup();
565
+ }
566
+ };
567
+ /**
568
+ * Factory function to create a Sentry Micro Frontend plugin.
569
+ *
570
+ * Creates a configured SentryMicroFrontendPlugin instance with micro frontend-specific
571
+ * features like multiplexed transport and backstage app routing.
572
+ *
573
+ * @param config - Optional Sentry micro frontend plugin configuration
574
+ * @returns SentryMicroFrontendPlugin instance
575
+ *
576
+ * @example
577
+ * ```typescript
578
+ * const sentry = createSentryMicroFrontendPlugin({
579
+ * dsn: 'https://...',
580
+ * backstage: [
581
+ * { name: 'admin', dsn: 'https://admin-dsn...' },
582
+ * { name: 'dashboard', dsn: 'https://dashboard-dsn...' },
583
+ * ],
584
+ * });
585
+ * ```
586
+ */
587
+ const createSentryMicroFrontendPlugin = (config) => {
588
+ return new SentryMicroFrontendPlugin(config);
589
+ };
590
+
591
+ //#endregion
592
+ export { isHostEnvironment as a, detectCurrentBackstageApp as i, createSentryMicroFrontendPlugin as n, createMultiplexedTransport as o, createBackstageScope as r, SentryMicroFrontendPlugin as t };
593
+ //# sourceMappingURL=plugin-CLFwRERa.mjs.map