import type { LightPlugin, LightClient, SentryEvent, LightConfig } from '../types'; import { isObject } from '../utils/helper'; interface SampleRateConfig { error?: number; performance?: number; network?: number; behavior?: number; [key: string]: number | undefined; } interface SamplingPluginConfig { rates?: SampleRateConfig; } class SamplingPlugin implements LightPlugin { name = 'sampling'; version = '1.0.0'; private client!: LightClient; private config: SamplingPluginConfig = { rates: { error: 1, performance: 1, network: 1, behavior: 1, }, }; setup(client: LightClient): void { this.client = client; this.loadConfig(); } private loadConfig(): void { const clientConfig = this.client.config as LightConfig; if (clientConfig && isObject(clientConfig.sampling)) { const samplingConfig = clientConfig.sampling as object; if ('rates' in samplingConfig && isObject((samplingConfig as { rates?: object }).rates)) { this.config.rates = { ...this.config.rates, ...((samplingConfig as { rates: object }).rates as object) } as SampleRateConfig; } } } private shouldSample(event: SentryEvent): boolean { const globalRate = (this.client.config as LightConfig).sampleRate ?? 1; if (globalRate <= 0) return false; const typeRate = this.getTypeRate(event); if (globalRate >= 1) { return this.randomCheck(typeRate); } return this.randomCheck(globalRate * typeRate); } private getTypeRate(event: SentryEvent): number { const rates = this.config.rates || {}; const type = event.type; if (type === 'count') { return 1; } const rate = rates[type]; return rate !== undefined ? rate : 1; } private randomCheck(rate: number): boolean { if (rate >= 1) return true; if (rate <= 0) return false; return Math.random() < rate; } beforeReport(event: SentryEvent): SentryEvent | null { if (!this.shouldSample(event)) { return null; } return event; } destroy(): void { // nothing to clean up } } export default SamplingPlugin;