Files
skills/docs/observability/monitor/analytics-browser/src/transport/batch.md
2026-05-29 08:20:56 +01:00

2.7 KiB

batch.ts

Purpose

Implements BatchTransport — the HTTP transport used by AnalyticsTracker for the steady-state, non-unload flush path. Every call posts a JSON-encoded { events } body to the configured endpoint, wrapped in an AbortController whose timeout is armed via the injected TimersLike. The transport short-circuits on 4xx responses (no retry), retries with exponential backoff on 5xx / network errors, and translates any post-abort failure into a typed AnalyticsBrowserError(TRANSPORT_TIMEOUT) so callers can discriminate timeouts from other transport failures.

Features

  • AbortController + timeoutMs on every fetch — guaranteed bounded latency.
  • 4xx short-circuit — no retry storm on stable client errors.
  • Exponential backoff on 5xx / network — retryDelay * 2 ** attempt.
  • Injectable fetchFn and timers — every browser-API touch is reachable from tests without DOM globals.
  • Idempotent shutdown() — future send() calls are no-ops returning true.

Usage: Basic

import { BatchTransport } from "@suaveplan/analytics-browser/transport";

const transport = new BatchTransport({ endpoint: "/api/analytics" });
await transport.send(events);

Usage: Advanced

import { BatchTransport } from "@suaveplan/analytics-browser/transport";

const transport = new BatchTransport({
    endpoint: "https://collector.example.com/v1/events",
    maxRetries: 5,
    retryDelay: 500,
    timeoutMs: 5_000,
    fetchFn: async (url, init) => {
        const req = new Request(url, init);
        return fetch(req, { credentials: "include" });
    },
});

API Reference

  • class BatchTransport implements Transport
    • new BatchTransport(options) — options: BatchTransportOptions { endpoint, maxRetries?, retryDelay?, timeoutMs?, fetchFn?, timers? }. Throws AnalyticsBrowserError(INVALID_OPTIONS) when endpoint is empty.
    • send(events) → Promise<boolean> — true on success, false on 4xx or exhausted retries. Throws AnalyticsBrowserError(TRANSPORT_TIMEOUT) when the fetch is aborted by the timeout.
    • shutdown() → Promise<void> — disables further sends.
    • isActive() → boolean.

Implementation Notes

The timeout setTimer callback aborts the controller with an AnalyticsBrowserError(TRANSPORT_TIMEOUT) as the reason. If the host's fetch rejects with that exact error, the transport rethrows it as-is. If the fetch rejects with a different error after the signal has aborted (e.g. a DOMException synthesised by the runtime), the transport still maps the failure to TRANSPORT_TIMEOUT because the signal's aborted state is the authoritative reason. Otherwise the failure is treated as a generic retryable network error and the loop continues until maxRetries is exhausted.