@tracelog/lib 2.1.2 → 2.2.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.
@@ -443,6 +443,12 @@ interface Config {
443
443
  collectApiUrl: string;
444
444
  /** Allow HTTP URLs (not recommended for production). @default false */
445
445
  allowHttp?: boolean;
446
+ /**
447
+ * Static HTTP headers to include in every request.
448
+ * For dynamic headers, use `setCustomHeaders()` instead.
449
+ * @example { 'X-Brand': 'my-brand', 'X-Tenant-Id': 'tenant-123' }
450
+ */
451
+ headers?: Record<string, string>;
446
452
  };
447
453
  };
448
454
  }
@@ -1238,8 +1244,10 @@ declare class EventManager extends StateManager {
1238
1244
  * @param storeManager - Storage manager for persistence
1239
1245
  * @param emitter - Optional event emitter for local event consumption
1240
1246
  * @param transformers - Optional event transformation hooks
1247
+ * @param staticHeaders - Optional static HTTP headers for custom backend (from config)
1248
+ * @param customHeadersProvider - Optional callback for dynamic headers
1241
1249
  */
1242
- constructor(storeManager: StorageManager, emitter?: Emitter | null, transformers?: TransformerMap);
1250
+ constructor(storeManager: StorageManager, emitter?: Emitter | null, transformers?: TransformerMap, staticHeaders?: Record<string, string>, customHeadersProvider?: CustomHeadersProvider);
1243
1251
  /**
1244
1252
  * Recovers persisted events from localStorage after a crash or page reload.
1245
1253
  *
@@ -1430,6 +1438,17 @@ declare class EventManager extends StateManager {
1430
1438
  * @see src/managers/README.md (lines 5-75) for flush details
1431
1439
  */
1432
1440
  flushImmediatelySync(): boolean;
1441
+ /**
1442
+ * Sets the custom headers provider callback for the custom integration.
1443
+ * Only affects requests to custom backend (not TraceLog SaaS).
1444
+ *
1445
+ * @param provider - Callback function that returns custom headers
1446
+ */
1447
+ setCustomHeadersProvider(provider: CustomHeadersProvider): void;
1448
+ /**
1449
+ * Removes the custom headers provider callback from the custom integration.
1450
+ */
1451
+ removeCustomHeadersProvider(): void;
1433
1452
  /**
1434
1453
  * Returns the current number of events in the main queue.
1435
1454
  *
@@ -2236,6 +2255,26 @@ interface TransformerMap {
2236
2255
  beforeSend?: BeforeSendTransformer;
2237
2256
  beforeBatch?: BeforeBatchTransformer;
2238
2257
  }
2258
+ /**
2259
+ * Callback function for providing dynamic HTTP headers.
2260
+ *
2261
+ * Called synchronously before each fetch request to custom backends.
2262
+ * Return empty object {} to send no custom headers.
2263
+ *
2264
+ * **Note**: Only applies to `custom` integration (not TraceLog SaaS).
2265
+ * Headers are NOT applied to sendBeacon requests (page unload).
2266
+ *
2267
+ * @returns Record of header names to values
2268
+ *
2269
+ * @example
2270
+ * ```typescript
2271
+ * tracelog.setCustomHeaders(() => ({
2272
+ * 'Authorization': `Bearer ${getAuthToken()}`,
2273
+ * 'X-Request-ID': crypto.randomUUID()
2274
+ * }));
2275
+ * ```
2276
+ */
2277
+ type CustomHeadersProvider = () => Record<string, string>;
2239
2278
 
2240
2279
  /**
2241
2280
  * Testing bridge interface for E2E and integration tests
@@ -2267,6 +2306,8 @@ interface TraceLogTestBridge {
2267
2306
  setTransformer(hook: 'beforeBatch', fn: BeforeBatchTransformer): void;
2268
2307
  setTransformer(hook: TransformerHook, fn: BeforeSendTransformer | BeforeBatchTransformer): void;
2269
2308
  removeTransformer(hook: TransformerHook): void;
2309
+ setCustomHeaders(provider: CustomHeadersProvider): void;
2310
+ removeCustomHeaders(): void;
2270
2311
  getEventManager(): EventManager | undefined;
2271
2312
  getStorageManager(): StorageManager | null;
2272
2313
  getPerformanceHandler(): PerformanceHandler | null;
@@ -2440,6 +2481,8 @@ declare const tracelog: {
2440
2481
  off: <K extends keyof EmitterMap>(event: K, callback: EmitterCallback<EmitterMap[K]>) => void;
2441
2482
  setTransformer: typeof setTransformer;
2442
2483
  removeTransformer: (hook: TransformerHook) => void;
2484
+ setCustomHeaders: (provider: CustomHeadersProvider) => void;
2485
+ removeCustomHeaders: () => void;
2443
2486
  isInitialized: () => boolean;
2444
2487
  destroy: () => void;
2445
2488
  setQaMode: (enabled: boolean) => void;
@@ -2447,4 +2490,4 @@ declare const tracelog: {
2447
2490
  mergeGlobalMetadata: (metadata: Record<string, MetadataType>) => void;
2448
2491
  };
2449
2492
 
2450
- export { AppConfigValidationError, type BeforeBatchTransformer, type BeforeSendTransformer, type ClickCoordinates, type ClickData, type ClickTrackingElementData, type Config, type CustomEventData, DEFAULT_SESSION_TIMEOUT, DEFAULT_WEB_VITALS_MODE, type DeviceInfo, DeviceType, type EmitterCallback, EmitterEvent, type EmitterMap, type ErrorData, ErrorType, type EventData, EventType, type EventTypeName, type EventsQueue, InitializationTimeoutError, IntegrationValidationError, MAX_ARRAY_LENGTH, MAX_CUSTOM_EVENT_ARRAY_SIZE, MAX_CUSTOM_EVENT_KEYS, MAX_CUSTOM_EVENT_NAME_LENGTH, MAX_CUSTOM_EVENT_STRING_SIZE, MAX_METADATA_NESTING_DEPTH, MAX_NESTED_OBJECT_KEYS, MAX_STRING_LENGTH, MAX_STRING_LENGTH_IN_ARRAY, type MetadataType, Mode, PII_PATTERNS, type PageViewData, PermanentError, type PersistedEventsQueue, type PrimaryScrollEvent, SamplingRateValidationError, type ScrollData, ScrollDirection, type SecondaryScrollEvent, type SessionEventCounts, SessionTimeoutValidationError, SpecialApiUrl, type State, type TraceLogTestBridge, TraceLogValidationError, type TransformerHook, type TransformerMap, type UTM, type ViewportConfig, type ViewportElement, type ViewportEventData, WEB_VITALS_GOOD_THRESHOLDS, WEB_VITALS_NEEDS_IMPROVEMENT_THRESHOLDS, WEB_VITALS_POOR_THRESHOLDS, type WebVitalType, type WebVitalsData, type WebVitalsMode, getWebVitalsThresholds, isPrimaryScrollEvent, isSecondaryScrollEvent, tracelog };
2493
+ export { AppConfigValidationError, type BeforeBatchTransformer, type BeforeSendTransformer, type ClickCoordinates, type ClickData, type ClickTrackingElementData, type Config, type CustomEventData, type CustomHeadersProvider, DEFAULT_SESSION_TIMEOUT, DEFAULT_WEB_VITALS_MODE, type DeviceInfo, DeviceType, type EmitterCallback, EmitterEvent, type EmitterMap, type ErrorData, ErrorType, type EventData, EventType, type EventTypeName, type EventsQueue, InitializationTimeoutError, IntegrationValidationError, MAX_ARRAY_LENGTH, MAX_CUSTOM_EVENT_ARRAY_SIZE, MAX_CUSTOM_EVENT_KEYS, MAX_CUSTOM_EVENT_NAME_LENGTH, MAX_CUSTOM_EVENT_STRING_SIZE, MAX_METADATA_NESTING_DEPTH, MAX_NESTED_OBJECT_KEYS, MAX_STRING_LENGTH, MAX_STRING_LENGTH_IN_ARRAY, type MetadataType, Mode, PII_PATTERNS, type PageViewData, PermanentError, type PersistedEventsQueue, type PrimaryScrollEvent, SamplingRateValidationError, type ScrollData, ScrollDirection, type SecondaryScrollEvent, type SessionEventCounts, SessionTimeoutValidationError, SpecialApiUrl, type State, type TraceLogTestBridge, TraceLogValidationError, type TransformerHook, type TransformerMap, type UTM, type ViewportConfig, type ViewportElement, type ViewportEventData, WEB_VITALS_GOOD_THRESHOLDS, WEB_VITALS_NEEDS_IMPROVEMENT_THRESHOLDS, WEB_VITALS_POOR_THRESHOLDS, type WebVitalType, type WebVitalsData, type WebVitalsMode, getWebVitalsThresholds, isPrimaryScrollEvent, isSecondaryScrollEvent, tracelog };
@@ -443,6 +443,12 @@ interface Config {
443
443
  collectApiUrl: string;
444
444
  /** Allow HTTP URLs (not recommended for production). @default false */
445
445
  allowHttp?: boolean;
446
+ /**
447
+ * Static HTTP headers to include in every request.
448
+ * For dynamic headers, use `setCustomHeaders()` instead.
449
+ * @example { 'X-Brand': 'my-brand', 'X-Tenant-Id': 'tenant-123' }
450
+ */
451
+ headers?: Record<string, string>;
446
452
  };
447
453
  };
448
454
  }
@@ -1238,8 +1244,10 @@ declare class EventManager extends StateManager {
1238
1244
  * @param storeManager - Storage manager for persistence
1239
1245
  * @param emitter - Optional event emitter for local event consumption
1240
1246
  * @param transformers - Optional event transformation hooks
1247
+ * @param staticHeaders - Optional static HTTP headers for custom backend (from config)
1248
+ * @param customHeadersProvider - Optional callback for dynamic headers
1241
1249
  */
1242
- constructor(storeManager: StorageManager, emitter?: Emitter | null, transformers?: TransformerMap);
1250
+ constructor(storeManager: StorageManager, emitter?: Emitter | null, transformers?: TransformerMap, staticHeaders?: Record<string, string>, customHeadersProvider?: CustomHeadersProvider);
1243
1251
  /**
1244
1252
  * Recovers persisted events from localStorage after a crash or page reload.
1245
1253
  *
@@ -1430,6 +1438,17 @@ declare class EventManager extends StateManager {
1430
1438
  * @see src/managers/README.md (lines 5-75) for flush details
1431
1439
  */
1432
1440
  flushImmediatelySync(): boolean;
1441
+ /**
1442
+ * Sets the custom headers provider callback for the custom integration.
1443
+ * Only affects requests to custom backend (not TraceLog SaaS).
1444
+ *
1445
+ * @param provider - Callback function that returns custom headers
1446
+ */
1447
+ setCustomHeadersProvider(provider: CustomHeadersProvider): void;
1448
+ /**
1449
+ * Removes the custom headers provider callback from the custom integration.
1450
+ */
1451
+ removeCustomHeadersProvider(): void;
1433
1452
  /**
1434
1453
  * Returns the current number of events in the main queue.
1435
1454
  *
@@ -2236,6 +2255,26 @@ interface TransformerMap {
2236
2255
  beforeSend?: BeforeSendTransformer;
2237
2256
  beforeBatch?: BeforeBatchTransformer;
2238
2257
  }
2258
+ /**
2259
+ * Callback function for providing dynamic HTTP headers.
2260
+ *
2261
+ * Called synchronously before each fetch request to custom backends.
2262
+ * Return empty object {} to send no custom headers.
2263
+ *
2264
+ * **Note**: Only applies to `custom` integration (not TraceLog SaaS).
2265
+ * Headers are NOT applied to sendBeacon requests (page unload).
2266
+ *
2267
+ * @returns Record of header names to values
2268
+ *
2269
+ * @example
2270
+ * ```typescript
2271
+ * tracelog.setCustomHeaders(() => ({
2272
+ * 'Authorization': `Bearer ${getAuthToken()}`,
2273
+ * 'X-Request-ID': crypto.randomUUID()
2274
+ * }));
2275
+ * ```
2276
+ */
2277
+ type CustomHeadersProvider = () => Record<string, string>;
2239
2278
 
2240
2279
  /**
2241
2280
  * Testing bridge interface for E2E and integration tests
@@ -2267,6 +2306,8 @@ interface TraceLogTestBridge {
2267
2306
  setTransformer(hook: 'beforeBatch', fn: BeforeBatchTransformer): void;
2268
2307
  setTransformer(hook: TransformerHook, fn: BeforeSendTransformer | BeforeBatchTransformer): void;
2269
2308
  removeTransformer(hook: TransformerHook): void;
2309
+ setCustomHeaders(provider: CustomHeadersProvider): void;
2310
+ removeCustomHeaders(): void;
2270
2311
  getEventManager(): EventManager | undefined;
2271
2312
  getStorageManager(): StorageManager | null;
2272
2313
  getPerformanceHandler(): PerformanceHandler | null;
@@ -2440,6 +2481,8 @@ declare const tracelog: {
2440
2481
  off: <K extends keyof EmitterMap>(event: K, callback: EmitterCallback<EmitterMap[K]>) => void;
2441
2482
  setTransformer: typeof setTransformer;
2442
2483
  removeTransformer: (hook: TransformerHook) => void;
2484
+ setCustomHeaders: (provider: CustomHeadersProvider) => void;
2485
+ removeCustomHeaders: () => void;
2443
2486
  isInitialized: () => boolean;
2444
2487
  destroy: () => void;
2445
2488
  setQaMode: (enabled: boolean) => void;
@@ -2447,4 +2490,4 @@ declare const tracelog: {
2447
2490
  mergeGlobalMetadata: (metadata: Record<string, MetadataType>) => void;
2448
2491
  };
2449
2492
 
2450
- export { AppConfigValidationError, type BeforeBatchTransformer, type BeforeSendTransformer, type ClickCoordinates, type ClickData, type ClickTrackingElementData, type Config, type CustomEventData, DEFAULT_SESSION_TIMEOUT, DEFAULT_WEB_VITALS_MODE, type DeviceInfo, DeviceType, type EmitterCallback, EmitterEvent, type EmitterMap, type ErrorData, ErrorType, type EventData, EventType, type EventTypeName, type EventsQueue, InitializationTimeoutError, IntegrationValidationError, MAX_ARRAY_LENGTH, MAX_CUSTOM_EVENT_ARRAY_SIZE, MAX_CUSTOM_EVENT_KEYS, MAX_CUSTOM_EVENT_NAME_LENGTH, MAX_CUSTOM_EVENT_STRING_SIZE, MAX_METADATA_NESTING_DEPTH, MAX_NESTED_OBJECT_KEYS, MAX_STRING_LENGTH, MAX_STRING_LENGTH_IN_ARRAY, type MetadataType, Mode, PII_PATTERNS, type PageViewData, PermanentError, type PersistedEventsQueue, type PrimaryScrollEvent, SamplingRateValidationError, type ScrollData, ScrollDirection, type SecondaryScrollEvent, type SessionEventCounts, SessionTimeoutValidationError, SpecialApiUrl, type State, type TraceLogTestBridge, TraceLogValidationError, type TransformerHook, type TransformerMap, type UTM, type ViewportConfig, type ViewportElement, type ViewportEventData, WEB_VITALS_GOOD_THRESHOLDS, WEB_VITALS_NEEDS_IMPROVEMENT_THRESHOLDS, WEB_VITALS_POOR_THRESHOLDS, type WebVitalType, type WebVitalsData, type WebVitalsMode, getWebVitalsThresholds, isPrimaryScrollEvent, isSecondaryScrollEvent, tracelog };
2493
+ export { AppConfigValidationError, type BeforeBatchTransformer, type BeforeSendTransformer, type ClickCoordinates, type ClickData, type ClickTrackingElementData, type Config, type CustomEventData, type CustomHeadersProvider, DEFAULT_SESSION_TIMEOUT, DEFAULT_WEB_VITALS_MODE, type DeviceInfo, DeviceType, type EmitterCallback, EmitterEvent, type EmitterMap, type ErrorData, ErrorType, type EventData, EventType, type EventTypeName, type EventsQueue, InitializationTimeoutError, IntegrationValidationError, MAX_ARRAY_LENGTH, MAX_CUSTOM_EVENT_ARRAY_SIZE, MAX_CUSTOM_EVENT_KEYS, MAX_CUSTOM_EVENT_NAME_LENGTH, MAX_CUSTOM_EVENT_STRING_SIZE, MAX_METADATA_NESTING_DEPTH, MAX_NESTED_OBJECT_KEYS, MAX_STRING_LENGTH, MAX_STRING_LENGTH_IN_ARRAY, type MetadataType, Mode, PII_PATTERNS, type PageViewData, PermanentError, type PersistedEventsQueue, type PrimaryScrollEvent, SamplingRateValidationError, type ScrollData, ScrollDirection, type SecondaryScrollEvent, type SessionEventCounts, SessionTimeoutValidationError, SpecialApiUrl, type State, type TraceLogTestBridge, TraceLogValidationError, type TransformerHook, type TransformerMap, type UTM, type ViewportConfig, type ViewportElement, type ViewportEventData, WEB_VITALS_GOOD_THRESHOLDS, WEB_VITALS_NEEDS_IMPROVEMENT_THRESHOLDS, WEB_VITALS_POOR_THRESHOLDS, type WebVitalType, type WebVitalsData, type WebVitalsMode, getWebVitalsThresholds, isPrimaryScrollEvent, isSecondaryScrollEvent, tracelog };
@@ -556,7 +556,7 @@ var LONG_TASK_THROTTLE_MS = 1e3;
556
556
  var MAX_NAVIGATION_HISTORY = 50;
557
557
 
558
558
  // package.json
559
- var version = "2.1.1";
559
+ var version = "2.1.2";
560
560
 
561
561
  // src/constants/version.constants.ts
562
562
  var LIB_VERSION = version;
@@ -1585,6 +1585,8 @@ var SenderManager = class extends StateManager {
1585
1585
  integrationId;
1586
1586
  apiUrl;
1587
1587
  transformers;
1588
+ staticHeaders;
1589
+ customHeadersProvider;
1588
1590
  lastPermanentErrorLog = null;
1589
1591
  recoveryInProgress = false;
1590
1592
  lastMetadataTimestamp = 0;
@@ -1599,9 +1601,11 @@ var SenderManager = class extends StateManager {
1599
1601
  * @param integrationId - Optional integration identifier ('saas' or 'custom')
1600
1602
  * @param apiUrl - Optional API endpoint URL
1601
1603
  * @param transformers - Optional event transformation hooks
1604
+ * @param staticHeaders - Optional static HTTP headers (from config)
1605
+ * @param customHeadersProvider - Optional callback for dynamic headers
1602
1606
  * @throws Error if integrationId and apiUrl are not both provided or both undefined
1603
1607
  */
1604
- constructor(storeManager, integrationId, apiUrl, transformers = {}) {
1608
+ constructor(storeManager, integrationId, apiUrl, transformers = {}, staticHeaders = {}, customHeadersProvider) {
1605
1609
  super();
1606
1610
  if (integrationId && !apiUrl || !integrationId && apiUrl) {
1607
1611
  throw new Error("SenderManager: integrationId and apiUrl must either both be provided or both be undefined");
@@ -1610,6 +1614,8 @@ var SenderManager = class extends StateManager {
1610
1614
  this.integrationId = integrationId;
1611
1615
  this.apiUrl = apiUrl;
1612
1616
  this.transformers = transformers;
1617
+ this.staticHeaders = staticHeaders;
1618
+ this.customHeadersProvider = customHeadersProvider;
1613
1619
  }
1614
1620
  /**
1615
1621
  * Get the integration ID for this sender
@@ -1618,6 +1624,49 @@ var SenderManager = class extends StateManager {
1618
1624
  getIntegrationId() {
1619
1625
  return this.integrationId;
1620
1626
  }
1627
+ /**
1628
+ * Sets the custom headers provider callback.
1629
+ * Only applies to 'custom' integration (ignored for 'saas').
1630
+ *
1631
+ * @param provider - Callback function that returns custom headers
1632
+ */
1633
+ setCustomHeadersProvider(provider) {
1634
+ this.customHeadersProvider = provider;
1635
+ }
1636
+ /**
1637
+ * Removes the custom headers provider callback.
1638
+ */
1639
+ removeCustomHeadersProvider() {
1640
+ this.customHeadersProvider = void 0;
1641
+ }
1642
+ /**
1643
+ * Builds custom headers by merging static headers with dynamic headers from provider.
1644
+ * Only applies to 'custom' integration (returns empty object for 'saas').
1645
+ *
1646
+ * @returns Merged custom headers object (dynamic headers override static)
1647
+ * @private
1648
+ */
1649
+ getCustomHeaders() {
1650
+ if (this.integrationId !== "custom") {
1651
+ return {};
1652
+ }
1653
+ let dynamicHeaders = {};
1654
+ if (this.customHeadersProvider) {
1655
+ try {
1656
+ const result = this.customHeadersProvider();
1657
+ if (typeof result === "object" && result !== null && !Array.isArray(result)) {
1658
+ dynamicHeaders = result;
1659
+ } else {
1660
+ log("warn", "Custom headers provider returned invalid value, expected object", {
1661
+ data: { received: typeof result }
1662
+ });
1663
+ }
1664
+ } catch (error) {
1665
+ log("warn", "Custom headers provider threw an error, using static headers only", { error });
1666
+ }
1667
+ }
1668
+ return { ...this.staticHeaders, ...dynamicHeaders };
1669
+ }
1621
1670
  getQueueStorageKey() {
1622
1671
  const userId = this.get("userId") || "anonymous";
1623
1672
  const baseKey = QUEUE_KEY(userId);
@@ -1645,6 +1694,11 @@ var SenderManager = class extends StateManager {
1645
1694
  *
1646
1695
  * **Important**: No retry mechanism for failures. Events are NOT persisted.
1647
1696
  *
1697
+ * **Custom Headers Limitation**: Custom headers set via `setCustomHeaders()` are NOT applied
1698
+ * to sendBeacon requests due to browser API limitations. The sendBeacon API only supports
1699
+ * Content-Type header via Blob. For scenarios requiring custom headers, ensure async
1700
+ * sends complete before page unload.
1701
+ *
1648
1702
  * @param body - Event queue to send
1649
1703
  * @returns `true` if send succeeded or was skipped, `false` if failed
1650
1704
  *
@@ -2067,6 +2121,7 @@ var SenderManager = class extends StateManager {
2067
2121
  controller.abort();
2068
2122
  }, REQUEST_TIMEOUT_MS);
2069
2123
  try {
2124
+ const customHeaders = this.getCustomHeaders();
2070
2125
  const response = await fetch(url, {
2071
2126
  method: "POST",
2072
2127
  body: payload,
@@ -2074,6 +2129,7 @@ var SenderManager = class extends StateManager {
2074
2129
  credentials: "include",
2075
2130
  signal: controller.signal,
2076
2131
  headers: {
2132
+ ...customHeaders,
2077
2133
  "Content-Type": "application/json"
2078
2134
  }
2079
2135
  });
@@ -2536,8 +2592,10 @@ var EventManager = class extends StateManager {
2536
2592
  * @param storeManager - Storage manager for persistence
2537
2593
  * @param emitter - Optional event emitter for local event consumption
2538
2594
  * @param transformers - Optional event transformation hooks
2595
+ * @param staticHeaders - Optional static HTTP headers for custom backend (from config)
2596
+ * @param customHeadersProvider - Optional callback for dynamic headers
2539
2597
  */
2540
- constructor(storeManager, emitter = null, transformers = {}) {
2598
+ constructor(storeManager, emitter = null, transformers = {}, staticHeaders = {}, customHeadersProvider) {
2541
2599
  super();
2542
2600
  this.emitter = emitter;
2543
2601
  this.transformers = transformers;
@@ -2548,7 +2606,16 @@ var EventManager = class extends StateManager {
2548
2606
  this.dataSenders.push(new SenderManager(storeManager, "saas", collectApiUrls.saas, transformers));
2549
2607
  }
2550
2608
  if (collectApiUrls?.custom) {
2551
- this.dataSenders.push(new SenderManager(storeManager, "custom", collectApiUrls.custom, transformers));
2609
+ this.dataSenders.push(
2610
+ new SenderManager(
2611
+ storeManager,
2612
+ "custom",
2613
+ collectApiUrls.custom,
2614
+ transformers,
2615
+ staticHeaders,
2616
+ customHeadersProvider
2617
+ )
2618
+ );
2552
2619
  }
2553
2620
  this.saveSessionCountsDebounced = this.debounce((sessionId) => {
2554
2621
  this.saveSessionCounts(sessionId);
@@ -2955,6 +3022,29 @@ var EventManager = class extends StateManager {
2955
3022
  flushImmediatelySync() {
2956
3023
  return this.flushEvents(true);
2957
3024
  }
3025
+ /**
3026
+ * Sets the custom headers provider callback for the custom integration.
3027
+ * Only affects requests to custom backend (not TraceLog SaaS).
3028
+ *
3029
+ * @param provider - Callback function that returns custom headers
3030
+ */
3031
+ setCustomHeadersProvider(provider) {
3032
+ for (const sender of this.dataSenders) {
3033
+ if (sender.getIntegrationId() === "custom") {
3034
+ sender.setCustomHeadersProvider(provider);
3035
+ }
3036
+ }
3037
+ }
3038
+ /**
3039
+ * Removes the custom headers provider callback from the custom integration.
3040
+ */
3041
+ removeCustomHeadersProvider() {
3042
+ for (const sender of this.dataSenders) {
3043
+ if (sender.getIntegrationId() === "custom") {
3044
+ sender.removeCustomHeadersProvider();
3045
+ }
3046
+ }
3047
+ }
2958
3048
  /**
2959
3049
  * Returns the current number of events in the main queue.
2960
3050
  *
@@ -6051,6 +6141,7 @@ var App = class extends StateManager {
6051
6141
  suppressNextScrollTimer = null;
6052
6142
  emitter = new Emitter();
6053
6143
  transformers = {};
6144
+ customHeadersProvider;
6054
6145
  managers = {};
6055
6146
  handlers = {};
6056
6147
  get initialized() {
@@ -6070,7 +6161,14 @@ var App = class extends StateManager {
6070
6161
  this.managers.storage = new StorageManager();
6071
6162
  try {
6072
6163
  this.setupState(config);
6073
- this.managers.event = new EventManager(this.managers.storage, this.emitter, this.transformers);
6164
+ const staticHeaders = config.integrations?.custom?.headers ?? {};
6165
+ this.managers.event = new EventManager(
6166
+ this.managers.storage,
6167
+ this.emitter,
6168
+ this.transformers,
6169
+ staticHeaders,
6170
+ this.customHeadersProvider
6171
+ );
6074
6172
  this.initializeHandlers();
6075
6173
  await this.managers.event.recoverPersistedEvents().catch((error) => {
6076
6174
  log("warn", "Failed to recover persisted events", { error });
@@ -6133,6 +6231,34 @@ var App = class extends StateManager {
6133
6231
  getTransformer(hook) {
6134
6232
  return this.transformers[hook];
6135
6233
  }
6234
+ /**
6235
+ * Sets a callback to provide custom HTTP headers for requests to custom backends.
6236
+ * Only applies to custom backend integration (not TraceLog SaaS).
6237
+ *
6238
+ * @param provider - Callback function that returns custom headers
6239
+ * @throws {Error} If provider is not a function
6240
+ * @internal Called from api.setCustomHeaders()
6241
+ */
6242
+ setCustomHeaders(provider) {
6243
+ if (typeof provider !== "function") {
6244
+ throw new Error(`[TraceLog] Custom headers provider must be a function, received: ${typeof provider}`);
6245
+ }
6246
+ this.customHeadersProvider = provider;
6247
+ if (this.managers.event) {
6248
+ this.managers.event.setCustomHeadersProvider(provider);
6249
+ }
6250
+ }
6251
+ /**
6252
+ * Removes the custom headers provider callback.
6253
+ *
6254
+ * @internal Called from api.removeCustomHeaders()
6255
+ */
6256
+ removeCustomHeaders() {
6257
+ this.customHeadersProvider = void 0;
6258
+ if (this.managers.event) {
6259
+ this.managers.event.removeCustomHeadersProvider();
6260
+ }
6261
+ }
6136
6262
  /**
6137
6263
  * Destroys the TraceLog instance and cleans up all resources.
6138
6264
  *
@@ -6158,6 +6284,7 @@ var App = class extends StateManager {
6158
6284
  this.emitter.removeAllListeners();
6159
6285
  this.transformers.beforeSend = void 0;
6160
6286
  this.transformers.beforeBatch = void 0;
6287
+ this.customHeadersProvider = void 0;
6161
6288
  this.set("suppressNextScroll", false);
6162
6289
  this.set("sessionId", null);
6163
6290
  this.isInitialized = false;
@@ -6312,6 +6439,7 @@ var App = class extends StateManager {
6312
6439
  // src/api.ts
6313
6440
  var pendingListeners = [];
6314
6441
  var pendingTransformers = [];
6442
+ var pendingCustomHeadersProvider = null;
6315
6443
  var app = null;
6316
6444
  var isInitializing = false;
6317
6445
  var isDestroying = false;
@@ -6346,6 +6474,10 @@ var init = async (config) => {
6346
6474
  }
6347
6475
  });
6348
6476
  pendingTransformers.length = 0;
6477
+ if (pendingCustomHeadersProvider) {
6478
+ instance.setCustomHeaders(pendingCustomHeadersProvider);
6479
+ pendingCustomHeadersProvider = null;
6480
+ }
6349
6481
  const initPromise = instance.init(validatedConfig);
6350
6482
  const timeoutPromise = new Promise((_, reject) => {
6351
6483
  setTimeout(() => {
@@ -6444,6 +6576,35 @@ var removeTransformer = (hook) => {
6444
6576
  }
6445
6577
  app.removeTransformer(hook);
6446
6578
  };
6579
+ var setCustomHeaders = (provider) => {
6580
+ if (typeof window === "undefined" || typeof document === "undefined") {
6581
+ return;
6582
+ }
6583
+ if (typeof provider !== "function") {
6584
+ throw new Error(`[TraceLog] Custom headers provider must be a function, received: ${typeof provider}`);
6585
+ }
6586
+ if (!app || isInitializing) {
6587
+ pendingCustomHeadersProvider = provider;
6588
+ return;
6589
+ }
6590
+ if (isDestroying) {
6591
+ throw new Error("[TraceLog] Cannot set custom headers while TraceLog is being destroyed");
6592
+ }
6593
+ app.setCustomHeaders(provider);
6594
+ };
6595
+ var removeCustomHeaders = () => {
6596
+ if (typeof window === "undefined" || typeof document === "undefined") {
6597
+ return;
6598
+ }
6599
+ if (!app) {
6600
+ pendingCustomHeadersProvider = null;
6601
+ return;
6602
+ }
6603
+ if (isDestroying) {
6604
+ throw new Error("[TraceLog] Cannot remove custom headers while TraceLog is being destroyed");
6605
+ }
6606
+ app.removeCustomHeaders();
6607
+ };
6447
6608
  var isInitialized = () => {
6448
6609
  if (typeof window === "undefined" || typeof document === "undefined") {
6449
6610
  return false;
@@ -6468,6 +6629,7 @@ var destroy = () => {
6468
6629
  isInitializing = false;
6469
6630
  pendingListeners.length = 0;
6470
6631
  pendingTransformers.length = 0;
6632
+ pendingCustomHeadersProvider = null;
6471
6633
  if (false) ;
6472
6634
  isDestroying = false;
6473
6635
  } catch (error) {
@@ -6475,6 +6637,7 @@ var destroy = () => {
6475
6637
  isInitializing = false;
6476
6638
  pendingListeners.length = 0;
6477
6639
  pendingTransformers.length = 0;
6640
+ pendingCustomHeadersProvider = null;
6478
6641
  isDestroying = false;
6479
6642
  log("warn", "Error during destroy, forced cleanup completed", { error });
6480
6643
  }
@@ -6518,6 +6681,8 @@ var tracelog = {
6518
6681
  off,
6519
6682
  setTransformer,
6520
6683
  removeTransformer,
6684
+ setCustomHeaders,
6685
+ removeCustomHeaders,
6521
6686
  isInitialized,
6522
6687
  destroy,
6523
6688
  setQaMode: setQaMode2,