AbsoluteJS

Diagnostics

@absolutejs/diagnosticsv0.2.1betaObservability

Privacy-first AbsoluteJS Support Mode: bounded browser diagnostics, redacted HAR capture, correlated support bundles, secure lifecycle storage, native UI, and operator tooling.

#Installation

BASH
bun add @absolutejs/diagnostics

#Capabilities

Overview

Privacy-first, on-demand browser diagnostics for AbsoluteJS applications.

It records a bounded network and console timeline only after an explicit support/operator action, exports a redacted HAR 1.2 document, and provides a Playwright/CDP path when a vendor needs a complete DevTools capture. Request and response bodies are off by default. Redaction happens before in-page entries are retained and again at export or server ingest.

Why this is separate from Beacon, Errors, and Replay

@absolutejs/beacon stays tiny and always-on. It records redacted request

breadcrumbs and actionable failures, not complete protocol archives.

@absolutejs/errors groups and persists issues. It should link a diagnostic

Show 5 more

id, not own large support artifacts.

@absolutejs/replay records privacy-masked DOM state. A DOM recording is not

an HTTP archive.

@absolutejs/observability can compose all four capabilities and correlate

the diagnostic id with Beacon session, Replay, Errors, and traces.

In-page diagnostics

Creating a controller does not start recording:

The recorder wraps the current fetch, XHR, and console functions, so it can coexist with Beacon. It also consumes Resource Timing entries for static and third-party resources visible to the page. stop() restores only wrappers it still owns.

The in-page manifest always declares completeness: "in-page-partial" and cacheDisabled: false. Application JavaScript cannot truthfully claim a full HAR.

Show 3 more

Body capture is deliberately difficult to enable

There is no captureBodies: true switch. Supply a per-request allow function and select request and/or response explicitly:

Strings and URL-encoded/JSON bodies are redacted immediately. Blob, stream, multipart, and other binary request bodies are never inspected by the in-page recorder.

Complete HAR capture with Playwright/CDP

Use the Playwright entry point when a payment processor, identity provider, or other vendor requests a real HAR with Preserve Log and Disable Cache:

Playwright first records to a uniquely named raw temporary file. stop() closes the context so Playwright flushes the HAR, creates the redacted output, runs the sharing audit, and removes the raw temporary file in a finally block. Call stop() rather than closing the browser window at the OS level.

The metadata declares completeness: "devtools-complete", whether cache was disabled, exact UTC start/end times, and any operator markers.

Support Mode controller and native UI

createSupportModeController provides a consent-shaped state machine: idle → recording → reviewing → sending → sent. Creating it never starts a recording. A host can use the headless controller directly or connect the framework-neutral native element.

The element explains what will be recorded, requires an explicit Start click, shows a persistent recording state, supports named markers, and exposes the privacy-audit result before send.

Correlated support bundles

createSupportBundle() produces one audited JSON artifact containing the redacted in-page archive and HAR plus marker, replay, release, environment, issue-fingerprint, and W3C trace correlations. It does not embed Replay data, server logs, or issue records; those remain in their purpose-built stores and are joined by id.

Request-level trace correlation recognizes valid traceparent headers and records exposed Server-Timing metrics. Diagnostic-id propagation is same-origin, opt-in, and off by default because mutating requests can affect caches or signed requests.

The optional Elysia correlation plugin makes the bounded correlation available to handlers and appends server timing:

Redaction and audit

Defaults remove or mask:

Authorization, Cookie, Set-Cookie, proxy credentials, and API-key

headers

Show 7 more

every URL query value and every fragment

bearer values and JWT-shaped strings

tokens, sessions, credentials, passwords, signatures, wallet payloads,

payment fields, card fields, and common personal-contact fields

request and response bodies in DevTools HAR captures

body content beyond the configured byte limit

The sharing audit reports finding codes and locations, never the suspected secret value.

Elysia relay

The relay defaults closed. A host must provide authorization and storage:

The relay enforces a byte limit, validates the archive shape, redacts again, audits the serialized HAR, and only then calls the store. Wire storage to @absolutejs/blob or another private store with an explicit retention policy.

Secure lifecycle storage

Show 2 more

createDiagnosticBlobCaptureStore() adapts any @absolutejs/blob store. The relay can enforce retention, atomic download limits, short-lived HMAC-signed download URLs, explicit deletion, and mandatory lifecycle audit hooks.

maxDownloads is accepted only when the store implements atomic consume(); the plugin refuses unsafe configuration rather than pretending a normal get() is sufficient. The Blob adapter exposes serialized consume() only with singleWriter: true. Clustered applications must supply a transactional store implementation instead of relying on an object-store read/modify/write race.

Operator viewer and comparison

@absolutejs/diagnostics/viewer builds a chronological network, console, and marker timeline. compareSupportBundles(left, right) reports request-set, status, failure-count, timing, console, and marker differences—useful for comparing a successful card attempt with a failed wallet attempt.

Browser limitations

A normal webpage cannot observe:

protected cookies and browser-owned authorization data

most cross-origin response headers or bodies

Show 5 more

native Apple Pay or browser-wallet network traffic

browser cache, connection, and service-worker protocol details with DevTools

fidelity

requests made by another device during a QR handoff

Therefore an in-page export is useful but partial. Use Playwright/CDP for a complete desktop-browser HAR. Capturing native iPhone Safari with Web Inspector still requires Apple's supported Mac-connected workflow; this package cannot bypass platform security boundaries.

Outcomes

What you can build

Overview

Privacy-first, on-demand browser diagnostics for AbsoluteJS applications.

Why this is separate from Beacon, Errors, and Replay

@absolutejs/beacon stays tiny and always-on. It records redacted request

Install

Install only the optional capability you use:

Hardening checklist

Production guidance

Make every external boundary explicitPin the deployed @absolutejs/diagnostics version, replace example or memory-backed dependencies with durable implementations, bound external calls, protect credentials, and emit enough evidence to retry or recover safely.

Follow in order

Troubleshooting path

1
Overview
Privacy-first, on-demand browser diagnostics for AbsoluteJS applications.
2
Why this is separate from Beacon, Errors, and Replay
@absolutejs/beacon stays tiny and always-on. It records redacted request
3
In-page diagnostics
Creating a controller does not start recording:

#Install 2

Partial snippet

Install only the optional capability you use:

SH
bun add playwright # complete Chromium HAR capture
bun add elysia     # upload/retrieval relay

#In-page diagnostics

Partial snippet

Creating a controller does not start recording:

TS
import { createBrowserDiagnostics } from "@absolutejs/diagnostics/browser";

const diagnostics = createBrowserDiagnostics({
  project: "web",
  release: APP_RELEASE,
  replayId: () => replay.getReplayId(),
  traceId: () => currentTraceId(),
  ignoredUrlSubstrings: ["/api/diagnostics"],
});

// Call only after an explicit support/operator action.
const session = diagnostics.start({ reason: "payment provider reproduction" });

// Reproduce the problem, then stop and download a redacted HAR.
const archive = await session.stop();
session.downloadHar("payment-provider.redacted.har");

#Body capture is deliberately difficult to enable

Partial snippet

There is no captureBodies: true switch. Supply a per-request allow function and select request and/or response explicitly:

TS
const diagnostics = createBrowserDiagnostics({
  project: "web",
  bodyCapture: {
    request: true,
    response: true,
    maxBodyBytes: 16_384,
    allow: ({ sameOrigin, url }) =>
      sameOrigin && new URL(url).pathname.startsWith("/api/support-safe/"),
  },
});

#Public entry points

Supported entry points declared by this project’s package manifest. Internal dist paths are not part of the package contract.

Public package entry point declared in package.json.

@absolutejs/diagnostics@absolutejs/diagnostics/browser@absolutejs/diagnostics/har@absolutejs/diagnostics/redact@absolutejs/diagnostics/playwright@absolutejs/diagnostics/blob@absolutejs/diagnostics/support@absolutejs/diagnostics/trace@absolutejs/diagnostics/ui@absolutejs/diagnostics/viewer@absolutejs/diagnostics/elysia@absolutejs/diagnostics/manifest@absolutejs/diagnostics/manifest.json

#Package commands

Scripts declared by this project’s package manifest.

bun run buildrm -rf dist && bun build src/index.ts src/browser.ts src/har.ts src/redact.ts src/support.ts src/trace.ts src/ui.ts src/viewer.ts --outdir dist --root ./src --splitting --sourcemap --target=browser && bun build src/playwright.ts src/elysia.ts src/blob.ts src/manifest.ts --outdir dist --root ./src --splitting --sourcemap --target=bun --external playwright --external elysia --external @absolutejs/manifest --external '@absolutejs/manifest/*' --external @sinclair/typebox --external '@sinclair/typebox/*' && tsc --project tsconfig.build.json && absolute-manifest emit
bun run check:packagebun run format && bun run typecheck && bun run test && bun run verify-package && bun run build && absolute-changelog check
bun run formatprettier --write "./**/*.{ts,json,md}"
bun run testbun test
bun run typechecktsc --noEmit

#API reference

Search the declarations exported by the current package type files. Expand a symbol to inspect its source-backed signature.

49 symbols
BrowserDiagnosticsOptionstypePermalink
TS
type BrowserDiagnosticsOptions = {
    bodyCapture?: DiagnosticBodyCapturePolicy;
    environment?: string;
    ignoredUrlSubstrings?: string[];
    maxBytes?: number;
    maxConsoleEntries?: number;
    maxNetworkEntries?: number;
    preserveQueryValues?: string[];
    project: string;
    /** Add the diagnostic id to same-origin requests. Off by default because
     * request mutation can affect caches, signatures, and CORS behavior. */
    propagateDiagnosticId?: boolean;
    release?: string;
    replayId?: () => string | undefined;
    traceId?: () => string | undefined;
};
Exported from @absolutejs/diagnostics