From 84f73c7e3e6f33610a4ebe8e7fb4b121f3ea3bed Mon Sep 17 00:00:00 2001 From: Emiliano Sanchez Date: Thu, 8 May 2025 14:51:33 -0300 Subject: [PATCH] Refactor storage usage --- src/consent/__tests__/sdkUserConsent.spec.ts | 4 ++- src/consent/sdkUserConsent.ts | 5 +-- src/listeners/__tests__/browser.spec.ts | 32 ++++++++++++-------- src/listeners/browser.ts | 5 ++- 4 files changed, 27 insertions(+), 19 deletions(-) diff --git a/src/consent/__tests__/sdkUserConsent.spec.ts b/src/consent/__tests__/sdkUserConsent.spec.ts index e7981871..fd3fe798 100644 --- a/src/consent/__tests__/sdkUserConsent.spec.ts +++ b/src/consent/__tests__/sdkUserConsent.spec.ts @@ -7,7 +7,9 @@ test('createUserConsentAPI', () => { const syncManager = { submitterManager: syncTaskFactory() }; const storage = { events: { clear: jest.fn() }, - impressions: { clear: jest.fn() } + impressions: { clear: jest.fn() }, + impressionCounts: { clear: jest.fn() }, + uniqueKeys: { clear: jest.fn() } }; // @ts-ignore diff --git a/src/consent/sdkUserConsent.ts b/src/consent/sdkUserConsent.ts index 4891e04e..c4feb84c 100644 --- a/src/consent/sdkUserConsent.ts +++ b/src/consent/sdkUserConsent.ts @@ -15,7 +15,7 @@ const ConsentStatus = { * The public user consent API exposed via SplitFactory, used to control if the SDK tracks and sends impressions and events or not. */ export function createUserConsentAPI(params: ISdkFactoryContext) { - const { settings, settings: { log }, syncManager, storage: { events, impressions, impressionCounts } } = params; + const { settings, settings: { log }, syncManager, storage: { events, impressions, impressionCounts, uniqueKeys } } = params; if (!isConsentGranted(settings)) log.info(USER_CONSENT_INITIAL, [settings.userConsent]); @@ -41,7 +41,8 @@ export function createUserConsentAPI(params: ISdkFactoryContext) { // @ts-ignore, clear method is present in storage for standalone and partial consumer mode if (events.clear) events.clear(); // @ts-ignore if (impressions.clear) impressions.clear(); // @ts-ignore - if (impressionCounts && impressionCounts.clear) impressionCounts.clear(); + if (impressionCounts.clear) impressionCounts.clear(); // @ts-ignore + if (uniqueKeys.clear) uniqueKeys.clear(); } } else { log.info(USER_CONSENT_NOT_UPDATED, [newConsentStatus]); diff --git a/src/listeners/__tests__/browser.spec.ts b/src/listeners/__tests__/browser.spec.ts index 14422f83..e1d532df 100644 --- a/src/listeners/__tests__/browser.spec.ts +++ b/src/listeners/__tests__/browser.spec.ts @@ -1,5 +1,4 @@ import { BrowserSignalListener } from '../browser'; -import { IEventsCacheSync, IImpressionCountsCacheSync, IImpressionsCacheSync, IStorageSync, ITelemetryCacheSync, IUniqueKeysCacheBase } from '../../storages/types'; import { ISplitApi } from '../../services/types'; import { fullSettings } from '../../utils/settingsValidation/__tests__/settings.mocks'; @@ -30,42 +29,48 @@ const fakeUniqueKeys = { }; // Storage with impressionsCount and telemetry cache -const fakeStorageOptimized = { // @ts-expect-error +const fakeStorageOptimized = { impressions: { isEmpty: jest.fn(), pop() { return [fakeImpression]; } - } as IImpressionsCacheSync, // @ts-expect-error + }, events: { isEmpty: jest.fn(), pop() { return [fakeEvent]; } - } as IEventsCacheSync, // @ts-expect-error + }, impressionCounts: { isEmpty: jest.fn(), pop() { return fakeImpressionCounts; } - } as IImpressionCountsCacheSync, // @ts-expect-error + }, uniqueKeys: { isEmpty: jest.fn(), pop() { return fakeUniqueKeys; } - } as IUniqueKeysCacheBase, // @ts-expect-error + }, telemetry: { isEmpty: jest.fn(), pop() { return 'fake telemetry'; } - } as ITelemetryCacheSync + } }; const fakeStorageDebug = { impressions: fakeStorageOptimized.impressions, - events: fakeStorageOptimized.events + events: fakeStorageOptimized.events, + impressionCounts: { + isEmpty: jest.fn(() => true) + }, + uniqueKeys: { + isEmpty: jest.fn(() => true) + } }; // @ts-expect-error @@ -155,7 +160,8 @@ function assertStop(listener: BrowserSignalListener) { test('Browser JS listener / consumer mode', () => { // No SyncManager ==> consumer mode - const listener = new BrowserSignalListener(undefined, fullSettings, fakeStorageOptimized as IStorageSync, fakeSplitApi); + // @ts-expect-error + const listener = new BrowserSignalListener(undefined, fullSettings, fakeStorageOptimized, fakeSplitApi); listener.start(); assertStart(listener); @@ -180,7 +186,7 @@ test('Browser JS listener / standalone mode / Impressions optimized mode with te const syncManagerMock = {}; // @ts-expect-error - const listener = new BrowserSignalListener(syncManagerMock, fullSettings, fakeStorageOptimized as IStorageSync, fakeSplitApi); + const listener = new BrowserSignalListener(syncManagerMock, fullSettings, fakeStorageOptimized, fakeSplitApi); listener.start(); assertStart(listener); @@ -205,7 +211,7 @@ test('Browser JS listener / standalone mode / Impressions debug mode', () => { const syncManagerMock = {}; // @ts-expect-error - const listener = new BrowserSignalListener(syncManagerMock, fullSettings, fakeStorageDebug as IStorageSync, fakeSplitApi); + const listener = new BrowserSignalListener(syncManagerMock, fullSettings, fakeStorageDebug, fakeSplitApi); listener.start(); assertStart(listener); @@ -234,7 +240,7 @@ test('Browser JS listener / standalone mode / Impressions debug mode', () => { test('Browser JS listener / standalone mode / Fallback to regular Fetch transport', () => { function runBrowserListener() { // @ts-expect-error - const listener = new BrowserSignalListener({}, fullSettings, fakeStorageDebug as IStorageSync, fakeSplitApi); + const listener = new BrowserSignalListener({}, fullSettings, fakeStorageDebug, fakeSplitApi); listener.start(); // Trigger data flush triggerEvent(VISIBILITYCHANGE_EVENT, 'hidden'); @@ -270,7 +276,7 @@ test('Browser JS listener / standalone mode / user consent status', () => { const settings = { ...fullSettings }; // @ts-expect-error - const listener = new BrowserSignalListener(syncManagerMock, settings, fakeStorageOptimized as IStorageSync, fakeSplitApi); + const listener = new BrowserSignalListener(syncManagerMock, settings, fakeStorageOptimized, fakeSplitApi); listener.start(); diff --git a/src/listeners/browser.ts b/src/listeners/browser.ts index ffd86004..a43ed22c 100644 --- a/src/listeners/browser.ts +++ b/src/listeners/browser.ts @@ -84,9 +84,8 @@ export class BrowserSignalListener implements ISignalListener { this._flushData(events + '/testImpressions/beacon', this.storage.impressions, this.serviceApi.postTestImpressionsBulk, this.fromImpressionsCollector, extraMetadata); this._flushData(events + '/events/beacon', this.storage.events, this.serviceApi.postEventsBulk); - if (this.storage.impressionCounts) this._flushData(events + '/testImpressions/count/beacon', this.storage.impressionCounts, this.serviceApi.postTestImpressionsCount, fromImpressionCountsCollector); - // @ts-ignore - if (this.storage.uniqueKeys) this._flushData(telemetry + '/v1/keys/cs/beacon', this.storage.uniqueKeys, this.serviceApi.postUniqueKeysBulkCs); + this._flushData(events + '/testImpressions/count/beacon', this.storage.impressionCounts, this.serviceApi.postTestImpressionsCount, fromImpressionCountsCollector); + this._flushData(telemetry + '/v1/keys/cs/beacon', this.storage.uniqueKeys, this.serviceApi.postUniqueKeysBulkCs); } // Flush telemetry data