import { releaseApiKey, validateAndTrackApiKey } from '../utils/inputValidation/apiKey'; import { ISdkFactoryContext } from '../sdkFactory/types'; import { LOCALHOST_MODE } from '../utils/constants'; const COOLDOWN_TIME_IN_MILLIS = 1000; /** * Creates an Sdk client, i.e., a base client with status, init, flush and destroy interface */ export function sdkLifecycleFactory(params: ISdkFactoryContext, isSharedClient?: boolean): { init(): void; flush(): Promise; destroy(): Promise } { const { sdkReadinessManager, syncManager, storage, settings, telemetryTracker, impressionsTracker, platform, serviceApi } = params; let hasInit = false; let lastActionTime = 0; const signalListener = platform.SignalListener && settings.mode !== LOCALHOST_MODE ? new platform.SignalListener(params) : undefined; function __cooldown(func: Function, time: number) { const now = Date.now(); //get the actual time elapsed in ms const timeElapsed = now - lastActionTime; //check if the time elapsed is less than desired cooldown if (timeElapsed < time) { //if yes, return message with remaining time in seconds settings.log.warn(`Flush cooldown, remaining time ${(time - timeElapsed) / 1000} seconds`); return Promise.resolve(); } else { //Do the requested action and re-assign the lastActionTime lastActionTime = now; return func(); } } function __flush() { return syncManager ? syncManager.flush() : Promise.resolve(); } return { init() { if (hasInit) return; hasInit = true; if (!isSharedClient) { validateAndTrackApiKey(settings.log, settings.core.authorizationKey); sdkReadinessManager.readinessManager.init(); impressionsTracker.start(); syncManager && syncManager.start(); signalListener && signalListener.start(); } }, flush() { // @TODO define cooldown time return __cooldown(__flush, COOLDOWN_TIME_IN_MILLIS); }, destroy() { hasInit = false; // Mark the SDK as destroyed immediately sdkReadinessManager.readinessManager.destroy(); // For main client, cleanup the SDK Key, listeners and scheduled jobs, and record stat before flushing data if (!isSharedClient) { releaseApiKey(settings.core.authorizationKey); telemetryTracker.sessionLength(); signalListener && signalListener.stop(); impressionsTracker.stop(); } // Stop background jobs syncManager && syncManager.stop(); serviceApi && serviceApi.stop(); return __flush().then(() => { // Cleanup storage return storage.destroy(); }); } }; }