JavaScript SDK
@runnev/client — официальный SDK для JavaScript и TypeScript. Ноль зависимостей во
время выполнения, поставляется в ESM и CommonJS, работает в Node 18+ и современных браузерах на
встроенных fetch и ReadableStream.
Установка
npm install @runnev/client # v1.6.1Типы включены в пакет; отдельный пакет @types добавлять не нужно.
Настройка
import { Runnev } from "@runnev/client";
const runnev = new Runnev({
apiKey: process.env.RUNNEV_API_KEY, // обязательно
baseUrl: "https://runnev.dev/v1", // по умолчанию
timeoutMs: 30000, // таймаут на запрос (не на поток подписки)
maxRetries: 4, // повторы при 429 / 5xx, с backoff
});В браузере создавайте его только с демо-ключом только для чтения; никогда не отправляйте ключ
rnv_live_ на клиентское устройство.
Публикация
// создание (серверный id)
const stream = await runnev.createStream({ name: "orders-eu", retentionSeconds: 86400 });
// публикация под явным номером — идемпотентна, безопасно повторять
const res = await runnev.publish(stream.id, 41823, [
{ type: "order.paid", id: "o_5521", amount: 1999 },
]);
console.log(res.cursor, res.duplicate); // 41823 false
// серверный номер
await runnev.publishAuto(stream.id, [{ type: "tick" }]);
// сырые байты для потока в режиме raw
await runnev.publishRaw(stream.id, 9001, new Uint8Array(protobufBytes));Подписка
Subscribe возвращает асинхронный итерируемый объект и также принимает колбэки. Он переподключается автоматически, возобновляя с последнего увиденного номера.
// асинхронная итерация
for await (const batch of runnev.subscribe(stream.id, { cursor: 0 })) {
console.log(batch.seq, batch.events);
}
// или колбэки, с AbortSignal для остановки
const controller = new AbortController();
runnev.subscribe(stream.id, {
cursor: "head",
signal: controller.signal,
onOpen: () => console.log("connected"),
onBatch: (batch) => console.log(batch.seq, batch.events),
onError: (err) => console.error(err.code, err.requestId),
});
// позже: controller.abort();Возобновление между перезапусками
let last = loadCursor() ?? -1; // из вашего надёжного хранилища
for await (const batch of runnev.subscribe(stream.id, { cursor: last })) {
if (batch.seq <= last) continue; // дедуп «не менее одного раза»
await handle(batch);
last = batch.seq;
saveCursor(last);
}Обработка ошибок
Сбои бросают подкласс RunnevError, несущий машиночитаемый код, идентификатор
запроса, HTTP-статус и ссылку на документацию.
import { RunnevError, RateLimitError, AuthenticationError } from "@runnev/client";
try {
await runnev.publish(id, seq, events);
} catch (err) {
if (err instanceof RateLimitError) {
await sleep(err.retryAfterMs);
} else if (err instanceof AuthenticationError) {
throw err; // не повторяемо
} else if (err instanceof RunnevError) {
console.error(err.code, err.status, err.requestId, err.docUrl);
}
}Классы: RunnevError (базовый), AuthenticationError,
InvalidRequestError, RateLimitError, ApiError.
Поверхность API
| Метод | Возвращает |
|---|---|
createStream({ name, retentionSeconds?, maxBytes?, mode?, id? }) | Stream |
listStreams({ limit?, cursor? }) | { data, hasMore, nextCursor } |
getStream(id) | Stream |
deleteStream(id) | void |
publish(id, seq, events) | PublishResult |
publishRaw(id, seq, bytes) | PublishResult |
publishAuto(id, events) | PublishResult |
getCursor(id) | { cursor, updatedAt } |
getBatch(id, seq) | Batch |
subscribe(id, options?) | AsyncIterable<Batch> |
В каталоге examples/ есть запускаемые publish.mjs,
subscribe.mjs и raw-protobuf.mjs.