diff --git a/CHANGES.txt b/CHANGES.txt index 16467ba2..8f571946 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -2,6 +2,7 @@ - Added two new configuration options for the SDK storage in browsers when using storage type `LOCALSTORAGE`: - `storage.expirationDays` to specify the validity period of the rollout cache. - `storage.clearOnInit` to clear the rollout cache on SDK initialization. + - Updated SDK_READY_FROM_CACHE event when using the `LOCALSTORAGE` storage type to be emitted alongside the SDK_READY event if it has not already been emitted. 2.1.0 (January 17, 2025) - Added support for the new impressions tracking toggle available on feature flags, both respecting the setting and including the new field being returned on `SplitView` type objects. Read more in our docs. diff --git a/src/readiness/__tests__/readinessManager.spec.ts b/src/readiness/__tests__/readinessManager.spec.ts index 9e2cf34a..174f1373 100644 --- a/src/readiness/__tests__/readinessManager.spec.ts +++ b/src/readiness/__tests__/readinessManager.spec.ts @@ -3,10 +3,14 @@ import { EventEmitter } from '../../utils/MinEvents'; import { IReadinessManager } from '../types'; import { SDK_READY, SDK_UPDATE, SDK_SPLITS_ARRIVED, SDK_SEGMENTS_ARRIVED, SDK_READY_FROM_CACHE, SDK_SPLITS_CACHE_LOADED, SDK_READY_TIMED_OUT } from '../constants'; import { ISettings } from '../../types'; +import { STORAGE_LOCALSTORAGE } from '../../utils/constants'; const settings = { startup: { readyTimeout: 0, + }, + storage: { + type: STORAGE_LOCALSTORAGE } } as unknown as ISettings; @@ -67,7 +71,14 @@ test('READINESS MANAGER / Ready event should be fired once', () => { const readinessManager = readinessManagerFactory(EventEmitter, settings); let counter = 0; + readinessManager.gate.on(SDK_READY_FROM_CACHE, () => { + expect(readinessManager.isReadyFromCache()).toBe(true); + expect(readinessManager.isReady()).toBe(true); + counter++; + }); + readinessManager.gate.on(SDK_READY, () => { + expect(readinessManager.isReadyFromCache()).toBe(true); expect(readinessManager.isReady()).toBe(true); counter++; }); @@ -79,7 +90,7 @@ test('READINESS MANAGER / Ready event should be fired once', () => { readinessManager.splits.emit(SDK_SPLITS_ARRIVED); readinessManager.segments.emit(SDK_SEGMENTS_ARRIVED); - expect(counter).toBe(1); // should be called once + expect(counter).toBe(2); // should be called once }); test('READINESS MANAGER / Ready from cache event should be fired once', (done) => { @@ -88,6 +99,7 @@ test('READINESS MANAGER / Ready from cache event should be fired once', (done) = readinessManager.gate.on(SDK_READY_FROM_CACHE, () => { expect(readinessManager.isReadyFromCache()).toBe(true); + expect(readinessManager.isReady()).toBe(false); counter++; }); diff --git a/src/readiness/readinessManager.ts b/src/readiness/readinessManager.ts index 6f46474d..c69eedce 100644 --- a/src/readiness/readinessManager.ts +++ b/src/readiness/readinessManager.ts @@ -3,6 +3,7 @@ import { ISettings } from '../types'; import SplitIO from '../../types/splitio'; import { SDK_SPLITS_ARRIVED, SDK_SPLITS_CACHE_LOADED, SDK_SEGMENTS_ARRIVED, SDK_READY_TIMED_OUT, SDK_READY_FROM_CACHE, SDK_UPDATE, SDK_READY } from './constants'; import { IReadinessEventEmitter, IReadinessManager, ISegmentsEventEmitter, ISplitsEventEmitter } from './types'; +import { STORAGE_LOCALSTORAGE } from '../utils/constants'; function splitsEventEmitterFactory(EventEmitter: new () => SplitIO.IEventEmitter): ISplitsEventEmitter { const splitsEventEmitter = objectAssign(new EventEmitter(), { @@ -114,6 +115,10 @@ export function readinessManagerFactory( isReady = true; try { syncLastUpdate(); + if (!isReadyFromCache && settings.storage?.type === STORAGE_LOCALSTORAGE) { + isReadyFromCache = true; + gate.emit(SDK_READY_FROM_CACHE); + } gate.emit(SDK_READY); } catch (e) { // throws user callback exceptions in next tick