@grainql/analytics-web
Version:
Lightweight TypeScript SDK for sending analytics events and managing remote configurations via Grain's REST API
320 lines • 9.13 kB
TypeScript
/**
* Grain Analytics Web SDK
* A lightweight, dependency-free TypeScript SDK for sending analytics events to Grain's REST API
*/
export interface GrainEvent {
eventName: string;
userId?: string;
properties?: Record<string, unknown>;
timestamp?: Date;
}
export interface EventPayload {
eventName: string;
userId: string;
properties: Record<string, unknown>;
}
export type AuthStrategy = 'NONE' | 'SERVER_SIDE' | 'JWT';
export interface AuthProvider {
getToken(): Promise<string> | string;
}
export interface GrainConfig {
tenantId: string;
apiUrl?: string;
authStrategy?: AuthStrategy;
secretKey?: string;
authProvider?: AuthProvider;
userId?: string;
batchSize?: number;
flushInterval?: number;
retryAttempts?: number;
retryDelay?: number;
maxEventsPerRequest?: number;
debug?: boolean;
defaultConfigurations?: Record<string, string>;
configCacheKey?: string;
configRefreshInterval?: number;
enableConfigCache?: boolean;
}
export interface SendEventOptions {
flush?: boolean;
}
export interface SetPropertyOptions {
userId?: string;
}
export interface PropertyPayload {
userId: string;
[key: string]: string;
}
export interface RemoteConfigRequest {
userId: string;
immediateKeys: string[];
properties?: Record<string, string>;
}
export interface RemoteConfigResponse {
userId: string;
snapshotId: string;
configurations: Record<string, string>;
isFinal: boolean;
qualifiedSegments: string[];
qualifiedRuleSets: string[];
timestamp: string;
isFromCache: boolean;
}
export interface RemoteConfigOptions {
immediateKeys?: string[];
properties?: Record<string, string>;
userId?: string;
forceRefresh?: boolean;
}
export interface RemoteConfigCache {
configurations: Record<string, string>;
snapshotId: string;
timestamp: string;
userId: string;
}
export type ConfigChangeListener = (configurations: Record<string, string>) => void;
export interface LoginEventProperties extends Record<string, unknown> {
method?: string;
success?: boolean;
errorMessage?: string;
loginAttempt?: number;
rememberMe?: boolean;
twoFactorEnabled?: boolean;
}
export interface SignupEventProperties extends Record<string, unknown> {
method?: string;
source?: string;
plan?: string;
success?: boolean;
errorMessage?: string;
}
export interface CheckoutEventProperties extends Record<string, unknown> {
orderId?: string;
total?: number;
currency?: string;
items?: Array<{
id: string;
name: string;
price: number;
quantity: number;
}>;
paymentMethod?: string;
success?: boolean;
errorMessage?: string;
couponCode?: string;
discount?: number;
}
export interface PageViewEventProperties extends Record<string, unknown> {
page?: string;
title?: string;
referrer?: string;
url?: string;
userAgent?: string;
screenResolution?: string;
viewportSize?: string;
}
export interface PurchaseEventProperties extends Record<string, unknown> {
orderId?: string;
total?: number;
currency?: string;
items?: Array<{
id: string;
name: string;
price: number;
quantity: number;
category?: string;
}>;
paymentMethod?: string;
shippingMethod?: string;
tax?: number;
shipping?: number;
discount?: number;
couponCode?: string;
}
export interface SearchEventProperties extends Record<string, unknown> {
query?: string;
results?: number;
filters?: Record<string, unknown>;
sortBy?: string;
category?: string;
success?: boolean;
}
export interface AddToCartEventProperties extends Record<string, unknown> {
itemId?: string;
itemName?: string;
price?: number;
quantity?: number;
currency?: string;
category?: string;
variant?: string;
}
export interface RemoveFromCartEventProperties extends Record<string, unknown> {
itemId?: string;
itemName?: string;
price?: number;
quantity?: number;
currency?: string;
category?: string;
variant?: string;
}
export declare class GrainAnalytics {
private config;
private eventQueue;
private flushTimer;
private isDestroyed;
private globalUserId;
private configCache;
private configRefreshTimer;
private configChangeListeners;
private configFetchPromise;
constructor(config: GrainConfig);
private validateConfig;
private log;
private formatEvent;
private getAuthHeaders;
private delay;
private isRetriableError;
private sendEvents;
private sendEventsWithBeacon;
private startFlushTimer;
private setupBeforeUnload;
/**
* Track an analytics event
*/
track(eventName: string, properties?: Record<string, unknown>, options?: SendEventOptions): Promise<void>;
track(event: GrainEvent, options?: SendEventOptions): Promise<void>;
/**
* Identify a user (sets userId for subsequent events)
*/
identify(userId: string): void;
/**
* Set global user ID for all subsequent events
*/
setUserId(userId: string | null): void;
/**
* Get current global user ID
*/
getUserId(): string | null;
/**
* Set user properties
*/
setProperty(properties: Record<string, unknown>, options?: SetPropertyOptions): Promise<void>;
/**
* Send properties to the API
*/
private sendProperties;
/**
* Track user login event
*/
trackLogin(properties?: LoginEventProperties, options?: SendEventOptions): Promise<void>;
/**
* Track user signup event
*/
trackSignup(properties?: SignupEventProperties, options?: SendEventOptions): Promise<void>;
/**
* Track checkout event
*/
trackCheckout(properties?: CheckoutEventProperties, options?: SendEventOptions): Promise<void>;
/**
* Track page view event
*/
trackPageView(properties?: PageViewEventProperties, options?: SendEventOptions): Promise<void>;
/**
* Track purchase event
*/
trackPurchase(properties?: PurchaseEventProperties, options?: SendEventOptions): Promise<void>;
/**
* Track search event
*/
trackSearch(properties?: SearchEventProperties, options?: SendEventOptions): Promise<void>;
/**
* Track add to cart event
*/
trackAddToCart(properties?: AddToCartEventProperties, options?: SendEventOptions): Promise<void>;
/**
* Track remove from cart event
*/
trackRemoveFromCart(properties?: RemoveFromCartEventProperties, options?: SendEventOptions): Promise<void>;
/**
* Manually flush all queued events
*/
flush(): Promise<void>;
/**
* Initialize configuration cache from localStorage
*/
private initializeConfigCache;
/**
* Save configuration cache to localStorage
*/
private saveConfigCache;
/**
* Get configuration value with fallback to defaults
*/
getConfig(key: string): string | undefined;
/**
* Get all configurations with fallback to defaults
*/
getAllConfigs(): Record<string, string>;
/**
* Fetch configurations from API
*/
fetchConfig(options?: RemoteConfigOptions): Promise<RemoteConfigResponse>;
/**
* Get configuration asynchronously (cache-first with fallback to API)
*/
getConfigAsync(key: string, options?: RemoteConfigOptions): Promise<string | undefined>;
/**
* Get all configurations asynchronously (cache-first with fallback to API)
*/
getAllConfigsAsync(options?: RemoteConfigOptions): Promise<Record<string, string>>;
/**
* Update configuration cache and notify listeners
*/
private updateConfigCache;
/**
* Add configuration change listener
*/
addConfigChangeListener(listener: ConfigChangeListener): void;
/**
* Remove configuration change listener
*/
removeConfigChangeListener(listener: ConfigChangeListener): void;
/**
* Notify all configuration change listeners
*/
private notifyConfigChangeListeners;
/**
* Start automatic configuration refresh timer
*/
private startConfigRefreshTimer;
/**
* Stop automatic configuration refresh timer
*/
private stopConfigRefreshTimer;
/**
* Preload configurations for immediate access
*/
preloadConfig(immediateKeys?: string[], properties?: Record<string, string>): Promise<void>;
/**
* Split events array into chunks of specified size
*/
private chunkEvents;
/**
* Destroy the client and clean up resources
*/
destroy(): void;
}
/**
* Create a new Grain Analytics client
*/
export declare function createGrainAnalytics(config: GrainConfig): GrainAnalytics;
export default GrainAnalytics;
declare global {
interface Window {
Grain?: {
GrainAnalytics: typeof GrainAnalytics;
createGrainAnalytics: typeof createGrainAnalytics;
};
}
}
//# sourceMappingURL=index.d.ts.map