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@alphaRequires 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-relay2. 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