docs: expand JavaScript SDK documentation
This commit is contained in:
@@ -1,12 +1,22 @@
|
||||
/**
|
||||
* Pluggable cache contract used by SocialhoseClient for GET responses.
|
||||
* The SDK uses the full request URL as the key.
|
||||
*/
|
||||
export interface Cache {
|
||||
/** Return a cached value, or `undefined` on miss/expiry. */
|
||||
get(key: string): Promise<unknown | undefined>;
|
||||
/** Store a value for the given TTL in milliseconds. */
|
||||
set(key: string, value: unknown, ttlMs: number): Promise<void>;
|
||||
/** Delete one cache entry. */
|
||||
delete(key: string): Promise<void>;
|
||||
}
|
||||
|
||||
type Entry = { at: number; value: unknown; ttlMs: number };
|
||||
|
||||
/** In-memory Map-backed cache with per-entry TTL. */
|
||||
/**
|
||||
* In-memory Map-backed cache with per-entry TTL.
|
||||
* Best for tests, scripts, and single-process services.
|
||||
*/
|
||||
export class MemoryCache implements Cache {
|
||||
private readonly map = new Map<string, Entry>();
|
||||
|
||||
@@ -29,7 +39,7 @@ export class MemoryCache implements Cache {
|
||||
}
|
||||
}
|
||||
|
||||
/** No-op cache — all operations are no-ops; useful for disabling caching. */
|
||||
/** Cache implementation that never stores values; useful for disabling caching. */
|
||||
export class NoopCache implements Cache {
|
||||
async get(_key: string): Promise<undefined> {
|
||||
return undefined;
|
||||
|
||||
@@ -2,11 +2,13 @@ export type { Cache } from './cache';
|
||||
export { MemoryCache, NoopCache } from './cache';
|
||||
import { type Cache, MemoryCache, NoopCache } from './cache';
|
||||
|
||||
/** Sentiment label assigned to a mention by Socialhose. */
|
||||
export type Sentiment = 'positive' | 'negative' | 'neutral';
|
||||
export type SentimentSplit = { positive: number; negative: number; neutral: number };
|
||||
export type QueryValue = string | number | boolean | null | undefined;
|
||||
export type QueryParams = Record<string, QueryValue>;
|
||||
|
||||
/** Configuration for {@link SocialhoseClient}. */
|
||||
export interface SocialhoseClientOptions {
|
||||
apiKey: string;
|
||||
baseUrl?: string;
|
||||
@@ -21,6 +23,7 @@ export interface SocialhoseClientOptions {
|
||||
defaultHeaders?: Record<string, string>;
|
||||
}
|
||||
|
||||
/** Per-call controls for cache TTL, cancellation, and extra headers. */
|
||||
export interface RequestOptions {
|
||||
/**
|
||||
* Reserved for cache-implementation use; not forwarded to fetch.
|
||||
@@ -226,6 +229,7 @@ export interface EntityStats extends EntityBrief {
|
||||
sparkline: { date: string; count: number }[];
|
||||
}
|
||||
|
||||
/** Structured error thrown for failed Socialhose requests. */
|
||||
export class SocialhoseError extends Error {
|
||||
readonly status?: number;
|
||||
readonly path: string;
|
||||
@@ -312,6 +316,7 @@ function platformMixOf(mentions: Mention[]): PlatformShare[] {
|
||||
.sort((a, b) => b.count - a.count);
|
||||
}
|
||||
|
||||
/** Authenticated server-side client for the Socialhose Public API. */
|
||||
export class SocialhoseClient {
|
||||
readonly apiKey: string;
|
||||
readonly baseUrl: string;
|
||||
@@ -326,6 +331,7 @@ export class SocialhoseClient {
|
||||
private readonly cacheImpl: Cache;
|
||||
private readonly usedCacheKeys = new Set<string>();
|
||||
|
||||
/** Create a client with authentication, retry, timeout, and cache settings. */
|
||||
constructor(options: SocialhoseClientOptions) {
|
||||
if (!options.fetch && typeof fetch === 'undefined') throw new Error('A fetch implementation is required');
|
||||
this.apiKey = options.apiKey;
|
||||
@@ -340,12 +346,14 @@ export class SocialhoseClient {
|
||||
this.cacheImpl = options.cache ?? (this.cacheTtlMs > 0 ? new MemoryCache() : new NoopCache());
|
||||
}
|
||||
|
||||
/** Delete cache entries used by this client instance. */
|
||||
async clearCache(): Promise<void> {
|
||||
const keys = [...this.usedCacheKeys];
|
||||
this.usedCacheKeys.clear();
|
||||
await Promise.all(keys.map((k) => this.cacheImpl.delete(k)));
|
||||
}
|
||||
|
||||
/** Perform an authenticated cached GET request. */
|
||||
async get<T>(path: string, params: QueryParams = {}, options: RequestOptions = {}): Promise<T> {
|
||||
const query = encodeParams(params);
|
||||
const url = `${joinUrl(this.baseUrl, path)}${query ? `?${query}` : ''}`;
|
||||
@@ -360,20 +368,24 @@ export class SocialhoseClient {
|
||||
return value;
|
||||
}
|
||||
|
||||
/** Perform an authenticated JSON POST request. */
|
||||
async post<T>(path: string, body: unknown, options: RequestOptions = {}): Promise<{ status: number; data: T | null }> {
|
||||
const url = joinUrl(this.baseUrl, path);
|
||||
return this.requestWithStatus<T>('POST', path, url, body, options);
|
||||
}
|
||||
|
||||
/** Fetch the first page of campaigns. */
|
||||
async getCampaigns(options: RequestOptions = {}): Promise<Campaign[]> {
|
||||
const d = await this.get<Paginated<Campaign>>('/campaigns/', { page: 1 }, options);
|
||||
return d.results;
|
||||
}
|
||||
|
||||
/** Fetch a single campaign by ID. */
|
||||
getCampaign(id: string, options: RequestOptions = {}): Promise<Campaign> {
|
||||
return this.get<Campaign>(`/campaigns/${id}/`, {}, options);
|
||||
}
|
||||
|
||||
/** Fetch aggregate overview analytics. */
|
||||
async getOverview(filters: AnalyticsFilters = {}, options: RequestOptions = {}): Promise<Overview> {
|
||||
const d = await this.get<Overview>('/analytics/overview/', filters as QueryParams, options);
|
||||
return { ...d, total_mentions: num(d.total_mentions), total_authors: num(d.total_authors) };
|
||||
@@ -745,6 +757,7 @@ export class SocialhoseClient {
|
||||
}
|
||||
}
|
||||
|
||||
/** Create a {@link SocialhoseClient}; convenience wrapper around the constructor. */
|
||||
export function createSocialhoseClient(options: SocialhoseClientOptions): SocialhoseClient {
|
||||
return new SocialhoseClient(options);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user