@superblocksteam/telemetry 2.0.105 → 2.0.106-next.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.
Files changed (99) hide show
  1. package/dist/browser/console-logging.d.ts +18 -0
  2. package/dist/browser/console-logging.d.ts.map +1 -0
  3. package/dist/browser/console-logging.js +32 -0
  4. package/dist/browser/console-logging.js.map +1 -0
  5. package/dist/browser/early-console-buffer.d.ts +39 -0
  6. package/dist/browser/early-console-buffer.d.ts.map +1 -0
  7. package/dist/browser/early-console-buffer.js +157 -0
  8. package/dist/browser/early-console-buffer.js.map +1 -0
  9. package/dist/browser/index.d.ts +7 -0
  10. package/dist/browser/index.d.ts.map +1 -1
  11. package/dist/browser/index.js +22 -1
  12. package/dist/browser/index.js.map +1 -1
  13. package/dist/browser/init.d.ts +27 -3
  14. package/dist/browser/init.d.ts.map +1 -1
  15. package/dist/browser/init.js +159 -14
  16. package/dist/browser/init.js.map +1 -1
  17. package/dist/browser/instrumentations.d.ts +61 -0
  18. package/dist/browser/instrumentations.d.ts.map +1 -0
  19. package/dist/browser/instrumentations.js +84 -0
  20. package/dist/browser/instrumentations.js.map +1 -0
  21. package/dist/browser/logs.d.ts +52 -0
  22. package/dist/browser/logs.d.ts.map +1 -0
  23. package/dist/browser/logs.js +85 -0
  24. package/dist/browser/logs.js.map +1 -0
  25. package/dist/browser/metrics.d.ts +25 -0
  26. package/dist/browser/metrics.d.ts.map +1 -0
  27. package/dist/browser/metrics.js +37 -0
  28. package/dist/browser/metrics.js.map +1 -0
  29. package/dist/browser/sanitizer.d.ts +35 -0
  30. package/dist/browser/sanitizer.d.ts.map +1 -0
  31. package/dist/browser/sanitizer.js +211 -0
  32. package/dist/browser/sanitizer.js.map +1 -0
  33. package/dist/browser/traced-socket.d.ts +102 -0
  34. package/dist/browser/traced-socket.d.ts.map +1 -0
  35. package/dist/browser/traced-socket.js +186 -0
  36. package/dist/browser/traced-socket.js.map +1 -0
  37. package/dist/common/index.d.ts +1 -0
  38. package/dist/common/index.d.ts.map +1 -1
  39. package/dist/common/index.js +1 -0
  40. package/dist/common/index.js.map +1 -1
  41. package/dist/common/trace-sanitizer.d.ts.map +1 -1
  42. package/dist/common/trace-sanitizer.js +5 -2
  43. package/dist/common/trace-sanitizer.js.map +1 -1
  44. package/dist/common/traced-socket-types.d.ts +43 -0
  45. package/dist/common/traced-socket-types.d.ts.map +1 -0
  46. package/dist/common/traced-socket-types.js +17 -0
  47. package/dist/common/traced-socket-types.js.map +1 -0
  48. package/dist/types/index.d.ts +5 -1
  49. package/dist/types/index.d.ts.map +1 -1
  50. package/dist-esm/browser/console-logging.d.ts +18 -0
  51. package/dist-esm/browser/console-logging.d.ts.map +1 -0
  52. package/dist-esm/browser/console-logging.js +27 -0
  53. package/dist-esm/browser/console-logging.js.map +1 -0
  54. package/dist-esm/browser/early-console-buffer.d.ts +39 -0
  55. package/dist-esm/browser/early-console-buffer.d.ts.map +1 -0
  56. package/dist-esm/browser/early-console-buffer.js +155 -0
  57. package/dist-esm/browser/early-console-buffer.js.map +1 -0
  58. package/dist-esm/browser/index.d.ts +7 -0
  59. package/dist-esm/browser/index.d.ts.map +1 -1
  60. package/dist-esm/browser/index.js +7 -0
  61. package/dist-esm/browser/index.js.map +1 -1
  62. package/dist-esm/browser/init.d.ts +27 -3
  63. package/dist-esm/browser/init.d.ts.map +1 -1
  64. package/dist-esm/browser/init.js +161 -16
  65. package/dist-esm/browser/init.js.map +1 -1
  66. package/dist-esm/browser/instrumentations.d.ts +61 -0
  67. package/dist-esm/browser/instrumentations.d.ts.map +1 -0
  68. package/dist-esm/browser/instrumentations.js +80 -0
  69. package/dist-esm/browser/instrumentations.js.map +1 -0
  70. package/dist-esm/browser/logs.d.ts +52 -0
  71. package/dist-esm/browser/logs.d.ts.map +1 -0
  72. package/dist-esm/browser/logs.js +78 -0
  73. package/dist-esm/browser/logs.js.map +1 -0
  74. package/dist-esm/browser/metrics.d.ts +25 -0
  75. package/dist-esm/browser/metrics.d.ts.map +1 -0
  76. package/dist-esm/browser/metrics.js +34 -0
  77. package/dist-esm/browser/metrics.js.map +1 -0
  78. package/dist-esm/browser/sanitizer.d.ts +35 -0
  79. package/dist-esm/browser/sanitizer.d.ts.map +1 -0
  80. package/dist-esm/browser/sanitizer.js +207 -0
  81. package/dist-esm/browser/sanitizer.js.map +1 -0
  82. package/dist-esm/browser/traced-socket.d.ts +102 -0
  83. package/dist-esm/browser/traced-socket.d.ts.map +1 -0
  84. package/dist-esm/browser/traced-socket.js +182 -0
  85. package/dist-esm/browser/traced-socket.js.map +1 -0
  86. package/dist-esm/common/index.d.ts +1 -0
  87. package/dist-esm/common/index.d.ts.map +1 -1
  88. package/dist-esm/common/index.js +1 -0
  89. package/dist-esm/common/index.js.map +1 -1
  90. package/dist-esm/common/trace-sanitizer.d.ts.map +1 -1
  91. package/dist-esm/common/trace-sanitizer.js +5 -2
  92. package/dist-esm/common/trace-sanitizer.js.map +1 -1
  93. package/dist-esm/common/traced-socket-types.d.ts +43 -0
  94. package/dist-esm/common/traced-socket-types.d.ts.map +1 -0
  95. package/dist-esm/common/traced-socket-types.js +16 -0
  96. package/dist-esm/common/traced-socket-types.js.map +1 -0
  97. package/dist-esm/types/index.d.ts +5 -1
  98. package/dist-esm/types/index.d.ts.map +1 -1
  99. package/package.json +5 -3
@@ -0,0 +1,80 @@
1
+ /**
2
+ * Browser Auto-Instrumentations Factory
3
+ *
4
+ * Creates and configures auto-instrumentations for browser telemetry.
5
+ * Handles XHR and Fetch requests with configurable URL filtering and
6
+ * trace context propagation.
7
+ */
8
+ import { context } from "@opentelemetry/api";
9
+ import { XMLHttpRequestInstrumentation } from "@opentelemetry/instrumentation-xml-http-request";
10
+ import { StackContextManager } from "@opentelemetry/sdk-trace-web";
11
+ /**
12
+ * Default regex for ignoring static asset URLs.
13
+ * These requests are not worth tracing and would create noise.
14
+ */
15
+ const DEFAULT_IGNORE_URLS = /\.(js|css|png|jpg|jpeg|svg|gif|woff|woff2|ttf|eot|ico)$/;
16
+ /**
17
+ * Create auto-instrumentations for browser telemetry.
18
+ *
19
+ * Returns an array containing XMLHttpRequestInstrumentation and optionally
20
+ * FetchInstrumentation (when the package is available).
21
+ *
22
+ * Both instrumentations use the provided ignoreUrls to filter out asset
23
+ * downloads, and propagate trace context only to URLs matching propagateTraceUrls.
24
+ *
25
+ * @param config - Optional instrumentation configuration
26
+ * @returns Array of configured Instrumentation instances
27
+ *
28
+ * @example
29
+ * ```typescript
30
+ * const instrumentations = createBrowserInstrumentations({
31
+ * propagateTraceUrls: [/https:\/\/api\.superblocks\.com/],
32
+ * ignoreUrls: [/\/static\//],
33
+ * });
34
+ * registerInstrumentations({ instrumentations });
35
+ * ```
36
+ */
37
+ export function createBrowserInstrumentations(config) {
38
+ const ignoreUrls = config?.ignoreUrls ?? [DEFAULT_IGNORE_URLS];
39
+ const propagateTraceHeaderCorsUrls = config?.propagateTraceUrls ?? [];
40
+ const instrumentations = [
41
+ new XMLHttpRequestInstrumentation({
42
+ ignoreUrls,
43
+ propagateTraceHeaderCorsUrls,
44
+ }),
45
+ ];
46
+ // Attempt to include FetchInstrumentation if available.
47
+ // This package may not be installed in all environments.
48
+ try {
49
+ const { FetchInstrumentation } =
50
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
51
+ require("@opentelemetry/instrumentation-fetch");
52
+ instrumentations.push(new FetchInstrumentation({
53
+ ignoreUrls,
54
+ propagateTraceHeaderCorsUrls,
55
+ }));
56
+ }
57
+ catch {
58
+ // FetchInstrumentation is not available; XHR instrumentation will be used alone.
59
+ }
60
+ return instrumentations;
61
+ }
62
+ /**
63
+ * Register the StackContextManager for async context propagation in the browser.
64
+ *
65
+ * This must be called before using `context.with()` in browser environments.
66
+ * Without this, Redux middleware and other async code cannot thread trace
67
+ * context through async operations.
68
+ *
69
+ * @example
70
+ * ```typescript
71
+ * registerBrowserContextManager();
72
+ * // context.with() now works correctly in browser async flows
73
+ * ```
74
+ */
75
+ export function registerBrowserContextManager() {
76
+ const contextManager = new StackContextManager();
77
+ contextManager.enable();
78
+ context.setGlobalContextManager(contextManager);
79
+ }
80
+ //# sourceMappingURL=instrumentations.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"instrumentations.js","sourceRoot":"","sources":["../../src/browser/instrumentations.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAE7C,OAAO,EAAE,6BAA6B,EAAE,MAAM,iDAAiD,CAAC;AAChG,OAAO,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AAEnE;;;GAGG;AACH,MAAM,mBAAmB,GACvB,yDAAyD,CAAC;AAmB5D;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,UAAU,6BAA6B,CAC3C,MAAqC;IAErC,MAAM,UAAU,GAAG,MAAM,EAAE,UAAU,IAAI,CAAC,mBAAmB,CAAC,CAAC;IAC/D,MAAM,4BAA4B,GAAG,MAAM,EAAE,kBAAkB,IAAI,EAAE,CAAC;IAEtE,MAAM,gBAAgB,GAAsB;QAC1C,IAAI,6BAA6B,CAAC;YAChC,UAAU;YACV,4BAA4B;SAC7B,CAAC;KACH,CAAC;IAEF,wDAAwD;IACxD,yDAAyD;IACzD,IAAI,CAAC;QACH,MAAM,EAAE,oBAAoB,EAAE;QAC5B,iEAAiE;QACjE,OAAO,CAAC,sCAAsC,CAK7C,CAAC;QACJ,gBAAgB,CAAC,IAAI,CACnB,IAAI,oBAAoB,CAAC;YACvB,UAAU;YACV,4BAA4B;SAC7B,CAAC,CACH,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,iFAAiF;IACnF,CAAC;IAED,OAAO,gBAAgB,CAAC;AAC1B,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,6BAA6B;IAC3C,MAAM,cAAc,GAAG,IAAI,mBAAmB,EAAE,CAAC;IACjD,cAAc,CAAC,MAAM,EAAE,CAAC;IACxB,OAAO,CAAC,uBAAuB,CAAC,cAAc,CAAC,CAAC;AAClD,CAAC"}
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Browser Log Provider
3
+ *
4
+ * Initializes the OTel LoggerProvider for browser contexts. Pairs with the
5
+ * EarlyConsoleBuffer to ensure pre-init console messages are captured and
6
+ * forwarded to the OTLP endpoint.
7
+ *
8
+ * This is the ONLY approved way to init log telemetry in browser contexts.
9
+ */
10
+ import { type Logger } from "@opentelemetry/api-logs";
11
+ export interface BrowserLogsConfig {
12
+ /** Full URL for the OTLP logs endpoint, e.g. "https://app.example.com/api/v1/logs" */
13
+ otlpUrl: string;
14
+ /** Logical service name recorded in every log record */
15
+ serviceName: string;
16
+ }
17
+ export interface BrowserLogsInstance {
18
+ /** Get a named Logger (uses serviceName when name is omitted) */
19
+ getLogger: (name?: string) => Logger;
20
+ /** Gracefully shut down the underlying LoggerProvider */
21
+ shutdown: () => Promise<void>;
22
+ }
23
+ /**
24
+ * Initialize the browser log provider.
25
+ *
26
+ * - Creates an OTLPLogExporter pointed at `config.otlpUrl`
27
+ * - Wraps it in a BatchLogRecordProcessor
28
+ * - Enables the EarlyConsoleBuffer so buffered pre-init console messages are
29
+ * flushed to OpenTelemetry immediately
30
+ *
31
+ * Calling this more than once returns the existing instance with a warning.
32
+ *
33
+ * @example
34
+ * ```typescript
35
+ * import { initBrowserLogs } from '@superblocksteam/telemetry/browser';
36
+ *
37
+ * const logs = initBrowserLogs({
38
+ * otlpUrl: 'https://app.superblocks.com/api/v1/logs',
39
+ * serviceName: 'superblocks-ui',
40
+ * });
41
+ *
42
+ * const logger = logs.getLogger();
43
+ * logger.emit({ severityNumber: SeverityNumber.INFO, body: 'hello' });
44
+ * ```
45
+ */
46
+ export declare function initBrowserLogs(config: BrowserLogsConfig): BrowserLogsInstance;
47
+ /**
48
+ * Reset the browser log provider singleton (for testing only).
49
+ * @internal
50
+ */
51
+ export declare function resetBrowserLogs(): void;
52
+ //# sourceMappingURL=logs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logs.d.ts","sourceRoot":"","sources":["../../src/browser/logs.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,KAAK,MAAM,EAAE,MAAM,yBAAyB,CAAC;AAUtD,MAAM,WAAW,iBAAiB;IAChC,sFAAsF;IACtF,OAAO,EAAE,MAAM,CAAC;IAChB,wDAAwD;IACxD,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,mBAAmB;IAClC,iEAAiE;IACjE,SAAS,EAAE,CAAC,IAAI,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;IACrC,yDAAyD;IACzD,QAAQ,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC/B;AAcD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,eAAe,CAC7B,MAAM,EAAE,iBAAiB,GACxB,mBAAmB,CA8BrB;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,IAAI,IAAI,CAEvC"}
@@ -0,0 +1,78 @@
1
+ /**
2
+ * Browser Log Provider
3
+ *
4
+ * Initializes the OTel LoggerProvider for browser contexts. Pairs with the
5
+ * EarlyConsoleBuffer to ensure pre-init console messages are captured and
6
+ * forwarded to the OTLP endpoint.
7
+ *
8
+ * This is the ONLY approved way to init log telemetry in browser contexts.
9
+ */
10
+ import { OTLPLogExporter } from "@opentelemetry/exporter-logs-otlp-http";
11
+ import { BatchLogRecordProcessor, LoggerProvider, } from "@opentelemetry/sdk-logs";
12
+ import EarlyConsoleBuffer from "./early-console-buffer.js";
13
+ import { createSanitizingLogProcessor } from "./sanitizer.js";
14
+ // Singleton
15
+ let instance;
16
+ function validateConfig(config) {
17
+ if (!config.serviceName?.trim()) {
18
+ throw new Error("[Telemetry] serviceName is required and cannot be empty");
19
+ }
20
+ if (!config.otlpUrl?.trim()) {
21
+ throw new Error("[Telemetry] otlpUrl is required for browser logs");
22
+ }
23
+ }
24
+ /**
25
+ * Initialize the browser log provider.
26
+ *
27
+ * - Creates an OTLPLogExporter pointed at `config.otlpUrl`
28
+ * - Wraps it in a BatchLogRecordProcessor
29
+ * - Enables the EarlyConsoleBuffer so buffered pre-init console messages are
30
+ * flushed to OpenTelemetry immediately
31
+ *
32
+ * Calling this more than once returns the existing instance with a warning.
33
+ *
34
+ * @example
35
+ * ```typescript
36
+ * import { initBrowserLogs } from '@superblocksteam/telemetry/browser';
37
+ *
38
+ * const logs = initBrowserLogs({
39
+ * otlpUrl: 'https://app.superblocks.com/api/v1/logs',
40
+ * serviceName: 'superblocks-ui',
41
+ * });
42
+ *
43
+ * const logger = logs.getLogger();
44
+ * logger.emit({ severityNumber: SeverityNumber.INFO, body: 'hello' });
45
+ * ```
46
+ */
47
+ export function initBrowserLogs(config) {
48
+ validateConfig(config);
49
+ if (instance) {
50
+ console.warn("[Telemetry] Browser log provider already initialized");
51
+ return instance;
52
+ }
53
+ const exporter = new OTLPLogExporter({ url: config.otlpUrl });
54
+ const sanitizer = createSanitizingLogProcessor();
55
+ const batchProcessor = new BatchLogRecordProcessor(exporter);
56
+ const provider = new LoggerProvider({
57
+ processors: [sanitizer, batchProcessor],
58
+ });
59
+ // Wire the EarlyConsoleBuffer so buffered pre-init logs are flushed now.
60
+ const otelLogger = provider.getLogger(config.serviceName, "1.0.0");
61
+ EarlyConsoleBuffer.getInstance().enableOpenTelemetry(otelLogger);
62
+ instance = {
63
+ getLogger: (name) => provider.getLogger(name ?? config.serviceName, "1.0.0"),
64
+ shutdown: async () => {
65
+ await provider.shutdown();
66
+ instance = undefined;
67
+ },
68
+ };
69
+ return instance;
70
+ }
71
+ /**
72
+ * Reset the browser log provider singleton (for testing only).
73
+ * @internal
74
+ */
75
+ export function resetBrowserLogs() {
76
+ instance = undefined;
77
+ }
78
+ //# sourceMappingURL=logs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logs.js","sourceRoot":"","sources":["../../src/browser/logs.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,EAAE,eAAe,EAAE,MAAM,wCAAwC,CAAC;AACzE,OAAO,EACL,uBAAuB,EACvB,cAAc,GACf,MAAM,yBAAyB,CAAC;AAEjC,OAAO,kBAAkB,MAAM,2BAA2B,CAAC;AAC3D,OAAO,EAAE,4BAA4B,EAAE,MAAM,gBAAgB,CAAC;AAgB9D,YAAY;AACZ,IAAI,QAAyC,CAAC;AAE9C,SAAS,cAAc,CAAC,MAAyB;IAC/C,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,IAAI,EAAE,EAAE,CAAC;QAChC,MAAM,IAAI,KAAK,CAAC,yDAAyD,CAAC,CAAC;IAC7E,CAAC;IACD,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,IAAI,EAAE,EAAE,CAAC;QAC5B,MAAM,IAAI,KAAK,CAAC,kDAAkD,CAAC,CAAC;IACtE,CAAC;AACH,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,UAAU,eAAe,CAC7B,MAAyB;IAEzB,cAAc,CAAC,MAAM,CAAC,CAAC;IAEvB,IAAI,QAAQ,EAAE,CAAC;QACb,OAAO,CAAC,IAAI,CAAC,sDAAsD,CAAC,CAAC;QACrE,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,MAAM,QAAQ,GAAG,IAAI,eAAe,CAAC,EAAE,GAAG,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC;IAC9D,MAAM,SAAS,GAAG,4BAA4B,EAAE,CAAC;IACjD,MAAM,cAAc,GAAG,IAAI,uBAAuB,CAAC,QAAQ,CAAC,CAAC;IAE7D,MAAM,QAAQ,GAAG,IAAI,cAAc,CAAC;QAClC,UAAU,EAAE,CAAC,SAAS,EAAE,cAAc,CAAC;KACxC,CAAC,CAAC;IAEH,yEAAyE;IACzE,MAAM,UAAU,GAAG,QAAQ,CAAC,SAAS,CAAC,MAAM,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;IACnE,kBAAkB,CAAC,WAAW,EAAE,CAAC,mBAAmB,CAAC,UAAU,CAAC,CAAC;IAEjE,QAAQ,GAAG;QACT,SAAS,EAAE,CAAC,IAAa,EAAE,EAAE,CAC3B,QAAQ,CAAC,SAAS,CAAC,IAAI,IAAI,MAAM,CAAC,WAAW,EAAE,OAAO,CAAC;QACzD,QAAQ,EAAE,KAAK,IAAI,EAAE;YACnB,MAAM,QAAQ,CAAC,QAAQ,EAAE,CAAC;YAC1B,QAAQ,GAAG,SAAS,CAAC;QACvB,CAAC;KACF,CAAC;IAEF,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,gBAAgB;IAC9B,QAAQ,GAAG,SAAS,CAAC;AACvB,CAAC"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Browser Metrics Bootstrap
3
+ *
4
+ * Initializes a MeterProvider for browser contexts using OTLP HTTP export.
5
+ */
6
+ import { type Meter } from "@opentelemetry/api";
7
+ export interface BrowserMetricsInstance {
8
+ getMeter: (name?: string) => Meter;
9
+ shutdown: () => Promise<void>;
10
+ }
11
+ export interface BrowserMetricsConfig {
12
+ /** Full URL for metrics endpoint (e.g. "http://localhost:4318/v1/metrics") */
13
+ otlpUrl: string;
14
+ serviceName: string;
15
+ }
16
+ /**
17
+ * Initialize browser metrics with a MeterProvider that exports via OTLP HTTP.
18
+ *
19
+ * Uses CUMULATIVE aggregation temporality, matching the existing UI pattern.
20
+ *
21
+ * @param config - Browser metrics configuration
22
+ * @returns Browser metrics instance with getMeter and shutdown
23
+ */
24
+ export declare function initBrowserMetrics(config: BrowserMetricsConfig): BrowserMetricsInstance;
25
+ //# sourceMappingURL=metrics.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metrics.d.ts","sourceRoot":"","sources":["../../src/browser/metrics.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAW,KAAK,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAQzD,MAAM,WAAW,sBAAsB;IACrC,QAAQ,EAAE,CAAC,IAAI,CAAC,EAAE,MAAM,KAAK,KAAK,CAAC;IACnC,QAAQ,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC/B;AAED,MAAM,WAAW,oBAAoB;IACnC,8EAA8E;IAC9E,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,oBAAoB,GAC3B,sBAAsB,CAoBxB"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Browser Metrics Bootstrap
3
+ *
4
+ * Initializes a MeterProvider for browser contexts using OTLP HTTP export.
5
+ */
6
+ import { metrics } from "@opentelemetry/api";
7
+ import { OTLPMetricExporter } from "@opentelemetry/exporter-metrics-otlp-http";
8
+ import { AggregationTemporality, MeterProvider, PeriodicExportingMetricReader, } from "@opentelemetry/sdk-metrics";
9
+ /**
10
+ * Initialize browser metrics with a MeterProvider that exports via OTLP HTTP.
11
+ *
12
+ * Uses CUMULATIVE aggregation temporality, matching the existing UI pattern.
13
+ *
14
+ * @param config - Browser metrics configuration
15
+ * @returns Browser metrics instance with getMeter and shutdown
16
+ */
17
+ export function initBrowserMetrics(config) {
18
+ const exporter = new OTLPMetricExporter({
19
+ url: config.otlpUrl,
20
+ temporalityPreference: AggregationTemporality.CUMULATIVE,
21
+ });
22
+ const reader = new PeriodicExportingMetricReader({
23
+ exporter,
24
+ });
25
+ const provider = new MeterProvider({
26
+ readers: [reader],
27
+ });
28
+ metrics.setGlobalMeterProvider(provider);
29
+ return {
30
+ getMeter: (name) => provider.getMeter(name ?? config.serviceName),
31
+ shutdown: () => provider.shutdown(),
32
+ };
33
+ }
34
+ //# sourceMappingURL=metrics.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metrics.js","sourceRoot":"","sources":["../../src/browser/metrics.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,OAAO,EAAc,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,kBAAkB,EAAE,MAAM,2CAA2C,CAAC;AAC/E,OAAO,EACL,sBAAsB,EACtB,aAAa,EACb,6BAA6B,GAC9B,MAAM,4BAA4B,CAAC;AAapC;;;;;;;GAOG;AACH,MAAM,UAAU,kBAAkB,CAChC,MAA4B;IAE5B,MAAM,QAAQ,GAAG,IAAI,kBAAkB,CAAC;QACtC,GAAG,EAAE,MAAM,CAAC,OAAO;QACnB,qBAAqB,EAAE,sBAAsB,CAAC,UAAU;KACzD,CAAC,CAAC;IAEH,MAAM,MAAM,GAAG,IAAI,6BAA6B,CAAC;QAC/C,QAAQ;KACT,CAAC,CAAC;IAEH,MAAM,QAAQ,GAAG,IAAI,aAAa,CAAC;QACjC,OAAO,EAAE,CAAC,MAAM,CAAC;KAClB,CAAC,CAAC;IAEH,OAAO,CAAC,sBAAsB,CAAC,QAAQ,CAAC,CAAC;IAEzC,OAAO;QACL,QAAQ,EAAE,CAAC,IAAa,EAAE,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,IAAI,MAAM,CAAC,WAAW,CAAC;QAC1E,QAAQ,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE;KACpC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Browser PII Sanitizing Processors
3
+ *
4
+ * Span and log processors that redact PII before export from the browser.
5
+ * Browser telemetry always runs in untrusted context, so aggressive sanitization
6
+ * is applied unconditionally.
7
+ *
8
+ * - SanitizingSpanProcessor: redacts sensitive span attributes and strips
9
+ * sensitive query params from URL attributes.
10
+ * - SanitizingLogProcessor: redacts sensitive log record attributes and
11
+ * replaces email-like patterns in log body text.
12
+ */
13
+ import type { LogRecordProcessor } from "@opentelemetry/sdk-logs";
14
+ import type { SpanProcessor } from "@opentelemetry/sdk-trace-base";
15
+ export interface SanitizingConfig {
16
+ /** Additional attribute key patterns to redact */
17
+ additionalKeyPatterns?: RegExp[];
18
+ /** Additional URL param names to strip */
19
+ additionalSensitiveParams?: string[];
20
+ }
21
+ /**
22
+ * Create a SpanProcessor that redacts PII from span attributes before export.
23
+ *
24
+ * @param config - Optional configuration for additional key patterns / URL params
25
+ * @returns A SpanProcessor suitable for use in a browser WebTracerProvider
26
+ */
27
+ export declare function createSanitizingSpanProcessor(config?: SanitizingConfig): SpanProcessor;
28
+ /**
29
+ * Create a LogRecordProcessor that redacts PII from log records before export.
30
+ *
31
+ * @param config - Optional configuration for additional key patterns
32
+ * @returns A LogRecordProcessor suitable for use in a browser log provider
33
+ */
34
+ export declare function createSanitizingLogProcessor(config?: SanitizingConfig): LogRecordProcessor;
35
+ //# sourceMappingURL=sanitizer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sanitizer.d.ts","sourceRoot":"","sources":["../../src/browser/sanitizer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAGH,OAAO,KAAK,EAEV,kBAAkB,EACnB,MAAM,yBAAyB,CAAC;AACjC,OAAO,KAAK,EAGV,aAAa,EACd,MAAM,+BAA+B,CAAC;AAwDvC,MAAM,WAAW,gBAAgB;IAC/B,kDAAkD;IAClD,qBAAqB,CAAC,EAAE,MAAM,EAAE,CAAC;IACjC,0CAA0C;IAC1C,yBAAyB,CAAC,EAAE,MAAM,EAAE,CAAC;CACtC;AAsKD;;;;;GAKG;AACH,wBAAgB,6BAA6B,CAC3C,MAAM,CAAC,EAAE,gBAAgB,GACxB,aAAa,CAEf;AAED;;;;;GAKG;AACH,wBAAgB,4BAA4B,CAC1C,MAAM,CAAC,EAAE,gBAAgB,GACxB,kBAAkB,CAEpB"}
@@ -0,0 +1,207 @@
1
+ /**
2
+ * Browser PII Sanitizing Processors
3
+ *
4
+ * Span and log processors that redact PII before export from the browser.
5
+ * Browser telemetry always runs in untrusted context, so aggressive sanitization
6
+ * is applied unconditionally.
7
+ *
8
+ * - SanitizingSpanProcessor: redacts sensitive span attributes and strips
9
+ * sensitive query params from URL attributes.
10
+ * - SanitizingLogProcessor: redacts sensitive log record attributes and
11
+ * replaces email-like patterns in log body text.
12
+ */
13
+ // ============================================================================
14
+ // Constants
15
+ // ============================================================================
16
+ const REDACTED = "[REDACTED]";
17
+ const REDACTED_EMAIL = "[REDACTED_EMAIL]";
18
+ /**
19
+ * Attribute key substrings that indicate sensitive values.
20
+ * Case-insensitive matching is applied.
21
+ */
22
+ const SENSITIVE_KEY_SUBSTRINGS = [
23
+ "email",
24
+ "token",
25
+ "secret",
26
+ "password",
27
+ "authorization",
28
+ "cookie",
29
+ "credential",
30
+ ];
31
+ /**
32
+ * Attribute key patterns (regex) for additional well-known sensitive keys
33
+ * not covered by simple substring matching (e.g. api_key, x-api-key).
34
+ */
35
+ const SENSITIVE_KEY_PATTERNS = [
36
+ /api[_\-.]?key/i,
37
+ /x[_\-.]?api[_\-.]?key/i,
38
+ ];
39
+ /**
40
+ * URL query parameter names that should be stripped.
41
+ * Exact (case-insensitive) match against param name.
42
+ */
43
+ const SENSITIVE_URL_PARAMS = [
44
+ "token",
45
+ "key",
46
+ "secret",
47
+ "password",
48
+ "code",
49
+ "state",
50
+ "auth",
51
+ ];
52
+ /** URL attribute keys that receive query-param sanitization. */
53
+ const URL_ATTRIBUTE_KEYS = new Set(["http.url", "url.full"]);
54
+ /** Regex matching email-like patterns in log body text. */
55
+ const EMAIL_PATTERN = /[\w.+-]+@[\w.-]+(\.\w+)?/g;
56
+ // ============================================================================
57
+ // Helpers
58
+ // ============================================================================
59
+ /**
60
+ * Returns true if the attribute key is sensitive and its value should be
61
+ * replaced with [REDACTED].
62
+ */
63
+ function isSensitiveKey(key, additionalPatterns) {
64
+ const lower = key.toLowerCase();
65
+ for (const substr of SENSITIVE_KEY_SUBSTRINGS) {
66
+ if (lower.includes(substr)) {
67
+ return true;
68
+ }
69
+ }
70
+ for (const pattern of SENSITIVE_KEY_PATTERNS) {
71
+ pattern.lastIndex = 0;
72
+ if (pattern.test(key)) {
73
+ return true;
74
+ }
75
+ }
76
+ for (const pattern of additionalPatterns) {
77
+ pattern.lastIndex = 0;
78
+ if (pattern.test(key)) {
79
+ return true;
80
+ }
81
+ }
82
+ return false;
83
+ }
84
+ /**
85
+ * Strips sensitive query parameters from a URL string.
86
+ * Sensitive param values are replaced with [REDACTED] (key is preserved).
87
+ */
88
+ function sanitizeUrl(url, additionalParams) {
89
+ const qIdx = url.indexOf("?");
90
+ if (qIdx === -1) {
91
+ return url;
92
+ }
93
+ const base = url.slice(0, qIdx);
94
+ const query = url.slice(qIdx + 1);
95
+ const sensitiveSet = new Set([
96
+ ...SENSITIVE_URL_PARAMS.map((p) => p.toLowerCase()),
97
+ ...additionalParams.map((p) => p.toLowerCase()),
98
+ ]);
99
+ const sanitizedParts = query.split("&").map((part) => {
100
+ const eqIdx = part.indexOf("=");
101
+ if (eqIdx === -1) {
102
+ return part;
103
+ }
104
+ const rawParamName = part.slice(0, eqIdx);
105
+ let paramName;
106
+ try {
107
+ paramName = decodeURIComponent(rawParamName).toLowerCase();
108
+ }
109
+ catch {
110
+ paramName = rawParamName.toLowerCase();
111
+ }
112
+ if (sensitiveSet.has(paramName)) {
113
+ return `${part.slice(0, eqIdx)}=${REDACTED}`;
114
+ }
115
+ return part;
116
+ });
117
+ return `${base}?${sanitizedParts.join("&")}`;
118
+ }
119
+ /**
120
+ * Sanitizes span/log attributes in-place. Sensitive keys get value [REDACTED];
121
+ * URL attributes get query-param sanitization.
122
+ */
123
+ function sanitizeAttributes(attributes, additionalKeyPatterns, additionalSensitiveParams) {
124
+ for (const key of Object.keys(attributes)) {
125
+ if (URL_ATTRIBUTE_KEYS.has(key)) {
126
+ const val = attributes[key];
127
+ if (typeof val === "string") {
128
+ attributes[key] = sanitizeUrl(val, additionalSensitiveParams);
129
+ }
130
+ // URL attributes are handled; skip further key-based check
131
+ continue;
132
+ }
133
+ if (isSensitiveKey(key, additionalKeyPatterns)) {
134
+ attributes[key] = REDACTED;
135
+ }
136
+ }
137
+ }
138
+ // ============================================================================
139
+ // SanitizingSpanProcessor
140
+ // ============================================================================
141
+ class SanitizingSpanProcessor {
142
+ additionalKeyPatterns;
143
+ additionalSensitiveParams;
144
+ constructor(config = {}) {
145
+ this.additionalKeyPatterns = config.additionalKeyPatterns ?? [];
146
+ this.additionalSensitiveParams = config.additionalSensitiveParams ?? [];
147
+ }
148
+ onStart(_span, _parentContext) {
149
+ // Nothing to do at start; sanitization occurs at end when attributes are final.
150
+ }
151
+ onEnd(span) {
152
+ // ReadableSpan.attributes is typed as Attributes (readonly in API), but
153
+ // in practice the SDK implementation uses a mutable object. We cast to
154
+ // allow in-place mutation, which avoids allocating a new span wrapper.
155
+ const attrs = span.attributes;
156
+ sanitizeAttributes(attrs, this.additionalKeyPatterns, this.additionalSensitiveParams);
157
+ }
158
+ async shutdown() { }
159
+ async forceFlush() { }
160
+ }
161
+ // ============================================================================
162
+ // SanitizingLogProcessor
163
+ // ============================================================================
164
+ class BrowserSanitizingLogProcessor {
165
+ additionalKeyPatterns;
166
+ constructor(config = {}) {
167
+ this.additionalKeyPatterns = config.additionalKeyPatterns ?? [];
168
+ }
169
+ onEmit(record, _context) {
170
+ // Sanitize attributes in-place
171
+ const attrs = record.attributes;
172
+ for (const key of Object.keys(attrs)) {
173
+ if (isSensitiveKey(key, this.additionalKeyPatterns)) {
174
+ attrs[key] = REDACTED;
175
+ }
176
+ }
177
+ // Redact email-like patterns in string body
178
+ if (typeof record.body === "string") {
179
+ EMAIL_PATTERN.lastIndex = 0;
180
+ record.body = record.body.replace(EMAIL_PATTERN, REDACTED_EMAIL);
181
+ }
182
+ }
183
+ async shutdown() { }
184
+ async forceFlush() { }
185
+ }
186
+ // ============================================================================
187
+ // Factory functions
188
+ // ============================================================================
189
+ /**
190
+ * Create a SpanProcessor that redacts PII from span attributes before export.
191
+ *
192
+ * @param config - Optional configuration for additional key patterns / URL params
193
+ * @returns A SpanProcessor suitable for use in a browser WebTracerProvider
194
+ */
195
+ export function createSanitizingSpanProcessor(config) {
196
+ return new SanitizingSpanProcessor(config);
197
+ }
198
+ /**
199
+ * Create a LogRecordProcessor that redacts PII from log records before export.
200
+ *
201
+ * @param config - Optional configuration for additional key patterns
202
+ * @returns A LogRecordProcessor suitable for use in a browser log provider
203
+ */
204
+ export function createSanitizingLogProcessor(config) {
205
+ return new BrowserSanitizingLogProcessor(config);
206
+ }
207
+ //# sourceMappingURL=sanitizer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sanitizer.js","sourceRoot":"","sources":["../../src/browser/sanitizer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,102 @@
1
+ /**
2
+ * Browser-side TracedSocket for WebSocket tracing.
3
+ *
4
+ * Wraps a WebSocket client (or any WebSocket-like object) and adds
5
+ * OpenTelemetry tracing. Designed to speak the same envelope protocol as the
6
+ * server-side TracedSocket so that distributed traces link correctly across
7
+ * the browser–server boundary.
8
+ *
9
+ * Envelope format (matches @superblocksteam/shared SocketRequest):
10
+ * outbound: { request: { method, id, traceparent?, tracestate?, ... } }
11
+ * inbound: { request: { method, id, traceparent?, tracestate?, ... } }
12
+ * { response: { id, ... } }
13
+ *
14
+ * Propagation uses the W3C Trace Context propagator registered globally by
15
+ * initBrowserTelemetry() (see browser/init.ts). The carrier is the
16
+ * `request` object itself — the same convention as the server side.
17
+ */
18
+ import { type Tracer } from "@opentelemetry/api";
19
+ import type { SocketMessageEnvelope } from "../common/traced-socket-types.js";
20
+ /** Minimal browser WebSocket surface needed by BrowserTracedSocket. */
21
+ export interface WebSocketLike {
22
+ readonly readyState: number;
23
+ close(code?: number, reason?: string): void;
24
+ send(data: string | ArrayBuffer): void;
25
+ addEventListener(type: string, listener: (event: unknown) => void): void;
26
+ removeEventListener(type: string, listener: (event: unknown) => void): void;
27
+ }
28
+ /** Configuration for BrowserTracedSocket. */
29
+ export interface BrowserTracedSocketConfig {
30
+ /**
31
+ * Tracer instance. When omitted the global tracer named
32
+ * "superblocks-ws" is used (requires initBrowserTelemetry() first).
33
+ */
34
+ tracer?: Tracer;
35
+ }
36
+ /**
37
+ * BrowserTracedSocket wraps a WebSocket and provides:
38
+ *
39
+ * 1. `decorateOutbound(msg)` — call this before sending any message.
40
+ * Injects traceparent/tracestate into msg.request so the server can
41
+ * extract the browser's active context.
42
+ *
43
+ * 2. `traceOutboundCall(method)` — wraps a client-initiated RPC call in a
44
+ * CLIENT span. Returns the span's end function.
45
+ *
46
+ * 3. `handleInbound(msg)` — call this when a message arrives from the server.
47
+ * Extracts the server's trace context and creates a SERVER span so that
48
+ * server-initiated pushes appear in the browser's trace.
49
+ *
50
+ * 4. `recordReconnect({ attempt })` — call this from the reconnect loop to
51
+ * create a ws.reconnect span.
52
+ *
53
+ * Lifecycle spans (ws.connect, ws.disconnect) are attached automatically via
54
+ * WebSocket open/close event listeners.
55
+ */
56
+ export declare class BrowserTracedSocket {
57
+ private readonly ws;
58
+ private readonly tracer;
59
+ private connectStartTime;
60
+ constructor(ws: WebSocketLike, config: BrowserTracedSocketConfig);
61
+ private readonly onOpen;
62
+ private readonly onClose;
63
+ /**
64
+ * Records a ws.reconnect span. Call this from the reconnect loop just
65
+ * before opening a new WebSocket, passing the attempt counter so it shows
66
+ * up as a span attribute.
67
+ */
68
+ recordReconnect({ attempt }: {
69
+ attempt: number;
70
+ }): void;
71
+ /**
72
+ * Injects W3C trace context into the message's request envelope.
73
+ * Call this on every outbound message before handing it to the transport.
74
+ *
75
+ * Mirrors the server-side TracedSocket.decorateToSend() behaviour so that
76
+ * the server can extract the browser's active context via propagation.extract.
77
+ */
78
+ decorateOutbound(message: SocketMessageEnvelope): SocketMessageEnvelope;
79
+ /**
80
+ * Creates a CLIENT span for a browser-initiated RPC call.
81
+ * Returns the span so the caller can end it after the response resolves.
82
+ *
83
+ * Usage:
84
+ * ```typescript
85
+ * const span = socket.traceOutboundCall("editor.runApi");
86
+ * const result = await socket.request("editor.runApi", params);
87
+ * span.end();
88
+ * ```
89
+ */
90
+ traceOutboundCall(method: string): import("@opentelemetry/api").Span;
91
+ /**
92
+ * Handles an inbound message from the server.
93
+ * - Extracts the server's trace context from the request envelope.
94
+ * - Creates a SERVER span as a child of the server's trace so that
95
+ * server-initiated pushes appear in the browser's distributed trace.
96
+ * - Response-only messages (no request field) are ignored.
97
+ */
98
+ handleInbound(message: SocketMessageEnvelope): void;
99
+ /** Remove lifecycle listeners. Call when tearing down the socket. */
100
+ dispose(): void;
101
+ }
102
+ //# sourceMappingURL=traced-socket.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"traced-socket.d.ts","sourceRoot":"","sources":["../../src/browser/traced-socket.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAML,KAAK,MAAM,EACZ,MAAM,oBAAoB,CAAC;AAM5B,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,kCAAkC,CAAC;AAE9E,uEAAuE;AACvE,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5C,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI,CAAC;IACvC,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,GAAG,IAAI,CAAC;IACzE,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,GAAG,IAAI,CAAC;CAC7E;AAED,6CAA6C;AAC7C,MAAM,WAAW,yBAAyB;IACxC;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAOD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,qBAAa,mBAAmB;IAK5B,OAAO,CAAC,QAAQ,CAAC,EAAE;IAJrB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,gBAAgB,CAAqB;gBAG1B,EAAE,EAAE,aAAa,EAClC,MAAM,EAAE,yBAAyB;IAYnC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAoBrB;IAEF,OAAO,CAAC,QAAQ,CAAC,OAAO,CAmBtB;IAEF;;;;OAIG;IACI,eAAe,CAAC,EAAE,OAAO,EAAE,EAAE;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;IAoB9D;;;;;;OAMG;IACI,gBAAgB,CACrB,OAAO,EAAE,qBAAqB,GAC7B,qBAAqB;IAexB;;;;;;;;;;OAUG;IACI,iBAAiB,CAAC,MAAM,EAAE,MAAM;IAkBvC;;;;;;OAMG;IACI,aAAa,CAAC,OAAO,EAAE,qBAAqB,GAAG,IAAI;IAgC1D,qEAAqE;IAC9D,OAAO,IAAI,IAAI;CAIvB"}