Skip to content

feat: implement client-side telemetry pipeline with Web Worker batching and beacon delivery - #761

Merged
Chucks1093 merged 2 commits into
accesslayerorg:devfrom
stableprogrammer:feat/telemetry-pipeline-756
Aug 24, 2026
Merged

feat: implement client-side telemetry pipeline with Web Worker batching and beacon delivery#761
Chucks1093 merged 2 commits into
accesslayerorg:devfrom
stableprogrammer:feat/telemetry-pipeline-756

Conversation

@stableprogrammer

Copy link
Copy Markdown
Contributor

Closes #756

Summary

  • Defines a typed TelemetryEvent union (PageLoad, ApiCall, SigningStep, ComponentError, UserAction) plus a DroppedEvents sentinel, all wrapped with a common TelemetryEnvelope (sessionId, walletAddress, buildId, timestamp, sequence).
  • Implements TelemetryBatcher — the testable core that buffers events in memory, flushes every 5 seconds or at 50 events, retains failed batches and prepends them to the next flush (at-least-once delivery), caps retained events at 500 (inserting a DroppedEvents sentinel when exceeded), and includes lastDeliveredSequence and currentBatchStartSequence in every batch header for server-side gap detection.
  • Implements telemetry.worker.ts — a dedicated Web Worker that wraps the batcher, compresses payloads with CompressionStream (gzip) before sending via fetch POST /telemetry, and handles FLUSH_AND_BEACON messages by shipping the current batch via navigator.sendBeacon for guaranteed page-unload delivery.
  • Implements TelemetryClient — the main-thread singleton that spawns the worker, assigns sessionId and monotonically incrementing sequence numbers, and registers a visibilitychange listener that posts FLUSH_AND_BEACON when the page is hidden. The track() method is a single postMessage call with zero synchronous work.
  • Exposes useTelemetry() React hook that lazily initialises the client on first mount and returns a stable track function.
  • Adds 17 unit tests covering: interval-based flush, size-based flush, beacon path, sequence gap reporting after a failed flush, at-least-once retention, DroppedEvents sentinel insertion, and a sub-0.1ms performance assertion for track().

Test plan

  • useTelemetry().track() completes in under 0.1ms on the main thread
  • Batch flushes after 5 seconds of inactivity
  • Batch flushes immediately when 50 events accumulate
  • Page hide triggers sendBeacon with the current batch
  • Failed flushes are retained and prepended to the next batch
  • DroppedEvents sentinel appears when retained events exceed 500
  • All 17 unit tests pass

@Chucks1093

Copy link
Copy Markdown
Member

Moving the batching and compression into a Web Worker is the right call since it keeps the main thread completely free and the zero synchronous work guarantee on track() means telemetry will never block a user interaction. The DroppedEvents sentinel is also a smart design because it gives the backend visibility into data loss without silently swallowing events, which would make capacity planning much harder.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants