npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@setu-ts/sdk

v0.11.0

Published

Portable HTTP client with retry, circuit breaker, rate limiting, and OpenAPI codegen

Readme

@setu-ts/sdk

Portable, zero-npm-dependency client SDK for consuming Setu-TS APIs from browsers and servers. Provides an injectable fetch HTTP client, bearer and API-key authentication interceptors, per-origin retry with backoff, circuit breaker, and sliding-window rate limiting, plus a pure generator that turns OpenAPI 3.1 documents into type-checked TypeScript client source.

This package does not register a plugin or resolve capability tokens. It is an external-consumer library with no dependency on kernel, runtime, or any plugin — its only in-repo import is type-level from @setu-ts/common.

Realtime clients

createSseClient consumes an SSE endpoint through fetch on every supported runtime. It sends configured headers on every reconnect, ignores comment-frame heartbeats, parses JSON events, applies server retry: delays, and sends Last-Event-ID after an identified event. It does not delegate to EventSource, so bearer authentication works equally in browsers and server runtimes.

import { createSseClient } from '@setu-ts/sdk';

const events = createSseClient({
  url: 'https://api.example.com/sse/scores',
  headers: { Authorization: 'Bearer token' },
  onEvent: ({ event, data }) => console.log(event, data),
});
// later: events.close()

createRealtimeClient wraps the global WebSocket with the server's application-level keep-alive contract. It filters the heartbeat payload ('ping' by default), replies to keep the server's inbound-idle timer fresh, reconnects with backoff, and re-applies the configured room query value.

import { createRealtimeClient } from '@setu-ts/sdk';

const board = createRealtimeClient({
  url: 'wss://api.example.com/ws/board',
  room: 'game-7',
  onMessage: ({ data }) => console.log(data),
});

Installation

# npm / pnpm / yarn
npm install @setu-ts/sdk@^0.11.0

# Bun
bun add @setu-ts/sdk@^0.11.0

# Deno
deno add npm:@setu-ts/sdk@^0.11.0

Quick Start

import { createBearerAuthInterceptor, createClient } from '@setu-ts/sdk';

const client = createClient({
  baseUrl: 'https://api.example.com',
  requestInterceptors: [createBearerAuthInterceptor('my-token')],
  retry: {
    limit: 3,
    delay: 500,
    backoff: 'exponential',
  },
});

const res = await client.request<User>({
  method: 'GET',
  path: 'users/123',
});

console.log(res.data); // User

Options

createClient(options) takes:

| Option | Type | Default | Description | | ---------------------- | ----------------------------- | --------------------------------------- | ----------------------------------------------------------------------- | | baseUrl | string | — | Base URL for every request. Required. | | headers | HeadersInit | — | Headers merged into every request. | | fetch | typeof fetch | global fetch | Injected transport. | | timing | IClientTiming | performance.now() + abort-aware sleep | Clock and sleep seam, so tests need no real time. | | retry | ClientRetryPolicy | off | Retry with fixed or exponential backoff. | | circuitBreaker | CircuitBreakerPolicy | off | Rolling-window breaker. | | rateLimit | ClientRateLimitPolicy | off | Sliding-window limiter. | | idempotency | ClientIdempotencyOptions | off | Generated keys for POST/PATCH; see Keyed retries. | | requestInterceptors | ClientRequestInterceptor[] | [] | Run in order before the request. | | responseInterceptors | ClientResponseInterceptor[] | [] | Run in order after the response. |

fetch and timing are the two seams that keep the client testable without a network or real time — Date.now() appears nowhere in this package. See Resilience for the three policy shapes and Authentication for the bundled interceptors.

The fetch default needs no browser-specific value: it resolves globalThis.fetch at call time, with the global as its receiver, so the default transport works in a browser unchanged. (An injected fetch is always used as-is, which is what tests rely on.)

HTTP Client

createClient(options) returns an IHttpClient whose single method is request<TResponse, TBody>(request: ClientRequest<TBody>): Promise<ClientResponse<TResponse>>.

ClientOptions

| Option | Type | Description | | ---------------------- | ----------------------------- | ------------------------------------------------------------------------------------------------------ | | baseUrl | string (required) | Base URL for every request | | headers | Record<string, string> | Default headers cloned into each request | | fetch | Function | Injectable fetch seam (default bound to the global realm) | | timing | IClientTiming | Injectable timing seam (defaults to createDefaultClientTiming()) | | retry | ClientRetryPolicy | Retry policy (transport failures + 408/425/429/5xx on safe methods; any method, and 409, when keyed) | | circuitBreaker | CircuitBreakerPolicy | Per-origin circuit breaker policy | | rateLimit | ClientRateLimitPolicy | Per-origin sliding-window rate limiter | | idempotency | ClientIdempotencyOptions | Generated idempotency keys; see Keyed retries | | requestInterceptors | ClientRequestInterceptor[] | Run once before resilient execution | | responseInterceptors | ClientResponseInterceptor[] | Run after successful parse; skipped on failure |

Request

interface ClientRequest<TBody = never> {
  method: string;
  path: string;
  query?: Record<string, string | string[]>;
  headers?: Record<string, string>;
  json?: TBody;
  idempotencyKey?: string;
  signal?: AbortSignal;
}
  • path must be relative. A leading slash, a scheme-relative //host/x, and a fully absolute https://host/x are all rejected — otherwise a request could leave baseUrl's origin and bypass the per-origin circuit breaker and rate limiter.
  • Query values are encoded; arrays repeat the key.
  • json is serialized with JSON.stringify; Content-Type: application/json is set automatically.
  • signal aborts fetches, queued waits, and retry attempts.

Response

interface ClientResponse<T> {
  status: number;
  headers: Headers;
  data?: T;
}
  • data is parsed when the response Content-Type names JSON: application/json or any structured +json suffix (application/problem+json, application/vnd.api+json). Media-type parameters and casing are ignored.
  • data is undefined for 204, for an empty body, and for a non-JSON content type.
  • Non-2xx responses throw HttpClientError rather than resolving.

Authentication

Bearer Token

import { createBearerAuthInterceptor } from '@setu-ts/sdk';

const client = createClient({
  baseUrl: 'https://api.example.com',
  requestInterceptors: [
    // Literal token
    createBearerAuthInterceptor('my-token'),
    // Or async provider
    createBearerAuthInterceptor(() => tokenStore.get()),
  ],
});

API Key

import { createApiKeyAuthInterceptor } from '@setu-ts/sdk';

const client = createClient({
  baseUrl: 'https://api.example.com',
  requestInterceptors: [
    // Default header: X-API-Key
    createApiKeyAuthInterceptor('my-key'),
    // Custom header
    createApiKeyAuthInterceptor('my-key', 'Authorization'),
  ],
});

Both factories accept a literal string or an async value provider. The header is only set when the request has not already supplied that header.

Resilience

Retry

import { BackoffStrategy } from '@setu-ts/sdk';

const client = createClient({
  baseUrl: 'https://api.example.com',
  retry: {
    limit: 3, // total attempts
    delay: 500, // base delay in ms
    backoff: 'exponential' as BackoffStrategy,
  },
});

Retries transport rejections and statuses 408, 425, 429, 500-599. By default, only retries safe methods (GET, HEAD, OPTIONS, PUT, DELETE). When a retryable response carries a Retry-After header with delta-seconds, that delay replaces the computed backoff only when it is within the policy cap. Set maxRetryAfterMs explicitly, or omit it to use the policy's largest fixed/exponential backoff. A larger hint surfaces the original HttpClientError immediately, with its headers intact.

At construction, limit must be a positive safe integer, delay must be finite and non-negative, and every explicit or derived delay must be at most 2_147_483_647 ms, the portable JavaScript timer maximum. Runtime strings, non-finite values, and timer-overflowing delays are rejected so they cannot disable the cap or be clamped into an immediate retry.

Keyed retries

ClientRequest.idempotencyKey supplies a key; ClientOptions.idempotency generates one by default for POST and PATCH. The default header is Idempotency-Key; configure idempotency.header to match the server. When ClientOptions.idempotency applies to the request's method and ClientRequest.idempotencyKey is absent, a request that already carries the configured header uses its value as the key. Without matching configuration the header is sent but does not make the request keyed, and a request carrying both idempotencyKey and that header is refused rather than either value replacing the other. The same key is reused across retry attempts, including a retryable 409.

Keyed POST/PATCH retries are safe ONLY when the server de-duplicates on that key, for example with idempotent() or within. Against a server that does not, a retried POST can execute twice. A keyed request carries a non-safelisted header, so a cross-origin browser call triggers a CORS preflight; the server must list that header in Access-Control-Allow-Headers. For the page to read the replay response, Access-Control-Expose-Headers must list Idempotent-Replayed.

A generated operation takes the same key per call in its trailing request parameter (request?: OperationRequestOptions): api.createOrder({ body }, { idempotencyKey }). The idempotencyKey and signal fields carry the same meaning as the same-named fields of ClientRequest, and the generated code forwards only those two fields.

Circuit Breaker

const client = createClient({
  baseUrl: 'https://api.example.com',
  circuitBreaker: {
    threshold: 5,
    timeout: 30_000,
    resetTimeout: 10_000,
  },
});

Per-origin rolling-window circuit breaker. An open circuit throws ClientCircuitOpenError before consuming a rate-limit slot. The breaker counts one failure per exhausted transient sequence (not one per retry attempt).

The two windows are independent:

  • timeout is the rolling window used to decide when the circuit trips — threshold counted failures inside it open the circuit.
  • resetTimeout is how long the circuit stays open, measured from the moment it tripped. It is not shortened by timeout elapsing, so timeout may safely be shorter than resetTimeout.

After resetTimeout elapses, exactly one half-open probe is admitted; concurrent callers get ClientCircuitOpenError. A successful probe closes the circuit and clears the window. A failed probe reopens it and restarts resetTimeout, so a dead dependency is probed once per cooldown rather than on every request.

What counts as a failure: a 5xx response, a transport rejection, or an exhausted retry sequence. A 4xx HttpClientError does not — a bad request means the caller was wrong, not that the origin is unhealthy — and neither does a caller abort.

Rate Limiting

const client = createClient({
  baseUrl: 'https://api.example.com',
  rateLimit: {
    maxRequests: 100,
    windowMs: 60_000,
  },
});

Per-origin sliding-window limiter. When the window is full, the client waits until the oldest retained timestamp expires.

Interceptors

Request Interceptors

import { ClientRequestContext, ClientRequestInterceptor } from '@setu-ts/sdk';

const loggingInterceptor: ClientRequestInterceptor = (ctx: ClientRequestContext) => {
  // The context carries the resolved `url` and the mutable `headers`; the
  // method is not part of it.
  console.log(ctx.url.href);
  ctx.headers.set('x-request-id', crypto.randomUUID());
};

const client = createClient({
  baseUrl: 'https://api.example.com',
  requestInterceptors: [loggingInterceptor],
});

Request interceptors receive a mutable ClientRequestContext (resolved URL and Headers) and execute once in registration order before the outbound attempt sequence.

Use createTraceContextInterceptor(telemetry) to propagate the active span as a W3C traceparent. It reads activeSpanContext() per request, preserves a caller-supplied header, and omits invalid or absent contexts. The telemetry service is structural and imported type-only, so the SDK keeps its zero-runtime-dependency boundary.

Response Interceptors

import { ClientRequestContext, ClientResponse, ClientResponseInterceptor } from '@setu-ts/sdk';

const timingInterceptor: ClientResponseInterceptor<unknown> = (
  response: ClientResponse<unknown>,
  request: ClientRequestContext,
) => {
  console.log(`${request.url.href} → ${response.status}`);
  return response;
};

Response interceptors receive a successful ClientResponse<T> and its immutable request description. They are skipped entirely when the request throws.

OpenAPI Code Generation

generateOpenApiClient(document, options?) is a pure function that turns an OpenAPI 3.1 document into TypeScript source.

import { generateOpenApiClient } from '@setu-ts/sdk';
import { readFileSync } from 'node:fs';

const document = JSON.parse(readFileSync('openapi.json', 'utf-8'));

const source = generateOpenApiClient(document, {
  sdkImport: '@setu-ts/sdk',
  factoryName: 'createApi',
  apiTypeName: 'Api',
});

// Write `source` to a file, then import the generated factory:
// import { createApi } from './generated-api.js';
// const api = createApi(client);

The generated factory accepts an IHttpClient and returns typed operation methods. Schema mapping covers the M21 vocabulary: primitives, arrays, objects with required, $ref, enum, const, anyOf, allOf, additionalProperties, null, and integer.

The output is publishable, formatted and lint-clean. createApi has a written-out return type (export interface Api), so JSR does not reject the file as a slow type; the source round-trips through deno fmt unchanged and needs no lint pragma. Both properties are load-bearing rather than cosmetic: the generated file's own header says "Do not edit manually", so a consumer who cannot publish or format it has nowhere to go.

Generated names and shapes

  • Operation methods are lower-camelCase and preserve interior casing. An operationId is split on every run of non-alphanumeric characters and re-joined, so listUsers stays listUsers and get-users-{id} becomes getUsersId. A leading digit run is prefixed with n, a reserved word is prefixed with _, and an id that sanitizes to nothing becomes operation.

  • Component schemas and argument interfaces are PascalCase. Component User emits export type User, and operation listUsers emits export interface ListUsersArgs.

  • The factory returns a named interface. export interface Api { … } lists every operation's signature and is the factory's return type; rename it with apiTypeName.

  • Two names that derive onto one identifier throw OpenApiCodegenError rather than emitting a file with a duplicate declaration, and the diagnostic names both originals. Component schemas, *Args interfaces, *Error unions, the client interface and the apiTypeName / factoryName options all draw from ONE registry, so a component named ListUsersArgs beside an operation listUsers is refused rather than silently emitting two declarations of one name. Each of those names derives from something the document or the caller WROTE, so a clash is a real problem you must see.

  • A hoisted alias ALLOCATES its name instead of throwing. The four hoisted aliases — a request body, a parameter, a success response and an error body — name an anonymous inline schema the document never named, so the generator may pick any identifier and a clash is its own problem to solve. Each asks the registry for its preferred name first, so no alias that generates today is ever renamed; a success response then tries …Response<status>Body, which reads correctly beside a component of the same name; and every arm finally takes a numeric suffix (…2, …3) allocated through the registry, because a suffix is not a namespace and a document may legally declare the suffixed name too. This matters because @setu-ts/openapi-plugin names a reused response schema ${operationId}Response${status} — exactly the derivation used here — so a schema that is both reused and enclosed in an inline body used to abort generation outright.

  • Declared error responses are typed. An operation declaring an observable non-2xx response also emits a union discriminated on the literal status and a narrowing guard:

    try {
      await api.getUserById('1');
    } catch (e) {
      if (isGetUserByIdError(e) && e.status === 404) {
        e.body.code; // typed by the document's 404 schema
      }
    }

    Every declared 3xx keeps its error arm, the auto-follow statuses (301, 302, 303, 307, and 308) included: Fetch returns such a response itself when it carries no Location, and the client then throws HttpClientError with that status. Any operation declaring an auto-follow redirect or a 3XX range returns unknown, because the follow target body is selected at runtime and is not described by the source operation.

    HttpClientError is generic in its body (HttpClientError<TBody = unknown>), so the bare name means what it always did. The union is discriminated on status because HttpClientError<A> | HttpClientError<B> is not — status is number on both arms. A default response and range codes such as 4XX are skipped: they name no single status.

  • Formatting matches deno fmt. Two-space indentation, a signature past 100 columns wrapped one parameter per line, and a path template too long for one line emitted as an equivalent […].join('') — a template literal is not usable there, because deno fmt rewraps a long one at whichever ${ happens to fit, which no generator can predict.

  • No multi-line type is written at a use site. An inline (non-$ref) body, parameter or success response is hoisted into an exported alias. A rendered type lands at several indentation levels, and a success type lands at two at once — the client interface's signature and the client.request<…> type argument — so no single indentation is correct for a multi-line object literal and deno fmt reindents whatever is emitted. A schema that @setu-ts/openapi-plugin derived from validateBody and used once arrives inline, so this is the ordinary case.

  • No lint pragma. An empty-object schema emits Record<PropertyKey, never> rather than {}, which is both what the schema means and what deno lint's ban-types accepts. A narrowed pragma could not be emitted unconditionally either: an ignore matching nothing is itself reported as ban-unused-ignore.

  • Path parameters are positional arguments; everything else lives in opts. Each path placeholder is substituted and percent-encoded, including a placeholder that shares a segment with literal text (/files/{id}.json).

  • Every operation ends with an optional trailing request parameter — request?: OperationRequestOptions, after the path parameters and after opts — whose idempotencyKey and signal fields carry the same meaning as the same-named fields of ClientRequest; the generated code forwards only those two fields, and existing calls are unaffected. A path parameter whose identifier is client, opts, request or encodeURIComponent is emitted with a _ prefix, so it cannot shadow the factory's client, the method's locals or the global its path expression calls; path parameters are positional, so no caller changes. An operation whose method name is client or encodeURIComponent is emitted as _client or _encodeURIComponent — a renamed method, but before, client never compiled and encodeURIComponent broke every generated path that encodes a parameter. A document component named OperationRequestOptions is refused like ClientResponse, rather than shadowing the import the generated file claims from sdkImport.

  • opts is required when any of its fields is required. A required query parameter or a requestBody marked required makes the opts parameter itself required, so a caller cannot omit it and silently skip a mandatory value.

  • Wire names are preserved. The query key and header name sent on the wire are the original OpenAPI names (user_id, X-API-Key); only the TypeScript field identifier is derived. Header values are stringified, so a non-string header schema still compiles.

  • All eight operation slots are generated, including trace. Parameters declared at the path-item level are merged into every operation on that path; an operation's own parameter overrides a shared one with the same name and in.

  • Document text can never escape into code. Text emitted into a comment (the operationId on each generated method) has comment terminators escaped and line breaks collapsed, and every emitted string literal and path template is escaped for its own context.

Codegen diagnostics

Declared OpenAPI ids name generated methods just like derived ones: listUsers produces listUsers. Distinct ids may sanitize to one method name: declared getUsers beside undeclared GET /users (derived get-users) is valid OpenAPI, but code generation refuses it with Duplicate operation name. Choose ids that yield distinct TypeScript names. Changing an id also changes its generated argument, error and inline-schema type names; regenerate clients and update their callers.

generateOpenApiClient throws OpenApiCodegenError — carrying path and method where they apply — rather than emitting a client that misbehaves or does not compile:

| Condition | Why it is rejected | | ---------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Missing operationId | No name to derive a method from | | Two operations deriving onto one method name | Duplicate declaration; both originals are named | | Two emitted TYPE names colliding | Duplicate declaration; one registry covers every emitted name. A HOISTED alias is the exception and does NOT throw — it allocates (see the naming rules above) | | Parameter with in: 'cookie' | Unsupported location | | Path placeholder with no matching in: 'path' parameter | Emitted source would reference an undeclared argument | | in: 'path' parameter absent from the path template | The caller's value would be silently dropped | | Two placeholders in one template deriving onto one argument name | Duplicate parameter in the emitted signature | | Malformed local $ref | No component name to resolve |

Outbound HTTP observations (devtool)

createObservedFetch wraps a fetch so the local diagnostics connector can count its attempts: how many started and are in flight, how many resolved or failed, the last response's status class and its time to headers. It never reads a URL, header, body, signal or error, and it never changes what the wrapped fetch receives or returns. Build it only when the application factory receives its devtool composition, so a production entry carries no wrapper at all, and register its plugin in that one application:

import type { IPlugin } from '@setu-ts/common';
import type { KernelDiagnosticsOptions } from '@setu-ts/kernel';
import { createApplication } from '@setu-ts/kernel';
import { RuntimePlugin } from '@setu-ts/runtime';
import { createClient, createObservedFetch } from '@setu-ts/sdk';

const PAYMENTS_URL = 'https://payments.internal.example';

export function createApp(
  _env?: Readonly<Record<string, unknown>>,
  devtool?: { plugins?: readonly IPlugin[]; diagnostics?: KernelDiagnosticsOptions },
) {
  const observed = devtool ? createObservedFetch({ alias: 'payments-api' }) : undefined;
  const payments = createClient({
    baseUrl: PAYMENTS_URL,
    ...(observed ? { fetch: observed.fetch } : {}),
  });
  void payments; // routes use `payments`
  return createApplication({
    plugins: [RuntimePlugin(), ...(observed ? [observed.plugin] : []), ...(devtool?.plugins ?? [])],
    ...(devtool?.diagnostics !== undefined ? { diagnostics: devtool.diagnostics } : {}),
  });
}

The alias is disclosed to a paired devtool as written — choose a non-secret label, never a hostname. A wrapped fetch should not depend on its receiver (prefer (input, init) => fetch(input, init)); a direct observed.fetch(url) call forwards undefined. One helper serves one application: registering its plugin in a second one throws. The helper needs crypto.getRandomValues (Node ≥ 19, Deno, Bun, workerd, browsers).

Errors

| Error | When thrown | | ------------------------ | ----------------------------------------------------------- | | HttpClientError | Non-2xx HTTP response (carries status, headers, body) | | ClientCircuitOpenError | Circuit breaker is open for the request origin | | OpenApiCodegenError | Invalid OpenAPI document during code generation |

Public Surface

| Export | Kind | Description | | ----------------------------- | ----------- | ---------------------------------------- | | createClient | factory | Creates an IHttpClient instance | | IHttpClient | interface | Client contract (request<T>()) | | ClientOptions | interface | Factory options | | ClientRequest | type | Outbound request description | | ClientResponse | type | Parsed response | | ClientRequestContext | type | Mutable context for request interceptors | | ClientRequestInterceptor | type | Request interceptor signature | | ClientResponseInterceptor | type | Response interceptor signature | | IClientTiming | interface | Timing seam (now(), sleep()) | | createDefaultClientTiming | factory | Default timing over performance.now() | | createObservedFetch | factory | Devtool outbound-attempt counters (M98n) | | ObservedFetch | interface | { fetch, plugin } returned by it | | ObservedFetchOptions | interface | { alias, fetch?, timing? } | | ClientRateLimitPolicy | type | Sliding-window rate limiter config | | RetryPolicy | re-export | From @setu-ts/common | | CircuitBreakerPolicy | re-export | From @setu-ts/common | | BackoffStrategy | re-export | From @setu-ts/common | | createBearerAuthInterceptor | factory | Bearer-token request interceptor | | createApiKeyAuthInterceptor | factory | API-key request interceptor | | HttpClientError | error class | Failed non-2xx response | | ClientCircuitOpenError | error class | Fail-fast circuit state | | OpenApiCodegenError | error class | Invalid-spec diagnostic | | generateOpenApiClient | function | Pure OpenAPI → TypeScript generator | | OpenApiCodegenOptions | type | Generator options | | SdkOpenApi* | types | Structural OpenAPI 3.1 subset |

Portability

  • Zero npm dependencies — uses only web-standard APIs (URL, Headers, AbortSignal, performance.now()).
  • Browser and server — runs in browsers, Node.js, Deno, Bun, and Cloudflare Workers. The default transport needs no browser-specific value: it resolves globalThis.fetch at call time with the global as its receiver, so the default works in a browser unchanged.
  • Injectable fetch — tests inject a fake; the default is bound to the global realm.
  • Injectable timing — IClientTiming makes backoff, breaker windows, and rate-limit waits testable without real time.

Architecture · Public API · Roadmap

Exports

| Export | Kind | | ------------------------------- | --------- | | createApiKeyAuthInterceptor | function | | createBearerAuthInterceptor | function | | createClient | function | | createDefaultClientTiming | function | | createObservedFetch | function | | createRealtimeClient | function | | createSseClient | function | | createTraceContextInterceptor | function | | generateOpenApiClient | function | | ClientCircuitOpenError | class | | HttpClientError | class | | OpenApiCodegenError | class | | CircuitBreakerPolicy | interface | | ClientIdempotencyOptions | interface | | ClientOptions | interface | | ClientRateLimitPolicy | interface | | ClientRequest | interface | | ClientRequestContext | interface | | ClientResponse | interface | | IClientTiming | interface | | IHttpClient | interface | | IRealtimeClient | interface | | ISseClient | interface | | IWebSocketTransport | interface | | ObservedFetch | interface | | ObservedFetchOptions | interface | | OpenApiCodegenOptions | interface | | OperationRequestOptions | interface | | RawSseEvent | interface | | RealtimeClientOptions | interface | | RealtimeMessage | interface | | RealtimeReconnectOptions | interface | | RetryPolicy | interface | | SdkOpenApiDocument | interface | | SdkOpenApiOperation | interface | | SdkOpenApiParameter | interface | | SdkOpenApiPathItem | interface | | SdkOpenApiRequestBody | interface | | SdkOpenApiResponse | interface | | SdkOpenApiSchema | interface | | SseClientOptions | interface | | SseEvent | interface | | SseReconnectOptions | interface | | BackoffStrategy | type | | ClientRequestInterceptor | type | | ClientResponseInterceptor | type | | ClientRetryPolicy | type | | RealtimeClientState | type | | SseClientState | type | | SseEventMap | type | | WebSocketFactory | type |

Generated from the package barrel by pnpm run docs:exports; pnpm run check:docs fails when it drifts.