Binary grpc-web
Reach for this only when you need protobuf on the wire. Connect JSON is debuggable in a way binary frames never are.
import { grpcTransport } from "@tahanabavi/typefetch-grpc";
import { GetUserRequest, GetUserResponse } from "./gen/user_pb";
grpcTransport({
codec: {
encode: (message) => GetUserRequest.toBinary(message),
decode: (bytes) => GetUserResponse.fromBinary(bytes),
},
});The codec deals only in message bytes. This package owns the 5-byte
length-prefix framing, the 0x80 trailer frame, percent-decoding of
grpc-message, and trailers-only responses — protocol concerns, not schema
ones. That boundary is what keeps protobuf out of everything published here.
Set a codec per endpoint to mix binary and JSON RPCs on one client.
The failure everyone hits first
A browser calling a cross-origin grpc-web server needs the server to expose the trailer:
Access-Control-Expose-Headers: grpc-status, grpc-messageWithout it the trailer is invisible to the client even though it was sent, and every call fails. This transport detects that exact case and says so in the error message rather than reporting a generic parse failure.
Binary grpc-web also generally needs a proxy (Envoy, or a server with grpc-web
support built in) in front of a plain gRPC server. grpc-web-text (base64) is
not supported.
Capabilities
onUploadProgress and onDownloadProgress do nothing here — a unary RPC is one
message in and one message out. The client warns rather than silently never
calling your handler, because a progress bar frozen at zero reads as a hung app.
Streaming (server, client, bidi) is deliberately out of scope: it cannot return
Promise<T>, so it would change the shape of every generated method. Use
@tahanabavi/typesocket for streams.