docs: expand JavaScript SDK documentation

This commit is contained in:
Mo Elzubeir
2026-05-29 13:35:09 -05:00
parent 252ea713b1
commit c860cf6d88
11 changed files with 850 additions and 116 deletions
+104
View File
@@ -0,0 +1,104 @@
# Caching, Retries, and Failure Semantics
## GET lifecycle
1. Build full URL from `baseUrl`, `path`, and query params.
2. Check cache by full URL.
3. Fetch with auth headers and timeout on cache miss.
4. Retry network errors, timeout errors, `429`, and `5xx`.
5. Parse JSON.
6. Throw `SocialhoseError` for unsupported non-OK responses.
7. Store successful parsed response in cache.
## POST lifecycle
1. Build URL.
2. Fetch JSON body with auth headers and timeout.
3. Retry network errors, timeout errors, `429`, and `5xx`.
4. Parse JSON.
5. Return `{ status, data }`.
6. Never cache.
## Retry policy
Defaults:
```ts
retries: 3,
retryDelayMs: (attempt) => 400 * 2 ** attempt + Math.random() * 200,
timeoutMs: 8_000,
```
Retries apply to transient conditions only:
- network failures
- SDK timeout/abort failures
- `429 Too Many Requests`
- `5xx` server errors
Retries do not apply to normal client errors such as `400`, `401`, `403`, and `404`.
## Cache contract
```ts
interface Cache {
get(key: string): Promise<unknown | undefined>;
set(key: string, value: unknown, ttlMs: number): Promise<void>;
delete(key: string): Promise<void>;
}
```
The cache key is the full request URL. `ttlMs` is in milliseconds and comes from `cacheTtlMs` or per-request `revalidateSeconds`.
## Redis-style cache example
```ts
import { SocialhoseClient, type Cache } from '@socialhose/api';
class RedisJsonCache implements Cache {
constructor(private redis: {
get(k: string): Promise<string | null>;
set(k: string, v: string, mode: 'PX', ttl: number): Promise<unknown>;
del(k: string): Promise<unknown>;
}) {}
async get(key: string) {
const value = await this.redis.get(key);
return value == null ? undefined : JSON.parse(value);
}
async set(key: string, value: unknown, ttlMs: number) {
if (ttlMs <= 0) return;
await this.redis.set(key, JSON.stringify(value), 'PX', ttlMs);
}
async delete(key: string) {
await this.redis.del(key);
}
}
const socialhose = new SocialhoseClient({
apiKey: process.env.SOCIALHOSE_API_KEY!,
cache: new RedisJsonCache(redis),
});
```
## Method failure semantics
Campaign, analytics, mention, and list methods:
- Throw `SocialhoseError` after retry exhaustion or unsupported non-OK responses.
- Return normalized arrays when the API wraps arrays in properties such as `series`, `platforms`, or `keywords`.
`inviteMailingListMember()`:
- `201 + status: invited` -> `outcome: 'invited'`.
- `409` -> `outcome: 'already'`.
- Unexpected success/conflict shapes -> `outcome: 'error'`.
- Other non-OK statuses throw.
Entity methods:
- `getEntityBrief()` throws if the mention search fails.
- `getEntityStats()` requires the initial brief but treats later subrequests as best-effort.
- `getEntityBriefs()` skips failed terms and returns successful entries.