import type { SegmentEvent } from '../types'; type Observer = (value: T) => void; /** * A simple observable value or object */ export class Observable { private internalValue: T; private observers: Observer[]; constructor(value: T) { this.internalValue = value; this.observers = []; } public get value(): T { return this.internalValue; } public set value(v: T) { this.internalValue = v; for (const observer of this.observers) { observer(this.internalValue); } } public onChange(observer: Observer): () => void { const n = this.observers.push(observer); return () => { this.observers.splice(n - 1, 1); }; } } /** * FlushPolicy defines the strategy for executing flushes * (uploading events to destinations) */ export interface FlushPolicy { /** * Marks when the client should atempt to upload events */ shouldFlush: Observable; /** * Start gets executed when the FlushPolicy is added to the client. * * This is a good place to initialize configuration or timers as it will only * execute when this policy is enabled */ start(): void; /** * Executed every time an event is tracked by the client * @param event triggered event */ onEvent(event: SegmentEvent): void; /** * Resets the values of this policy. * * Called when the flush has been completed. */ reset(): void; /** * Ends the execution of the flush policy. * All cleanup methods should be contained here */ end(): void; } /** * A Base Class for implementing a FlushPolicy. * * Initializes the shouldFlush value to false and sets it to false on reset */ export abstract class FlushPolicyBase implements FlushPolicy { shouldFlush = new Observable(false); reset(): void { this.shouldFlush.value = false; } end(): void { // Nothing to cleanup } abstract start(): void; abstract onEvent(event: SegmentEvent): void; }