garazyk-gruszka

star 0

Strongly typed XRPC client, firehose consumer, lexicon resolution, and account utilities for AT Protocol services from the @garazyk/gruszka Deno package. Use when making XRPC calls, consuming the firehose, resolving lexicons dynamically, or generating account credentials.

jvalinsky By jvalinsky schedule Updated 5/24/2026

name: garazyk-gruszka description: Strongly typed XRPC client, firehose consumer, lexicon resolution, and account utilities for AT Protocol services from the @garazyk/gruszka Deno package. Use when making XRPC calls, consuming the firehose, resolving lexicons dynamically, or generating account credentials.

Garazyk Gruszka — AT Protocol Client

@garazyk/gruszka provides a strongly typed XRPC client with actor-scoped sub-clients, firehose consumption, dynamic lexicon resolution, and account utilities. Base package with no import constraints.

When to Use

  • Make XRPC queries or procedures against an AT Protocol service
  • Consume the firehose (subscribeRepos) WebSocket stream
  • Resolve lexicons dynamically via DNS/DID/record
  • Generate invite codes, passwords, or random strings
  • Access typed namespace clients (app.bsky, chat.bsky, com.atproto)

Quick Start

import { XrpcClient, XrpcError } from "@garazyk/gruszka";
import { FirehoseClient, parseFirehoseFrame } from "@garazyk/gruszka";
import { generateInviteCode, generatePassword } from "@garazyk/gruszka";

Subpath imports:

import { resolveLexicon, DenoDnsResolver, HttpDidResolver, HttpRecordFetcher }
  from "@garazyk/gruszka/lexicon-resolution";
import { /* generated lexicon definitions */ } from "@garazyk/gruszka/lexicons";
import { /* hand-written namespace clients */ } from "@garazyk/gruszka/legacy-clients";
import { formatBytes } from "@garazyk/gruszka/format";

API Reference

XrpcClient

Export Type Description
XrpcClient class High-level XRPC client with namespace sub-clients
XrpcError class XRPC-specific error with status and body
client.as(actor) ActorScopedClient Bind all requests to an actor's identity
client.asAdmin(token) ActorScopedClient Bind requests with admin token
client.waitForHealthy() async → void Poll /_health until service responds

ActorScopedClient

Returned by client.as(actor) or client.asAdmin(token). Every request includes the actor's bearer token.

Property Type Description
raw ActorRawClient Raw XRPC/HTTP methods (get, post, query, procedure, xrpcGet, xrpcPost, postBinary, httpGet, httpPost)
api GeneratedClient Fully typed namespace client (e.g., api.app.bsky.actor.getProfile(...))
repo ActorRepoClient Record CRUD (createRecord, getRecord, putRecord, deleteRecord, applyWrites, listRecords, describeRepo, listMissingBlobs, uploadBlob)
graph ActorGraphClient Social graph (getFollows, getFollowers, getBlocks, getMutes, muteActor, unmuteActor, getRelationships, getStarterPacks, getList, getLists)
feed ActorFeedClient Feed/timeline (getProfile, getTimeline, getAuthorFeed, getPostThread, getLikes, searchActors, getActorLikes, getPosts, getRepostedBy, getFeed, getFeedGenerators)

Firehose

Export Type Description
FirehoseClient class WebSocket client for subscribeRepos
FirehoseEvent class Decoded event (seq, type, payload, header, body)
parseFirehoseFrame(payload) function Parse raw binary frame to header + body
firehoseEventFromFrame(frame) function Convert parsed frame to FirehoseEvent
FirehoseFrameParseError class Error on invalid DAG-CBOR

Lexicon Resolution

Export Type Description
resolveLexicon(nsid, ports) async → Result Dynamic DNS/DID/record lexicon resolution
ResolutionPorts type { dns, did, record } adapter interfaces
DenoDnsResolver class DNS resolution via Deno APIs
HttpDidResolver class DID resolution via HTTP
HttpRecordFetcher class Record fetch via HTTP

Account Utilities

Export Type Description
generateInviteCode() → string Generate a random invite code
generatePassword() → string Generate a random password
randomString(length) → string Generate a random string

Transport

Export Type Description
TransportLayer class Low-level HTTP transport with response recording
TransportError class Transport-level error
TransportResponse type { method, status, body, time }

Key Patterns

Create a client and make typed calls

const client = new XrpcClient("http://localhost:2583");
await client.waitForHealthy();

const luna = client.as(actor);
const profile = await luna.feed.getProfile("alice.test");
const timeline = await luna.feed.getTimeline(25);

Actor-scoped repo operations

const luna = client.as(actor);
await luna.repo.createRecord({
  collection: "app.bsky.feed.post",
  record: { $type: "app.bsky.feed.post", text: "Hello!", createdAt: new Date().toISOString() },
});
const records = await luna.repo.listRecords({ collection: "app.bsky.feed.post", limit: 10 });

Consume the firehose

import { FirehoseClient, parseFirehoseFrame } from "@garazyk/gruszka";

const firehose = new FirehoseClient("ws://localhost:2584/xrpc/com.atproto.sync.subscribeRepos");
for await (const event of firehose) {
  console.log(`seq=${event.seq} type=${event.type}`);
}

Resolve a lexicon dynamically

import { resolveLexicon } from "@garazyk/gruszka/lexicon-resolution";
import { DenoDnsResolver, HttpDidResolver, HttpRecordFetcher } from "@garazyk/gruszka/lexicon-resolution";

const result = await resolveLexicon("app.bsky.feed.post", {
  dns: new DenoDnsResolver(),
  did: new HttpDidResolver(),
  record: new HttpRecordFetcher(),
});
if (result.ok) console.log("Resolved:", result.value.id);

Boundary Rules

Gruszka is the base package with no import constraints. All other packages may import from gruszka.

Related Skills

  • garazyk-hamownia — Re-exports resolveLexicon and uses XrpcClient for scenarios
  • garazyk-schemat — Provides service URLs that feed into XrpcClient construction
  • garazyk-laweta — Docker client used to start services that XrpcClient connects to
Install via CLI
npx skills add https://github.com/jvalinsky/garazyk --skill garazyk-gruszka
Repository Details
star Stars 0
call_split Forks 0
navigation Branch main
article Path SKILL.md
More from Creator