Reference
@rippledb/remote-http
HTTP transport for client-server sync
@rippledb/remote-http
HTTP transport implementation of the Remote interface. Connects clients to RippleDB servers over HTTP.
Installation
pnpm add @rippledb/remote-httpnpm install @rippledb/remote-httpyarn add @rippledb/remote-httpUsage
import { createHttpRemote } from "@rippledb/remote-http";
import { createReplicator } from "@rippledb/client";
const remote = createHttpRemote<MySchema>({
baseUrl: "https://api.example.com",
});
// Use with replicator
const replicator = createReplicator({
stream: "user-123",
store,
remote,
});
await replicator.sync();createHttpRemote
function createHttpRemote<S extends RippleSchema>(
opts: HttpRemoteOptions,
): Remote<S>;Options:
type HttpRemoteOptions = {
baseUrl: string;
fetch?: typeof fetch;
headers?: Record<string, string>;
};| Option | Type | Description |
|---|---|---|
baseUrl | string | Server URL (trailing slash removed automatically) |
fetch | typeof fetch? | Custom fetch implementation (default: global fetch) |
headers | Record<string, string>? | Additional headers for all requests |
Endpoints
The HTTP remote expects two endpoints:
POST /pull
Pull changes from the server.
Request:
{
"stream": "user-123",
"cursor": "42",
"limit": 100
}Response:
{
"changes": [
{
"stream": "user-123",
"entity": "todos",
"entityId": "todo-1",
"kind": "upsert",
"patch": { "title": "Buy milk" },
"tags": { "title": "1706123456789:0:server-1" },
"hlc": "1706123456789:0:server-1"
}
],
"nextCursor": "43"
}POST /append
Append changes to the server.
Request:
{
"stream": "user-123",
"idempotencyKey": "req-abc",
"changes": [
{
"stream": "user-123",
"entity": "todos",
"entityId": "todo-1",
"kind": "upsert",
"patch": { "title": "Buy milk" },
"tags": { "title": "1706123456789:0:client-1" },
"hlc": "1706123456789:0:client-1"
}
]
}Response:
{
"accepted": 1
}Server Implementation
Here's a minimal Express server that works with the HTTP remote:
import express from "express";
import { SqliteDb } from "@rippledb/db-sqlite";
const app = express();
app.use(express.json());
const db = new SqliteDb<MySchema>({ filename: "./data.db" });
app.post("/pull", async (req, res) => {
const { stream, cursor, limit } = req.body;
const result = await db.pull({ stream, cursor, limit });
res.json(result);
});
app.post("/append", async (req, res) => {
const { stream, idempotencyKey, changes } = req.body;
const result = await db.append({ stream, idempotencyKey, changes });
res.json(result);
});
app.listen(3000);Authentication
Add authentication headers:
const remote = createHttpRemote({
baseUrl: "https://api.example.com",
headers: {
Authorization: `Bearer ${token}`,
},
});Custom Fetch
Use a custom fetch implementation (useful for testing or React Native):
import nodeFetch from "node-fetch";
const remote = createHttpRemote({
baseUrl: "https://api.example.com",
fetch: nodeFetch as unknown as typeof fetch,
});Error Handling
The remote throws on non-2xx responses:
try {
await remote.pull({ stream: "user-123", cursor: null });
} catch (error) {
// error.message: "remote.pull failed: 401"
}Content Type
All requests use Content-Type: application/json.
Related
- Client Reference — Replicator and Store
- Server Reference — Db interface
- Guides: Client Sync — Full sync setup guide