@gambar/bearvision-sdk (0.2.11)

Published 2026-07-08 14:27:35 -04:00 by GamBar

Installation

@gambar:registry=
npm install @gambar/bearvision-sdk@0.2.11
"@gambar/bearvision-sdk": "0.2.11"

About this package

BearVision — Telemetry SDK

A lightweight observability SDK: error tracking, analytics, and performance metrics in one protobuf-first pipeline.

Quick start

Go

# ~/.netrc — one-time setup (replace <token> with your Forgejo token)
echo "machine git.gamriel.com login <user> password <token>" >> ~/.netrc

# Tell Go to use the private proxy + skip checksum DB
go env -w GOPROXY=https://git.gamriel.com/api/packages/GamBar/go/,https://proxy.golang.org,direct
go env -w GONOSUMCHECK=git.gamriel.com
go env -w GONOSUMDB=git.gamriel.com

go get git.gamriel.com/GamBar/BearVision-Proto/sdk/go@latest
import "git.gamriel.com/GamBar/BearVision-Proto/sdk/go"

client := bearvision.New("my-project", "sk-abc123", "https://ingest.example.com/events")

client.Error("nil pointer", "stack trace...")
client.Track("page_view", nil)
client.Track("signup", map[string]string{"plan": "pro"})
client.Perf("db_query", 42.5)
client.Track("click", map[string]string{"label": "signup"}, map[string]string{"experiment": "A"})

JS/TS

npm config set @gambar:registry https://git.gamriel.com/api/packages/GamBar/npm/
npm config set //git.gamriel.com/api/packages/GamBar/npm/:_authToken=your_token
npm install @gambar/bearvision-sdk
import { BearVisionClient, Level } from "@gambar/bearvision-sdk";

const client = new BearVisionClient({
  projectId: "my-project",
  apiKey: "sk-abc123",
  endpoint: "https://ingest.example.com/events",
});

await client.error("nil pointer", "stack trace...");
await client.error("crash", "stack...", Level.WARNING, { env: "staging" });
await client.track("page_view", { source: "email" });
await client.perf("page_load", 1234.5);
// Optional bag as last arg:
await client.track("click", { label: "signup" }, { experiment: "A" });
// Get server-echoed ID from errors:
const id = await client.error("crash", "at line 42");

Script embed — zero config

<script
  src="https://track.gamriel.com/scripts/bv.js"
  data-project="my-project"
  data-key="sk-abc123"
  data-endpoint="https://ingest.example.com/events"
></script>

Captures errors, page views, web vitals automatically. Manual API:

<script>
bv.track("button_click");
bv.track("signup", { plan: "premium" });
bv.error("it broke");
bv.error(new Error("network failure"), { component: "FormField" });
bv.perf("custom_api_call", 342);
</script>

Go SDK

Creating a client

// Minimum config — endpoint is required.
client := bearvision.New("my-project", "sk-abc123", "https://ingest.example.com/events")

// With custom options:
client := bearvision.New("my-project", "sk-abc123", "https://ingest.example.com/events")
client.Encoding = bearvision.EncodingJSON   // default: binary protobuf
client.HTTPClient = &http.Client{Timeout: 5 * time.Second}

Sending events

// Error — message, stacktrace, level, optional bag
client.Error("nil pointer dereference", "at invoice.go:213", bearvision.Level_ERROR)
client.Error("crash", "stack...", bearvision.Level_WARNING, map[string]string{"env": "staging"})

// Track — action, optional data, optional bag
client.Track("page_view", nil)
client.Track("signup", map[string]string{"plan": "pro"}, map[string]string{"experiment": "A"})

// Perf — metric, value, optional unit (default "ms")
client.Perf("db_query", 42.5)
client.Perf("page_load", 1230.0, "s")

All three auto-generate an ID and timestamp. Error() returns the server-echoed event ID for cross-referencing:

id, err := client.Error("crash", "at line 42")
// id is confirmed by the server — use it to look up the event later

Track() and Perf() return only an error. Use client.Send(ctx, evt) for advanced use cases (context, client info, custom error levels).

Advanced usage

For context, bag, client info, or custom error levels, build an Event directly:

evt := &bearvision.Event{
    Id:        myID,
    Timestamp: time.Now().UnixMilli(),
    Context: &bearvision.Context{
        Environment: "production",
        Release:     "v2.14.3",
        SessionId:   "sess_abc123",
    },
    Client: &bearvision.ClientInfo{
        Browser: "Chrome 124",
        Country: "US",
    },
    Bag: map[string]string{"experiment": "new-checkout"},
    Payload: &bearvision.Event_Error{
        Error: &bearvision.ErrorEvent{
            Message:    "crash",
            Stacktrace: "goroutine 1 [running]:\nmain.go:42",
            ErrorType:  "RuntimePanic",
            Level:      bearvision.Level_FATAL,
        },
    },
}
client.Send(context.Background(), evt)

Server — decoding events

import (
    bv "git.gamriel.com/GamBar/BearVision-Proto/sdk/go"
    "google.golang.org/protobuf/encoding/protojson"
    "google.golang.org/protobuf/proto"
)

func eventsHandler(w http.ResponseWriter, r *http.Request) {
    body, _ := io.ReadAll(r.Body)
    var evt bv.Event

    switch r.Header.Get("Content-Type") {
    case "application/json":
        protojson.Unmarshal(body, &evt)
    default:
        proto.Unmarshal(body, &evt)
    }

    if evt.Id == "" {
        http.Error(w, "missing id", 400)
        return
    }

    // Determine event type from the oneof payload
    switch {
    case evt.GetError() != nil:
        // handle error
    case evt.GetAnalytics() != nil:
        // handle analytics
    case evt.GetPerformance() != nil:
        // handle performance
    }
}

JS/TS SDK

Creating a client

const client = new BearVisionClient({
  projectId: "my-project",
  apiKey: "sk-abc123",
  endpoint: "https://ingest.example.com/events",
  encoding: "binary", // or "json" (default: "binary")
});

Sending events

// Error with optional stacktrace, level, and bag
await client.error("nil pointer", "at line 42");
await client.error("crash", "stack...", Level.WARNING, { env: "staging" });

// Track with optional data and bag
await client.track("page_view", { source: "email" });
await client.track("click", { label: "signup" }, { experiment: "A" });

// Perf with optional unit and bag
await client.perf("page_load", 1234.5);
await client.perf("db_query", 42.0, "ms", { db: "postgres" });

All three auto-generate an ID and timestamp. client.error() returns the server-echoed event ID:

const id = await client.error("crash", "at line 42");
// id is confirmed by the server — use it to look up the event later

client.track() and client.perf() return Promise<void>. Use client.send() for advanced cases (it also returns the echoed event ID):

import { create } from "@bufbuild/protobuf";
import { EventSchema, ContextSchema, ClientInfoSchema, ErrorEventSchema, Level } from "@gambar/bearvision-sdk";

const evt = create(EventSchema, {
  context: create(ContextSchema, { environment: "production", release: "v2.14.3" }),
  client: create(ClientInfoSchema, { browser: "Chrome 124", country: "US" }),
  bag: { experiment: "new-checkout" },
  payload: { case: "error", value: create(ErrorEventSchema, { message: "crash", level: Level.FATAL }) },
});
await client.send(evt);

Script embed — zero-config for websites

One <script> tag. No build step, no npm. 3.6 KB minified.

<script
  src="https://track.gamriel.com/scripts/bv.js"
  data-project="my-project"
  data-key="sk-abc123"
  data-endpoint="https://ingest.example.com/events"
></script>

What it captures automatically

Signal Event Details
window.onerror ErrorEvent message, stacktrace, file, line, column
unhandledrejection ErrorEvent reason message + stack
Navigation timing PerformanceEvent domComplete, domInteractive, ttfb, dnsTime, tcpTime, tlsTime, total
First contentful paint PerformanceEvent FCP value in ms
Largest contentful paint PerformanceEvent LCP value (2s timeout fallback)
Page view AnalyticsEvent path, title, url, referrer

Manual API

<script>
// Track — action + optional data (→ AnalyticsEvent.data)
bv.track("button_click");
bv.track("signup", { plan: "premium", source: "banner" });

// Error — string or Error + optional bag (→ Event.bag), returns server-echoed event ID
const id = await bv.error("it broke");
bv.error(new Error("network failure"));
bv.error("validation failed", { component: "FormField", field: "email" });

// Perf — metric + value (unit is always "ms")
bv.perf("custom_api_call", 342);

// Debug: set window.__bvOnError to receive send failures
window.__bvOnError = (err) => console.error("[BearVision]", err);
</script>

Proto reference

The single proto/event.proto file defines the wire format:

Event              — envelope (id, project, timestamp, context, client, bag)
├── ErrorEvent     — crashes, exceptions, stack traces
├── AnalyticsEvent — page views, button clicks, behavioural signals
└── PerformanceEvent — latencies, db timings, web vitals

EventResponse      — server response (echoes the event id for cross-referencing)

Servers must respond with EventResponse { string id = 1 } using the same Content-Type as the request. The SDKs parse the echoed ID — client.Error() and bv.error() return it, confirming the event was received.

Key design decisions:

  • No PII — no IP, user agent, cookies, or visitor IDs. Privacy-first by default.
  • Client-side parsingClientInfo holds parsed values (browser, OS, device), never raw user-agent strings.
  • Server-side fingerprinting — errors are grouped by fingerprint computed on the server, so clients can't poison grouping.
  • No EventType enum — the event type is determined by which oneof payload is set, eliminating enum/oneof drift.
  • Flat bag — a single map<string, string> on Event for arbitrary attributes, instead of a nested Metadata wrapper.

Edit proto/event.proto → run just proto → Go + JS stubs regenerate automatically.


Development

just proto       # regenerate Go + JS protobuf stubs
just test        # proto → typecheck → Go tests → JS tests → sync check
just typecheck   # TypeScript checking only
just check-sync  # verify Go and JS SDK method signatures are in sync
just bundle      # build embed script (minified) from src/embed.ts
just all         # proto + typecheck + tests + bundle

Layout

proto/                        # Protobuf schema
  event.proto

sdk/go/                       # Go SDK
  client.go                   # BearVisionClient + Error/Track/Perf
  event.go                    # Event constructors
  event.pb.go                 # generated protobuf types

sdk/js/                       # JS/TS SDK
  src/client.ts               # BearVisionClient (npm package)
  src/embed.ts                # embed entrypoint (window.bv)
  src/proto/event_pb.js       # generated protobuf types
  dist/bv.js                  # bundled embed script (minified)

Dependencies

Development dependencies

ID Version
@bufbuild/protobuf ^2.12.1
jsdom ^29.1.1
rolldown ^1.1.3
ts-patch ^3.3.0
typescript ^5.8.0
vitest ^3.0.0
Details
npm
2026-07-08 14:27:35 -04:00
0
MIT
42 KiB
Assets (1)
Versions (5) View all
0.2.12 2026-07-08
0.2.11 2026-07-08
0.2.2 2026-07-08
0.2.0 2026-07-08
0.1.0 2026-07-08