Typed Buckets
Buckets are gunsole’s core abstraction for grouping logs. Pass buckets in your config to get first-class typed accessors with full autocomplete.
import { createGunsoleClient } from "@gunsole/web";
const gunsole = createGunsoleClient({ projectId: "my-app", mode: "local", buckets: ["auth", "payments", "api", "ui", "database"] as const, // ^^^^^^^^ // `as const` is required for type inference});Direct call logs at info level. Each bucket also has level sub-methods:
// Direct call — logs at "info" levelgunsole.auth("User logged in");
// Level sub-methodsgunsole.auth.info("User logged in");gunsole.auth.debug("Token refresh started");gunsole.auth.warn("Token expires in 5 minutes");gunsole.auth.error("Login failed", { context: { reason: "invalid_password" }, tags: { method: "oauth" },});gunsole.auth.fatal("Auth service unreachable");
gunsole.payments("Checkout completed", { context: { amount: 99.99, currency: "USD" }, tags: { provider: "stripe" },});
gunsole.database.warn("Slow query detected", { context: { query: "SELECT * FROM users", duration: 2300 },});Method signature
Section titled “Method signature”gunsole.auth(message: string, options?: BucketLogOptions): voidgunsole.auth.info(message: string, options?: BucketLogOptions): voidgunsole.auth.debug(message: string, options?: BucketLogOptions): voidgunsole.auth.warn(message: string, options?: BucketLogOptions): voidgunsole.auth.error(message: string, options?: BucketLogOptions): voidgunsole.auth.fatal(message: string, options?: BucketLogOptions): voidBucketLogOptions is LogOptions without bucket and message (both are positional/implied):
{ context?: Record<string, unknown>; tags?: Partial<Tags> | TagEntry<Tags>[]; traceId?: string;}So when you call gunsole.payments("Checkout completed", { tags: ... }), it’s equivalent to:
gunsole.info({ bucket: "payments", message: "Checkout completed", tags: { ... },});Escape hatch
Section titled “Escape hatch”The log() API still works with any bucket string. Bucket accessors are the typed surface; log() is the untyped escape hatch.
// Typed — autocomplete + compile-time checkgunsole.payments("User paid");
// Untyped — any bucket string acceptedgunsole.log({ bucket: "payments", message: "User paid" });gunsole.log({ bucket: "some-dynamic-bucket", message: "..." });Reserved bucket names
Section titled “Reserved bucket names”Bucket names that conflict with GunsoleClient methods are rejected at both compile time and runtime:
log, info, debug, warn, error, fatal,setUser, setSessionId, setDebug, flush, destroy, isDestroyed,drainBatch, projectId, apiKey, logEndpoint,attachGlobalErrorHandlers, detachGlobalErrorHandlers// Compile-time errorconst gunsole = createGunsoleClient({ projectId: "my-app", mode: "local", buckets: ["auth", "log"] as const, // ^^^^^ ❌ Type error: "log" is a reserved bucket name});Backward compatibility
Section titled “Backward compatibility”Omitting buckets returns a plain GunsoleClient — no phantom properties, no behavior change.
// No buckets — returns GunsoleClient<Tags> (clean type, no index signature)const gunsole = createGunsoleClient({ projectId: "my-app", mode: "local",});
// No bucket accessors — must specify bucket in every callgunsole.info({ bucket: "auth", message: "User logged in" });gunsole.error({ bucket: "payments", message: "Charge failed" });TypeScript exports
Section titled “TypeScript exports”| Export | Description |
|---|---|
BucketLogOptions | Log options for bucket methods (no bucket/message) |
BucketLogger | Callable bucket accessor interface |
WithBuckets | Mapped type adding bucket accessors to client |
ReservedBucketName | Union of reserved bucket names |
ValidateBuckets | Compile-time bucket name validator |