@arpabet/vrpc

value-rpc client for browsers and Node: msgpack/JSON codecs, streams with credit flow control, reconnect with hash-chain resumption, reverse calls
1,001
Install
npm install @arpabet/vrpc
Latest Version:0.2.1
License:Apache-2.0
Last Updated:Aug 5, 2026
Links: GitHub  ·  npm
Maintainer: karagatan

@arpabet/vrpc

value-rpc protocol core for browsers, Node ≥ 22, and Bun. Zero runtime dependencies. See the repo README for the full tour.

import { createClient } from "@arpabet/vrpc";

const client = createClient({ url: "wss://example.com/rpc" });

await client.call("greet", ["world"]);                    // unary
for await (const v of client.getStream("count", [10])) {} // server stream
await client.putStream("upload", null, values);           // client stream
const chat = client.chat("chat.echo");                    // bidirectional

client.addFunction("notify", (args) => null);             // server calls YOU

Options (createClient)

Option Default Meaning
url — ws:// / wss:// endpoint
codec "msgpack" "msgpack" works with every server; "json" needs a JSON-codec server (negotiated via the vrpc.json subprotocol)
auth — credential (or async factory) for the handshake auth field
timeoutMs 5000 default unary timeout, sent as the request SLA
connectTimeoutMs 10000 dial + handshake bound
metadata — Metadata or per-request factory (traceparent, …)
reconnect enabled backoff options or false
resume true hash-chain session resumption across reconnects
maxPending 4096 per-stream receive window (flow-control credit)
dialect standard wire field names; must match the server's Dialect
webSocket / dialer global / WS overrides for tests and custom transports

Error model

Every failure is a VrpcError with a code mirroring valuerpc.Code:

try {
  await client.call("user.get", [42]);
} catch (err) {
  if (err instanceof VrpcError && err.code === Code.Unavailable) retryLater();
}

Timeouts map to Code.DeadlineExceeded, aborts to Code.Canceled, connection loss to Code.Unavailable — the same branches a Go caller writes with valuerpc.CodeOf.

Value model

null | boolean | number | bigint | string | Uint8Array | Value[] | {…} | VrpcDouble | VrpcDecimal | VrpcExt

  • Integer numbers encode as value LONG; beyond ±2^53 pass a bigint (exact int64 over msgpack). double(x) forces a DOUBLE encoding.
  • Uint8Array is value RAW bytes.
  • Maps are plain objects; keys encode sorted (canonical frames).
  • VrpcDecimal (decimal("1.045")) and VrpcExt round-trip over msgpack.

Streams & flow control

getStream returns an async iterator; credit is granted to the server as you consume, so a slow consumer backpressures the producer losslessly. break/return sends a CancelRequest. putStream/chat.send honor the credit the server grants — a misbehaving peer is cut off with Code.ResourceExhausted, exactly like the Go client.

Reverse calls

The server can invoke functions and open streams on this client (addFunction, addOutgoingStream, addIncomingStream, addChat) — the same registrar surface valueserver.Server has. Handlers receive (args, ctx) where ctx.signal aborts on cancellation/disconnect.

Related Packages

@vue-solana/core

Framework-agnostic primitives for Vue Solana libraries.

6,830 0
nuxt-remote-fn

Remote Functions. Instead of Event Handlers.

1,948
silgi

The fastest end-to-end type-safe RPC framework for TypeScript — compiled pipelin...

29,920 35
@fougere/nuxt

The Nuxt module: Fougere's client primitives and server surface.

9,076 6
nuxt-procedures

Nuxt module to define and easily consume your backend API in a validated and typ...

1,678 2

Version History

Version Released License
0.2.1 Apache-2.0
0.2.0 Apache-2.0