JSPM

  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 30
  • Score
    100M100P100Q81479F
  • License MIT

LogDB SDK for browsers, Deno (Supabase Edge Functions), Bun, and Cloudflare Workers. OTLP HTTP transport via fetch.

Package Exports

  • @logdbhq/web
  • @logdbhq/web/builders
  • @logdbhq/web/models

Readme

@logdbhq/web

LogDB SDK for browsers, Deno (Supabase Edge Functions), Bun, Cloudflare Workers, and modern Node. One package, every JS runtime that has fetch.

Status: v0.1.0-alpha. Writer-only. Reader API and OpenTelemetry exporter ship later.

Why

You're building a Lovable-style app: Vite + React frontend, Supabase Edge Functions on the backend, and you want both sides instrumented in LogDB.

  • The Node SDK (@logdbhq/node) uses native gRPC — only works in Node.
  • The browser can't speak native gRPC. Deno can't import Node modules.
  • This package uses fetch + OTLP HTTP/JSON. Works in every JS runtime.
  • Bundle size: 20 KB minified, 6.3 KB gzipped in the browser.

Install

npm install @logdbhq/web@alpha

Requires any runtime with native fetch (Node 18+, Deno, Bun, modern browsers, Cloudflare Workers).

Two patterns: server vs browser

Pattern A — Edge Function / Node / Bun (server-side)

Direct to LogDB. The API key stays on the server.

import { LogDBClient, LogLevel } from "@logdbhq/web";

const client = new LogDBClient({
  apiKey: Deno.env.get("LOGDB_API_KEY")!,
  endpoint: "https://otlp.logdb.site",
  defaultApplication: "my-edge-function",
});

await client.log({ message: "user signed up", level: LogLevel.Info });
await client.flush();

Pattern B — Browser (Vite/React/Lovable)

Browser POSTs to your own Supabase Edge Function relay. The relay holds the API key. The browser never sees it.

1. Drop the relay function into your project (template provided):

mkdir -p supabase/functions/logdb-relay
cp node_modules/@logdbhq/web/templates/supabase-edge-function/index.ts \
   supabase/functions/logdb-relay/index.ts

supabase secrets set LOGDB_API_KEY=your-key-here
supabase functions deploy logdb-relay

2. Wire up the browser SDK:

import { LogDBClient, LogLevel } from "@logdbhq/web";

const client = new LogDBClient({
  endpoint: `${import.meta.env.VITE_SUPABASE_URL}/functions/v1/logdb-relay`,
  defaultApplication: "my-react-app",
  // No apiKey — the relay stamps it.
});

await client.log({ message: "checkout button clicked", level: LogLevel.Info });

See templates/supabase-edge-function/ for the relay template and full setup instructions.

Fluent builder

import { LogDBClient, LogEventBuilder, LogLevel } from "@logdbhq/web";

await LogEventBuilder.create(client)
  .setMessage("payment processed")
  .setLogLevel(LogLevel.Info)
  .setUserEmail("alice@example.com")
  .setCorrelationId(traceId)
  .addAttribute("amount_eur", 199.99)
  .addAttribute("currency", "EUR")
  .addLabel("payment")
  .log();

Heartbeats and cache

import { LogBeatBuilder, LogCacheBuilder } from "@logdbhq/web";

await LogBeatBuilder.create(client)
  .setMeasurement("active_users")
  .addTag("region", "eu-west-1")
  .addField("count", 1247)
  .log();

await LogCacheBuilder.create(client)
  .setKey("user:42:profile")
  .setValue({ name: "Alice", role: "admin" })
  .log();

Configuration

Option Default Description
endpoint — (required) Base URL the SDK POSTs to. The SDK appends /v1/logs and /v1/metrics. Browser: your relay URL. Server: the LogDB OTLP collector.
apiKey undefined Server-side only. Sent as logdb.apikey resource attribute. Omit in browser mode.
defaultApplication undefined Default application field. Recommended.
defaultEnvironment "production" Default environment field.
defaultCollection "logs" Default LogDB collection.
enableBatching true Buffer entries and flush in batches.
batchSize 100 Max entries per batch.
flushInterval 5000 (ms) Max time an entry waits in the buffer.
maxRetries 3 Retry attempts per send on transient failures.
retryDelay 1000 (ms) Initial retry delay.
retryBackoffMultiplier 2.0 Exponential backoff multiplier.
enableCircuitBreaker true Trip circuit on repeated failures.
circuitBreakerFailureThreshold 0.5 Failure rate (0..1) that trips.
circuitBreakerSamplingDuration 10000 (ms) Sliding window.
circuitBreakerDurationOfBreak 30000 (ms) Open state duration.
requestTimeout 30000 (ms) Per-request deadline.
headers {} Extra HTTP headers.
onError undefined (err, batch?) => void callback for failed sends.
fetchImpl globalThis.fetch Override fetch (for tests / custom transports).

Error handling

import {
  LogDBClient,
  LogLevel,
  LogResponseStatus,
  LogDBAuthError,
  LogDBNetworkError,
} from "@logdbhq/web";

const client = new LogDBClient({ endpoint: "...", apiKey: "..." });

// 1. Status return value (single sends never throw on transient failures)
const status = await client.log({ message: "x", level: LogLevel.Info });
if (status === LogResponseStatus.NotAuthorized) {
  console.error("Bad API key");
}

// 2. EventEmitter
client.on("error", (err) => {
  if (err instanceof LogDBAuthError) {
    console.error("LogDB rejected the API key");
  } else if (err instanceof LogDBNetworkError) {
    console.warn("LogDB transient delivery error:", err.message);
  }
});

// 3. options.onError callback
new LogDBClient({
  endpoint: "...",
  apiKey: "...",
  onError: (err, batch) => { /* ... */ },
});

Comparison with @logdbhq/node

@logdbhq/web @logdbhq/node
Runtimes Browser, Deno, Bun, Workers, Node 18+ Node 20+ only
Transport OTLP HTTP/JSON via fetch Native gRPC over HTTP/2
Bundle (gzipped) 6.3 KB n/a (server-only)
Dependencies none @grpc/grpc-js, @bufbuild/protobuf
Use when Browser, edge, anywhere fetch works Node services that want gRPC

The two packages share the same conceptual API — LogDBClient, builders, LogLevel, LogResponseStatus, error classes — so switching between them in mixed-runtime apps is straightforward.

Documentation

License

MIT