Releases: Crossdeckhq/buckets-oss
Release list
v0.15.2 — docs: name operations at the gateway
Tip: wrap your route/resolver once at the gateway/router and every read inherits the operation name (bucket(path) in a tRPC base procedure, bucket('users.show', handler) on an Express route). Inner bucket() still wins. Docs only.
v0.15.1 — docs: withActor (async-safe WHO)
Documents withActor(id, fn) — the async-safe actor wrapper — alongside setActor. In an async handler (Firebase/Cloud Functions, tRPC resolvers) a bare setActor can be lost across an await; withActor (AsyncLocalStorage.run) keeps the user across awaited reads. Docs only — both APIs shipped in 0.14.0.
v0.15.0 — the browser identity seam
Adds the browser-side bridge: initBucketsWeb() registers the same global seam the server does, so the Crossdeck web SDK drives WHO on identify() / reset() with no cross-import. Completes the cross-match across both surfaces (server was 0.14.0). Additive, backward-compatible.
v0.14.1 — fix: the local readout now shows Who × What
Fix: MirrorSink was silently dropping the cross-match — npx @cross-deck/buckets showed the bucket table but never the Who caused the reads / Who × what sections for local OSS users. The local readout now carries the actor maps through (regression test added).
Docs: Quickstart now leads with a 30-second no-database demo, and an explicit "Seeing No readout?" note covers the empty-state every first-time user hits.
v0.14.0 — the cross-match: reads by user × function + npx CLI
The moat, in the OSS. Tell Buckets who's behind a request — one line, setActor(userId), with the id you already have — and every read attributes to the person and the function that spent it. No standalone read tool can do this.
setActor(userId)→byActor(WHO) +byActorLabel(WHO × WHAT), two independent axes. Server + browser.anonymousfor no-identity reads;machinefor background work (still by tenant).- Feature-first WHAT —
bucket() ?? feature ?? route ?? collection(the operation, not the page). npx @cross-deck/buckets— prints WHO × WHAT to the terminal. Free, offline, no account.- Decoupled identity bridge so the Crossdeck SDK (or your own boundary) drives it without either package depending on the other.
Additive and backward-compatible — byLabel unchanged, the WHO dimension is absent until you wire identity. README reframed to "who caused it = the user."
v0.13.1 — Serverless docs (adapter-agnostic)
Docs-only release. Refreshes the README/npm page with a prominent Serverless — wrap your handlers section: the published withBuckets one-liner, zero added cost (uses CPU already billed, no instance kept awake), and the adapter-agnostic point — one wrap flushes the meter, covering Firestore / MongoDB / Postgres at once. No code change since 0.13.0.
v0.13.0 — honest README + loud untagged (unknown>col:x)
Honest, ship-ready
- README corrected — no per-user claims. The tag is
{origin, feature, appId, env}: there is no user dimension. "Who caused it" is the origin (a real user vs a machine). Raw counts only — no currency. - Untagged is loud — un-bucketed reads surface as
unknown>col:x(env-rooted:server>unknown>col:x), never a silent bare collection. Server meter +/webadapter. - Verified: env root-stamp, observe-only adapters, raw units, no user dimension, never-throws.
withBuckets()serverless flush unchanged.
v0.12.0 — withBuckets() serverless flush
withBuckets(handler) — keep the no-slip promise on serverless
The collector ships counts on a ~1/min timer — right for a long-lived server, wrong for serverless. Lambda / Cloud Functions / Cloud Run / Vercel freeze the container the instant a handler returns, so a sub-minute invocation's counted reads are billed by the provider but never shipped. withBuckets() closes that blind spot.
import { withBuckets } from "@cross-deck/buckets";
export const handler = withBuckets(async (event) => { /* …db reads… */ });
export const handler = withBuckets("nightly-export", async (event) => { /* … */ });- Flushes the meter once, in a
finally, before the function returns — on success and on throw. - Transparent: forwards args +
this, returns/throws unchanged. - A flush fault can never escape into the caller; fails fast on misuse.
- Fully typed; 7 new tests; 45/45 suite green.
v0.11.0 — per-environment read attribution
Every bucket now shows which environment a read ran in (server / web / dashboard), stamped as the root of the bucket path. Zero extra reads (string prepend), backward compatible (pre-stamp reads render unknown). Phase 1 of the per-environment design: server + web. See README → "Server and browser".
v0.10.2
Docs: de-Firestore the framing — Buckets supports Firestore, MongoDB and Postgres (server + browser). Badge/API/roadmap/description corrected; broken npm badge fixed. No code change.