@tracelog/lib 2.8.5 → 2.9.0-rc.108.6

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.
@@ -406,6 +406,22 @@ interface EventData {
406
406
  /** Campaign tracking parameters */
407
407
  utm?: UTM;
408
408
  }
409
+ /**
410
+ * Internal queue entry: an `EventData` enriched with the session ID frozen at
411
+ * `track()` time. Survives session renewal — when the user is idle past the
412
+ * timeout, `state.sessionId` is nulled but events already in the queue keep
413
+ * their original `_session_id`, so `EventManager.buildBatchesWithIds()` can
414
+ * still attribute them correctly instead of emitting `session_id: null` to the
415
+ * wire.
416
+ *
417
+ * **Internal only.** The leading underscore mirrors `EventsQueue._metadata` —
418
+ * this field is stripped from `events[]` at batch construction time, since the
419
+ * backend's `EventDto` uses `forbidNonWhitelisted: true` and the wrapper
420
+ * `EventsQueue.session_id` is the contract.
421
+ */
422
+ interface QueuedEvent extends EventData {
423
+ _session_id: string;
424
+ }
409
425
 
410
426
  /**
411
427
  * Web Vitals filtering mode
@@ -1628,9 +1644,57 @@ declare class EventManager extends StateManager {
1628
1644
  flushPendingEvents(): void;
1629
1645
  private clearSendTimeout;
1630
1646
  private isSuccessfulResult;
1647
+ /**
1648
+ * Groups the queue by frozen `_session_id`, preserving insertion order.
1649
+ * Single pass — `buildBatchesWithIds()` builds one batch + one eventIds list
1650
+ * per group, so the grouping cost is O(N) per flush regardless of session
1651
+ * count.
1652
+ *
1653
+ * **Self-heal**: any entry missing `_session_id` (an internal invariant
1654
+ * violation — `buildEventPayload` always stamps it) is removed from the
1655
+ * queue rather than left behind, otherwise a single corrupted entry would
1656
+ * keep `eventsQueue.length > 0` forever and re-trigger periodic sends.
1657
+ */
1658
+ private groupQueuedEventsBySession;
1659
+ /**
1660
+ * Builds a parallel list of `(batch, eventIds)` for sending. The eventIds are
1661
+ * the original `_session_id`-tagged event IDs in the queue that map to this
1662
+ * batch — used for optimistic removal. We can't read them off the wrapper's
1663
+ * `events[]` because dedup may have removed some signatures.
1664
+ */
1665
+ private buildBatchesWithIds;
1631
1666
  private flushEvents;
1667
+ /**
1668
+ * Sends one batch synchronously across all integrations (sendBeacon path).
1669
+ * Optimistic removal: if any integration succeeds, we remove the batch's
1670
+ * events from the queue and emit it locally. Failures persist per-integration.
1671
+ */
1672
+ private sendBatchSync;
1673
+ /**
1674
+ * Sends one batch asynchronously across all integrations (fetch path).
1675
+ */
1676
+ private sendBatchAsync;
1632
1677
  private sendEventsQueue;
1633
- private buildEventsPayload;
1678
+ /**
1679
+ * Builds a single batch from a per-session group: dedup by signature,
1680
+ * SESSION_START first, then timestamp order, strip `_session_id`, apply
1681
+ * `beforeBatch` transformer when running standalone.
1682
+ *
1683
+ * **Why N batches per flush**: events freeze their `_session_id` at `track()`
1684
+ * time. If the session was renewed (idle timeout) between two `track()`
1685
+ * calls, the queue contains events from multiple sessions. `buildBatchesWithIds()`
1686
+ * emits one batch per session so the backend's `EventsQueueDto.session_id`
1687
+ * remains the single source of truth and stays consistent with the events it
1688
+ * carries.
1689
+ *
1690
+ * **Strip**: `_session_id` is removed from each event in the wrapper's
1691
+ * `events[]` because the backend uses `forbidNonWhitelisted: true` and would
1692
+ * reject the batch if the field leaked through.
1693
+ *
1694
+ * **Transformer note**: `beforeBatch` is invoked **once per session-batch**,
1695
+ * not once per flush. A queue spanning N sessions triggers N invocations.
1696
+ */
1697
+ private buildBatchFromGroup;
1634
1698
  private buildEventPayload;
1635
1699
  private isDuplicateEvent;
1636
1700
  private pruneOldFingerprints;
@@ -2333,6 +2397,11 @@ type BeforeSendTransformer = (event: EventData) => EventData | null;
2333
2397
  * Transform entire batch before sending to backend.
2334
2398
  * Applied per-batch (10s interval or 50 events), can filter by returning null.
2335
2399
  *
2400
+ * **Multi-batch flushes**: when the queue spans more than one session (e.g.
2401
+ * after an idle-timeout renewal), one flush produces one batch per session,
2402
+ * and this transformer is invoked **once per session-batch**. Avoid stateful
2403
+ * transformers that assume a single invocation per flush.
2404
+ *
2336
2405
  * @param batch - The batch to transform
2337
2406
  * @returns Transformed batch or null to filter
2338
2407
  */
@@ -2589,4 +2658,4 @@ declare const tracelog: {
2589
2658
  resetIdentity: () => Promise<void>;
2590
2659
  };
2591
2660
 
2592
- 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, type IdentifyData, type InitResult, 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_NESTED_OBJECT_KEYS, MAX_STRING_LENGTH, MAX_STRING_LENGTH_IN_ARRAY, type MetadataType, Mode, PII_PATTERNS, type PageViewData, PermanentError, type PersistedEventsQueue, type PrimaryScrollEvent, type QueueMetadata, RateLimitError, SamplingRateValidationError, type ScrollData, ScrollDirection, type SecondaryScrollEvent, type SessionEventCounts, SessionTimeoutValidationError, SpecialApiUrl, type State, TimeoutError, 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 };
2661
+ 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, type IdentifyData, type InitResult, 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_NESTED_OBJECT_KEYS, MAX_STRING_LENGTH, MAX_STRING_LENGTH_IN_ARRAY, type MetadataType, Mode, PII_PATTERNS, type PageViewData, PermanentError, type PersistedEventsQueue, type PrimaryScrollEvent, type QueueMetadata, type QueuedEvent, RateLimitError, SamplingRateValidationError, type ScrollData, ScrollDirection, type SecondaryScrollEvent, type SessionEventCounts, SessionTimeoutValidationError, SpecialApiUrl, type State, TimeoutError, 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 };
@@ -406,6 +406,22 @@ interface EventData {
406
406
  /** Campaign tracking parameters */
407
407
  utm?: UTM;
408
408
  }
409
+ /**
410
+ * Internal queue entry: an `EventData` enriched with the session ID frozen at
411
+ * `track()` time. Survives session renewal — when the user is idle past the
412
+ * timeout, `state.sessionId` is nulled but events already in the queue keep
413
+ * their original `_session_id`, so `EventManager.buildBatchesWithIds()` can
414
+ * still attribute them correctly instead of emitting `session_id: null` to the
415
+ * wire.
416
+ *
417
+ * **Internal only.** The leading underscore mirrors `EventsQueue._metadata` —
418
+ * this field is stripped from `events[]` at batch construction time, since the
419
+ * backend's `EventDto` uses `forbidNonWhitelisted: true` and the wrapper
420
+ * `EventsQueue.session_id` is the contract.
421
+ */
422
+ interface QueuedEvent extends EventData {
423
+ _session_id: string;
424
+ }
409
425
 
410
426
  /**
411
427
  * Web Vitals filtering mode
@@ -1628,9 +1644,57 @@ declare class EventManager extends StateManager {
1628
1644
  flushPendingEvents(): void;
1629
1645
  private clearSendTimeout;
1630
1646
  private isSuccessfulResult;
1647
+ /**
1648
+ * Groups the queue by frozen `_session_id`, preserving insertion order.
1649
+ * Single pass — `buildBatchesWithIds()` builds one batch + one eventIds list
1650
+ * per group, so the grouping cost is O(N) per flush regardless of session
1651
+ * count.
1652
+ *
1653
+ * **Self-heal**: any entry missing `_session_id` (an internal invariant
1654
+ * violation — `buildEventPayload` always stamps it) is removed from the
1655
+ * queue rather than left behind, otherwise a single corrupted entry would
1656
+ * keep `eventsQueue.length > 0` forever and re-trigger periodic sends.
1657
+ */
1658
+ private groupQueuedEventsBySession;
1659
+ /**
1660
+ * Builds a parallel list of `(batch, eventIds)` for sending. The eventIds are
1661
+ * the original `_session_id`-tagged event IDs in the queue that map to this
1662
+ * batch — used for optimistic removal. We can't read them off the wrapper's
1663
+ * `events[]` because dedup may have removed some signatures.
1664
+ */
1665
+ private buildBatchesWithIds;
1631
1666
  private flushEvents;
1667
+ /**
1668
+ * Sends one batch synchronously across all integrations (sendBeacon path).
1669
+ * Optimistic removal: if any integration succeeds, we remove the batch's
1670
+ * events from the queue and emit it locally. Failures persist per-integration.
1671
+ */
1672
+ private sendBatchSync;
1673
+ /**
1674
+ * Sends one batch asynchronously across all integrations (fetch path).
1675
+ */
1676
+ private sendBatchAsync;
1632
1677
  private sendEventsQueue;
1633
- private buildEventsPayload;
1678
+ /**
1679
+ * Builds a single batch from a per-session group: dedup by signature,
1680
+ * SESSION_START first, then timestamp order, strip `_session_id`, apply
1681
+ * `beforeBatch` transformer when running standalone.
1682
+ *
1683
+ * **Why N batches per flush**: events freeze their `_session_id` at `track()`
1684
+ * time. If the session was renewed (idle timeout) between two `track()`
1685
+ * calls, the queue contains events from multiple sessions. `buildBatchesWithIds()`
1686
+ * emits one batch per session so the backend's `EventsQueueDto.session_id`
1687
+ * remains the single source of truth and stays consistent with the events it
1688
+ * carries.
1689
+ *
1690
+ * **Strip**: `_session_id` is removed from each event in the wrapper's
1691
+ * `events[]` because the backend uses `forbidNonWhitelisted: true` and would
1692
+ * reject the batch if the field leaked through.
1693
+ *
1694
+ * **Transformer note**: `beforeBatch` is invoked **once per session-batch**,
1695
+ * not once per flush. A queue spanning N sessions triggers N invocations.
1696
+ */
1697
+ private buildBatchFromGroup;
1634
1698
  private buildEventPayload;
1635
1699
  private isDuplicateEvent;
1636
1700
  private pruneOldFingerprints;
@@ -2333,6 +2397,11 @@ type BeforeSendTransformer = (event: EventData) => EventData | null;
2333
2397
  * Transform entire batch before sending to backend.
2334
2398
  * Applied per-batch (10s interval or 50 events), can filter by returning null.
2335
2399
  *
2400
+ * **Multi-batch flushes**: when the queue spans more than one session (e.g.
2401
+ * after an idle-timeout renewal), one flush produces one batch per session,
2402
+ * and this transformer is invoked **once per session-batch**. Avoid stateful
2403
+ * transformers that assume a single invocation per flush.
2404
+ *
2336
2405
  * @param batch - The batch to transform
2337
2406
  * @returns Transformed batch or null to filter
2338
2407
  */
@@ -2589,4 +2658,4 @@ declare const tracelog: {
2589
2658
  resetIdentity: () => Promise<void>;
2590
2659
  };
2591
2660
 
2592
- 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, type IdentifyData, type InitResult, 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_NESTED_OBJECT_KEYS, MAX_STRING_LENGTH, MAX_STRING_LENGTH_IN_ARRAY, type MetadataType, Mode, PII_PATTERNS, type PageViewData, PermanentError, type PersistedEventsQueue, type PrimaryScrollEvent, type QueueMetadata, RateLimitError, SamplingRateValidationError, type ScrollData, ScrollDirection, type SecondaryScrollEvent, type SessionEventCounts, SessionTimeoutValidationError, SpecialApiUrl, type State, TimeoutError, 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 };
2661
+ 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, type IdentifyData, type InitResult, 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_NESTED_OBJECT_KEYS, MAX_STRING_LENGTH, MAX_STRING_LENGTH_IN_ARRAY, type MetadataType, Mode, PII_PATTERNS, type PageViewData, PermanentError, type PersistedEventsQueue, type PrimaryScrollEvent, type QueueMetadata, type QueuedEvent, RateLimitError, SamplingRateValidationError, type ScrollData, ScrollDirection, type SecondaryScrollEvent, type SessionEventCounts, SessionTimeoutValidationError, SpecialApiUrl, type State, TimeoutError, 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 };