@feelai/fetch-client
v1.0.10
Published
A type-safe HTTP/WebSocket client that consumes contracts defined with `@feelai/contract`. It provides fully-inferred TypeScript types for API calls, streaming, and socket connections — no manual type annotations required.
Readme
@feelai/fetch-client
A type-safe HTTP/WebSocket client that consumes contracts defined with @feelai/contract. It provides fully-inferred TypeScript types for API calls, streaming, and socket connections — no manual type annotations required.
Features
- Type-Safe API Calls: Input and output types are automatically inferred from your contract.
- Input Validation: Validates request input against the contract schema at runtime using
typeboxbefore sending. - Streaming Support: Connect to stream endpoints over WebSocket with typed event emitters.
- Socket Support: Real-time bidirectional communication with typed client/server events.
- Configurable Headers & Query: Hook into request lifecycle to inject auth tokens or custom query params.
- Large Payload Chunking: Automatically splits large WebSocket messages into 1MB chunks.
Installation
bun add @feelai/fetch-clientUsage
1. Create a Client
Pass your contract and a base URL to createClient (or instantiate FetchClient directly).
import { createClient } from "@feelai/fetch-client";
import { todoListContract } from "./todoListContract";
const client = createClient(todoListContract, "https://api.example.com");2. Call API Endpoints
Use client.fetch() to call HTTP endpoints defined in the contract's apiMap. The method, input shape, and response type are all inferred automatically.
// No input required
const tasks = await client.fetch("getTasks");
// ^? Task[]
// With typed input
const newTask = await client.fetch("createTask", { title: "Buy groceries" });
// ^? TaskAll requests are sent as
POSTwith a JSON body andcredentials: "include"by default.
3. Connect to a Stream
Use client.stream() to open a WebSocket connection to a stream endpoint. Returns a typed Stream object with typed event handlers.
const stream = await client.stream("generateTask", { content: "Write a summary" });
stream.on("chunk", (data) => {
console.log("Partial:", data);
});
stream.on("end", (data) => {
console.log("Done:", data);
});
stream.on("error", (err) => {
console.error("Error:", err);
});4. Connect to a Socket
Use client.socket() to open a typed bidirectional WebSocket connection for real-time communication.
const socket = await client.socket("taskUpdates");
// Listen for server events
socket.on("taskCreated", (task) => {
console.log("New task:", task);
});
// Send client events
socket.emit("subscribe", {});5. Inject Headers & Query Params
Customize outgoing requests by assigning to initHeaders and initStreamQuery on the client instance.
client.initHeaders = () => ({
Authorization: `Bearer ${getToken()}`,
});
client.initStreamQuery = () => ({
token: getToken(),
});6. Advanced Options
The fetch() method accepts standard RequestInit options plus extras:
| Option | Type | Description |
| ---------------- | ------------------------ | ------------------------------------------------ |
| query | Record<string, string> | Appends query parameters to the URL. |
| skipValidation | boolean | Skips runtime input validation (default: false). |
const tasks = await client.fetch("getTasks", undefined, {
query: { page: "1" },
skipValidation: true,
});API Reference
createClient(contract, baseUrl)
Factory function. Returns a FetchClient instance bound to the given contract and base URL.
FetchClient<TContract>
| Member | Type | Description |
| -------------------------------- | -------------------------------------- | ------------------------------------------------------------- |
| initHeaders | () => Record<string, string> \| void | Called before every HTTP request to inject headers. |
| initStreamQuery | () => Record<string, string> \| void | Called before every stream connection to inject query params. |
| fetch(path, input?, options?) | Promise<Output> | Calls an HTTP API endpoint from the contract. |
| stream(path, input?, options?) | Promise<Stream<Events>> | Opens a WebSocket stream connection. |
| socket(path, query?) | Promise<SocketClient<...>> | Opens a bidirectional WebSocket socket connection. |
Related Packages
@feelai/contract— Define API, stream, and socket contracts.@feelai/stream— TheStreamtype used by streaming responses.
