3.6 KiB
react-auth-metrics
(no submodules)
Purpose
react-auth-metrics.ts builds the OTel instrument set for @suaveplan/react-auth. Instruments are constructed lazily through metrics.getMeter("suaveplan.react-auth") so consumers without a registered MeterProvider pay zero overhead — the OTel API ships a no-op meter by default. The module exposes five counters (react_auth.sign_in.total, react_auth.sign_up.total, react_auth.sign_out.total, react_auth.guard.allow.total, react_auth.guard.deny.total) and one histogram (react_auth.session_fetch.duration_ms), plus helper functions that record the corresponding event with a typed attribute payload. The helpers also push every event into an in-memory state ring so spec-conformance tests can assert exact attribute payloads without standing up a full SDK pipeline. resetReactAuthMetricsState() clears the ring between tests.
Features
- Lazy OTel instrument construction; no-op until a
MeterProvideris registered. - 5 counters + 1 histogram covering the wave-1 production paths.
- Typed
outcome/predicateattributes per record helper. - In-memory
statering (getReactAuthMetricsState) for assertion-friendly tests. resetReactAuthMetricsState()test-only helper.
Usage: Basic
import { recordSignIn } from "@suaveplan/react-auth";
await client.signIn(credentials);
recordSignIn("success");
Usage: Advanced
Wire a real MeterProvider (e.g. for shipping metrics to Prometheus) and assert via the in-memory ring in tests:
import { metrics } from "@opentelemetry/api";
import { MeterProvider } from "@opentelemetry/sdk-metrics";
import {
getReactAuthMetricsState,
recordSessionFetchDuration,
resetReactAuthMetricsState,
} from "@suaveplan/react-auth";
const provider = new MeterProvider();
metrics.setGlobalMeterProvider(provider);
resetReactAuthMetricsState();
recordSessionFetchDuration(42, "success");
const state = getReactAuthMetricsState();
expect(state.sessionFetchDurationMs).toEqual([
{ attributes: { outcome: "success" }, value: 42 },
]);
API Reference
interface ReactAuthMetricSample—{ attributes: Record<string, string>; value?: number }.interface ReactAuthMetricsState—{ signInTotal; signUpTotal; signOutTotal; guardAllowTotal; guardDenyTotal; sessionFetchDurationMs }arrays.function getReactAuthMetrics()— returns the cached instrument bundle.function recordSignIn(outcome: "success" | "failure"): void.function recordSignUp(outcome: "success" | "failure"): void.function recordSignOut(outcome: "success" | "failure"): void.function recordGuardAllow(predicate: string): void.function recordGuardDeny(predicate: string): void.function recordSessionFetchDuration(durationMs: number, outcome: "success" | "failure"): void.function getReactAuthMetricsState(): ReactAuthMetricsState.function resetReactAuthMetricsState(): void.
Implementation Notes
The OTel API exposes a global no-op MeterProvider until the application opts in by calling setGlobalMeterProvider(...); this means the helpers are safe to call from production paths without any registration ceremony. The in-memory state ring is unbounded by design — it is intended only for tests and the package's own conformance checks. A long-running process would never call getReactAuthMetricsState() directly, so leak risk is bounded by test scope. The cached instrument bundle is module-level (let cached: CachedInstruments | undefined) so the meter is resolved at most once per process; the lazy build means importing the module is free.