Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 8 additions & 7 deletions src/readiness/__tests__/sdkReadinessManager.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -220,19 +220,20 @@ describe('SDK Readiness Manager - Promises', () => {

// make the SDK ready from cache
sdkReadinessManager.readinessManager.splits.emit(SDK_SPLITS_CACHE_LOADED, { initialCacheLoad: false, lastUpdateTimestamp: null });
expect(await sdkReadinessManager.sdkStatus.whenReadyFromCache()).toBe(false);
expect(await sdkReadinessManager.sdkStatus.whenReadyFromCache()).toEqual({ initialCacheLoad: false, lastUpdateTimestamp: null });

// validate error log for SDK_READY_FROM_CACHE
expect(loggerMock.error).not.toBeCalled();
sdkReadinessManager.readinessManager.gate.on(SDK_READY_FROM_CACHE, () => {});
sdkReadinessManager.readinessManager.gate.on(SDK_READY_FROM_CACHE, () => { });
expect(loggerMock.error).toBeCalledWith(ERROR_CLIENT_LISTENER, ['SDK_READY_FROM_CACHE']);

const readyFromCache = sdkReadinessManager.sdkStatus.whenReadyFromCache();
const ready = sdkReadinessManager.sdkStatus.whenReady();

// make the SDK ready
emitReadyEvent(sdkReadinessManager.readinessManager);
expect(await sdkReadinessManager.sdkStatus.whenReadyFromCache()).toBe(true);
expect(await sdkReadinessManager.sdkStatus.whenReadyFromCache()).toEqual({ initialCacheLoad: false, lastUpdateTimestamp: null });
expect(await sdkReadinessManager.sdkStatus.whenReady()).toEqual({ initialCacheLoad: false, lastUpdateTimestamp: null });

let testPassedCount = 0;
function incTestPassedCount() { testPassedCount++; }
Expand Down Expand Up @@ -260,12 +261,12 @@ describe('SDK Readiness Manager - Promises', () => {
function incTestPassedCount() { testPassedCount++; }
function throwTestFailed() { throw new Error('It should rejected, not resolved.'); }

await readyFromCacheForTimeout.then(throwTestFailed,incTestPassedCount);
await readyForTimeout.then(throwTestFailed,incTestPassedCount);
await readyFromCacheForTimeout.then(throwTestFailed, incTestPassedCount);
await readyForTimeout.then(throwTestFailed, incTestPassedCount);

// any subsequent call to .whenReady() and .whenReadyFromCache() must be a rejected promise until the SDK is ready
await sdkReadinessManagerForTimedout.sdkStatus.whenReadyFromCache().then(throwTestFailed,incTestPassedCount);
await sdkReadinessManagerForTimedout.sdkStatus.whenReady().then(throwTestFailed,incTestPassedCount);
await sdkReadinessManagerForTimedout.sdkStatus.whenReadyFromCache().then(throwTestFailed, incTestPassedCount);
await sdkReadinessManagerForTimedout.sdkStatus.whenReady().then(throwTestFailed, incTestPassedCount);

// make the SDK ready
emitReadyEvent(sdkReadinessManagerForTimedout.readinessManager);
Expand Down
3 changes: 2 additions & 1 deletion src/readiness/readinessManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,8 @@ export function readinessManagerFactory(
hasTimedout() { return hasTimedout; },
isDestroyed() { return isDestroyed; },
isOperational() { return (isReady || isReadyFromCache) && !isDestroyed; },
lastUpdate() { return lastUpdate; }
lastUpdate() { return lastUpdate; },
metadataReady() { return metadataReady; }
};

}
10 changes: 5 additions & 5 deletions src/readiness/sdkReadinessManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,9 +120,9 @@ export function sdkReadinessManagerFactory(
},

whenReady() {
return new Promise<void>((resolve, reject) => {
return new Promise<SplitIO.SdkReadyMetadata>((resolve, reject) => {
if (readinessManager.isReady()) {
resolve();
resolve(readinessManager.metadataReady());
} else if (readinessManager.hasTimedout()) {
reject(TIMEOUT_ERROR);
} else {
Expand All @@ -133,13 +133,13 @@ export function sdkReadinessManagerFactory(
},

whenReadyFromCache() {
return new Promise<boolean>((resolve, reject) => {
return new Promise<SplitIO.SdkReadyMetadata>((resolve, reject) => {
if (readinessManager.isReadyFromCache()) {
resolve(readinessManager.isReady());
resolve(readinessManager.metadataReady());
} else if (readinessManager.hasTimedout()) {
reject(TIMEOUT_ERROR);
} else {
readinessManager.gate.once(SDK_READY_FROM_CACHE, () => resolve(readinessManager.isReady()));
readinessManager.gate.once(SDK_READY_FROM_CACHE, resolve);
readinessManager.gate.once(SDK_READY_TIMED_OUT, () => reject(TIMEOUT_ERROR));
}
});
Expand Down
1 change: 1 addition & 0 deletions src/readiness/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ export interface IReadinessManager {
isDestroyed(): boolean,
isOperational(): boolean,
lastUpdate(): number,
metadataReady(): SplitIO.SdkReadyMetadata,

timeout(): void,
setDestroyed(): void,
Expand Down
11 changes: 6 additions & 5 deletions types/splitio.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -831,18 +831,19 @@ declare namespace SplitIO {
* As it's meant to provide similar flexibility than event listeners, given that the SDK might be ready after a timeout event, the `whenReady` method will return a resolved promise once the SDK is ready.
* You must handle the promise rejection to avoid an unhandled promise rejection error, or set the `startup.readyTimeout` configuration option to 0 to avoid the timeout and thus the rejection.
*
* @returns A promise that resolves once the SDK_READY event is emitted or rejects if the SDK has timedout.
* @returns A promise that resolves once the SDK_READY event is emitted or rejects if the SDK has timedout. The promise resolves with a metadata object that contains the `initialCacheLoad` property,
* which indicates whether the SDK_READY event was emitted together with the SDK_READY_FROM_CACHE event (i.e., fresh install/first app launch) or not (warm cache/subsequent app launch).
*/
whenReady(): Promise<void>;
whenReady(): Promise<SdkReadyMetadata>;
/**
* Returns a promise that resolves when the SDK is ready for evaluations using cached data, which might not yet be synchronized with the backend (`SDK_READY_FROM_CACHE` event emitted), or rejected if the SDK has timedout (`SDK_READY_TIMED_OUT` event emitted).
* As it's meant to provide similar flexibility than event listeners, given that the SDK might be ready from cache after a timeout event, the `whenReadyFromCache` method will return a resolved promise once the SDK is ready from cache.
* You must handle the promise rejection to avoid an unhandled promise rejection error, or set the `startup.readyTimeout` configuration option to 0 to avoid the timeout and thus the rejection.
*
* @returns A promise that resolves once the SDK_READY_FROM_CACHE event is emitted or rejects if the SDK has timedout. The promise resolves with a boolean value that
* indicates whether the SDK_READY_FROM_CACHE event was emitted together with the SDK_READY event (i.e., the SDK is ready and synchronized with the backend) or not.
* @returns A promise that resolves once the SDK_READY_FROM_CACHE event is emitted or rejects if the SDK has timedout. The promise resolves with a metadata object that contains the `initialCacheLoad` property,
* which indicates whether the SDK_READY_FROM_CACHE event was emitted together with the SDK_READY event (i.e., fresh install/first app launch) or not (warm cache/subsequent app launch).
*/
whenReadyFromCache(): Promise<boolean>;
whenReadyFromCache(): Promise<SdkReadyMetadata>;
}
/**
* Common definitions between clients for different environments interface.
Expand Down