From 1efe8199721f7c5cee04085e14ba4b315bbf4c36 Mon Sep 17 00:00:00 2001 From: Mike Chu Date: Fri, 20 Oct 2023 15:14:27 +0000 Subject: [PATCH 01/13] chore: only yarn install during container create --- .devcontainer/devcontainer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 80d0fa17..0f32afdd 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -3,7 +3,7 @@ "image": "mcr.microsoft.com/devcontainers/javascript-node:1-18-bullseye", - "postCreateCommand": "npm install -g npm && yarn install", + "postCreateCommand": "yarn install", "customizations": { "vscode": { From b9cc3822ec4a24705521ca8e49f1088c16419c70 Mon Sep 17 00:00:00 2001 From: Mike Chu Date: Fri, 20 Oct 2023 15:21:35 +0000 Subject: [PATCH 02/13] chore: add copilot & chat to dev container --- .devcontainer/devcontainer.json | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 0f32afdd..49503577 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -1,10 +1,7 @@ { "name": "React SDK", - "image": "mcr.microsoft.com/devcontainers/javascript-node:1-18-bullseye", - "postCreateCommand": "yarn install", - "customizations": { "vscode": { "extensions": [ @@ -14,11 +11,12 @@ "Gruntfuggly.todo-tree", "github.vscode-github-actions", "Orta.vscode-jest", - "ms-vscode.test-adapter-converter" + "ms-vscode.test-adapter-converter", + "GitHub.copilot-chat" ], "settings": { "files.eol": "\n" } } } -} +} \ No newline at end of file From 096c82734f2bff76d1694f5adf1cb3938246b57d Mon Sep 17 00:00:00 2001 From: Mike Chu Date: Fri, 20 Oct 2023 16:27:28 +0000 Subject: [PATCH 03/13] fix: add missing getVuid method --- src/client.ts | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/client.ts b/src/client.ts index 33107de8..8737f20d 100644 --- a/src/client.ts +++ b/src/client.ts @@ -49,7 +49,7 @@ const default_user: UserInfo = { attributes: {}, }; -export interface ReactSDKClient extends Omit { +export interface ReactSDKClient extends Omit { user: UserInfo; onReady(opts?: { timeout?: number }): Promise; @@ -180,6 +180,8 @@ export interface ReactSDKClient extends Omit; + + getVuid(): string | undefined; } export const DEFAULT_ON_READY_TIMEOUT = 5000; @@ -219,7 +221,7 @@ class OptimizelyReactSDKClient implements ReactSDKClient { */ constructor(config: optimizely.Config) { this.initialConfig = config; - this.userPromiseResolver = () => { }; + this.userPromiseResolver = () => {}; const configWithClientInfo = { ...config, @@ -1227,6 +1229,14 @@ class OptimizelyReactSDKClient implements ReactSDKClient { this.client?.sendOdpEvent(action, type, identifiers, data); } + + public getVuid(): string | undefined { + if (!this._client) { + logger.warn('Unable to get VUID because Optimizely client failed to initialize.'); + return undefined; + } + return this._client.getVuid(); + } } export function createInstance(config: optimizely.Config): ReactSDKClient { From 43438b4fea1cb357a703ac57caf3d2b36f549e72 Mon Sep 17 00:00:00 2001 From: Mike Chu Date: Fri, 20 Oct 2023 18:57:43 +0000 Subject: [PATCH 04/13] test: add unit tests for getVuid --- src/client.spec.ts | 49 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) diff --git a/src/client.spec.ts b/src/client.spec.ts index 759fe2e1..55da16eb 100644 --- a/src/client.spec.ts +++ b/src/client.spec.ts @@ -269,7 +269,7 @@ describe('ReactSDKClient', () => { await instance.setUser({ id: 'xxfueaojfe8&86', }); - await instance.onReady() + await instance.onReady(); await instance.setUser({ id: 'xxfueaojfe8&87', @@ -1624,4 +1624,51 @@ describe('ReactSDKClient', () => { expect(mockInnerClient.sendOdpEvent).toHaveBeenCalledTimes(1); }); }); + + describe('getVuid', () => { + const vuidFormat = /^vuid_[a-f0-9]{27}$/; + let instance: ReactSDKClient; + + beforeEach(async () => { + instance = createInstance(config); + }); + + + it('should return undefined if client is null', () => { + // @ts-ignore + instance._client = null; + + const vuid = instance.getVuid(); + + expect(vuid).toBeUndefined(); + }); + + it('should call the JS getVuid if a user set', async () => { + await instance.setUser({ + id: 'user1', + }); + + instance.getVuid(); + + expect(mockInnerClient.getVuid).toHaveBeenCalledTimes(1); + expect(logger.warn).toHaveBeenCalledTimes(0); + }); + + it('should call the JS getVuid if even if a user is not set', async () => { + instance.getVuid(); + + expect(mockInnerClient.getVuid).toHaveBeenCalledTimes(1); + expect(logger.warn).toHaveBeenCalledTimes(0); + }); + + it('should return a valid vuid', async () => { + const validVuid = 'vuid_8de3bb278fce47f6b000cadc1ac'; + const mockGetVuid = mockInnerClient.getVuid as jest.Mock; + mockGetVuid.mockReturnValue(validVuid); + + const vuid = instance.getVuid(); + + expect(vuid).toMatch(vuidFormat); + }); + }); }); From 90f1590412e4eb5a2353b5163f3ebfa60d45b3c8 Mon Sep 17 00:00:00 2001 From: Mike Chu Date: Fri, 20 Oct 2023 20:18:48 +0000 Subject: [PATCH 05/13] fix: user context not saving to this.userContext --- src/client.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/client.ts b/src/client.ts index 8737f20d..0e6fbea4 100644 --- a/src/client.ts +++ b/src/client.ts @@ -184,7 +184,7 @@ export interface ReactSDKClient extends Omit Date: Fri, 20 Oct 2023 20:50:04 +0000 Subject: [PATCH 06/13] feat: add getQualifedSegments --- src/client.ts | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/client.ts b/src/client.ts index 0e6fbea4..edebfe06 100644 --- a/src/client.ts +++ b/src/client.ts @@ -181,6 +181,8 @@ export interface ReactSDKClient extends Omit; + getQualifedSegments(): string[] | null; + getVuid(): string | undefined; } @@ -369,6 +371,15 @@ class OptimizelyReactSDKClient implements ReactSDKClient { return await this.userContext.fetchQualifiedSegments(options); } + public getQualifedSegments(): string[] | null { + if (!this.userContext) { + logger.warn('Unable to get qualified segments for user because Optimizely user context failed to initialize.'); + return []; + } + + return this.userContext.qualifiedSegments; + } + public async setUser(userInfo: UserInfo): Promise { this.isUserReady = true; From 326c38e78ab42311984dcc4c35d8cddff045e776 Mon Sep 17 00:00:00 2001 From: Mike Chu Date: Fri, 20 Oct 2023 20:53:38 +0000 Subject: [PATCH 07/13] test(wip): adding getQualifedSegments tests --- src/client.spec.ts | 33 +++++++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/src/client.spec.ts b/src/client.spec.ts index 55da16eb..c9d89b05 100644 --- a/src/client.spec.ts +++ b/src/client.spec.ts @@ -1632,7 +1632,6 @@ describe('ReactSDKClient', () => { beforeEach(async () => { instance = createInstance(config); }); - it('should return undefined if client is null', () => { // @ts-ignore @@ -1671,4 +1670,34 @@ describe('ReactSDKClient', () => { expect(vuid).toMatch(vuidFormat); }); }); -}); + + describe('getQualifedSegments', () => { + let instance: ReactSDKClient; + + beforeEach(async () => { + instance = createInstance(config); + }); + + it('returns null if userContext is not initialized', () => { + instance['userContext'] = null; + + expect(instance.getQualifedSegments()).toBeNull(); + }); + + it('returns qualified segments if userContext is initialized', () => { + instance['userContext'] = { + qualifiedSegments: ['segment1', 'segment2'], + }; + + expect(instance.getQualifedSegments()).toEqual(['segment1', 'segment2']); + }); + + it('logs a warning if userContext is not initialized', () => { + const loggerWarnSpy = jest.spyOn(logger, 'warn'); + + instance.getQualifedSegments(); + + expect(loggerWarnSpy).toHaveBeenCalledWith('Unable to get qualified segments for user because Optimizely user context failed to initialize.'); + }); + }); +}); \ No newline at end of file From da27443addd4048c309a29ada39ce2042997de12 Mon Sep 17 00:00:00 2001 From: Mike Chu Date: Fri, 27 Oct 2023 21:22:47 +0000 Subject: [PATCH 08/13] chore: lint fix --- .devcontainer/devcontainer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 49503577..d46c3bef 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -19,4 +19,4 @@ } } } -} \ No newline at end of file +} From 9e02ff894e81adc37b0015ab786fcc2efe80c392 Mon Sep 17 00:00:00 2001 From: Mike Chu Date: Fri, 27 Oct 2023 21:23:07 +0000 Subject: [PATCH 09/13] test: fix test & implementation --- src/client.spec.ts | 14 ++++++++------ src/client.ts | 2 +- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/client.spec.ts b/src/client.spec.ts index c9d89b05..0ebbc66e 100644 --- a/src/client.spec.ts +++ b/src/client.spec.ts @@ -1679,16 +1679,18 @@ describe('ReactSDKClient', () => { }); it('returns null if userContext is not initialized', () => { - instance['userContext'] = null; + // @ts-ignore + instance.userContext = null; expect(instance.getQualifedSegments()).toBeNull(); }); - it('returns qualified segments if userContext is initialized', () => { - instance['userContext'] = { + it('returns qualified segments if userContext is initialized', () => { + // @ts-ignore + instance.userContext = { qualifiedSegments: ['segment1', 'segment2'], }; - + expect(instance.getQualifedSegments()).toEqual(['segment1', 'segment2']); }); @@ -1696,8 +1698,8 @@ describe('ReactSDKClient', () => { const loggerWarnSpy = jest.spyOn(logger, 'warn'); instance.getQualifedSegments(); - + expect(loggerWarnSpy).toHaveBeenCalledWith('Unable to get qualified segments for user because Optimizely user context failed to initialize.'); }); }); -}); \ No newline at end of file +}); diff --git a/src/client.ts b/src/client.ts index edebfe06..10e95125 100644 --- a/src/client.ts +++ b/src/client.ts @@ -374,7 +374,7 @@ class OptimizelyReactSDKClient implements ReactSDKClient { public getQualifedSegments(): string[] | null { if (!this.userContext) { logger.warn('Unable to get qualified segments for user because Optimizely user context failed to initialize.'); - return []; + return null; } return this.userContext.qualifiedSegments; From e6a6d25e5dddc2e75df0b27d05f033df32644c26 Mon Sep 17 00:00:00 2001 From: Mike Chu Date: Thu, 2 Nov 2023 14:49:06 +0000 Subject: [PATCH 10/13] fix: requsted PR adjustments --- src/client.spec.ts | 55 ++++++++++++++++++++++++++++++++++++---------- src/client.ts | 15 +++---------- 2 files changed, 46 insertions(+), 24 deletions(-) diff --git a/src/client.spec.ts b/src/client.spec.ts index 0ebbc66e..2def0b47 100644 --- a/src/client.spec.ts +++ b/src/client.spec.ts @@ -29,6 +29,8 @@ import * as optimizely from '@optimizely/optimizely-sdk'; import { createInstance, OnReadyResult, ReactSDKClient } from './client'; import { logger } from './logger'; +import * as utils from './utils'; +import { OptimizelyUserContext } from '@optimizely/optimizely-sdk'; interface MockedReactSDKClient extends ReactSDKClient { client: optimizely.Client; @@ -1671,35 +1673,64 @@ describe('ReactSDKClient', () => { }); }); - describe('getQualifedSegments', () => { + describe('getUserContextInstance', () => { let instance: ReactSDKClient; beforeEach(async () => { instance = createInstance(config); }); - it('returns null if userContext is not initialized', () => { + it('should log a warning if client is not defined', () => { + // @ts-ignore + instance._client = null; + + instance.getUserContextInstance({ id: 'user1' }); + + expect(logger.warn).toHaveBeenCalledTimes(1); + expect(logger.warn).toBeCalledWith("Unable to get user context for user id \"%s\" because Optimizely client failed to initialize.", "user1"); + }); + + it('should return null if userContext is not initialized', () => { // @ts-ignore instance.userContext = null; - expect(instance.getQualifedSegments()).toBeNull(); + const context = instance.getUserContextInstance({ id: 'user1' }); + + expect(context).toBeDefined(); }); - it('returns qualified segments if userContext is initialized', () => { + it('should test that this.userContext are equal', () => { + const expectedUserInfo = { id: 'user1', attributes: { custom: 'attribute' } } as utils.UserInfo; + jest.spyOn(utils, 'areUsersEqual'); + // @ts-ignore + instance.userContext = mockOptimizelyUserContext; // @ts-ignore - instance.userContext = { - qualifiedSegments: ['segment1', 'segment2'], - }; + instance.user = expectedUserInfo; - expect(instance.getQualifedSegments()).toEqual(['segment1', 'segment2']); + instance.getUserContextInstance(expectedUserInfo); + + expect(utils.areUsersEqual).toBeCalledTimes(1); + expect(utils.areUsersEqual).toHaveBeenCalledWith(expectedUserInfo, expectedUserInfo); + }); + + it('should return userContext if userContext is not defined', () => { + const expectedUserInfo = { id: 'user1', attributes: { custom: 'attribute' } } as utils.UserInfo; + // @ts-ignore + instance.userContext = null; + + const actualContext = instance.getUserContextInstance(expectedUserInfo); + + expect(actualContext).toBeDefined(); }); - it('logs a warning if userContext is not initialized', () => { - const loggerWarnSpy = jest.spyOn(logger, 'warn'); + it('should set and return userContext if userContext is defined', () => { + const expectedUserInfo = { id: 'user1', attributes: { custom: 'attribute' } } as utils.UserInfo; + // @ts-ignore + instance.userContext = {}; - instance.getQualifedSegments(); + const actualContext = instance.getUserContextInstance(expectedUserInfo); - expect(loggerWarnSpy).toHaveBeenCalledWith('Unable to get qualified segments for user because Optimizely user context failed to initialize.'); + expect(actualContext).toBeDefined(); }); }); }); diff --git a/src/client.ts b/src/client.ts index 10e95125..7d718652 100644 --- a/src/client.ts +++ b/src/client.ts @@ -181,7 +181,7 @@ export interface ReactSDKClient extends Omit; - getQualifedSegments(): string[] | null; + getUserContextInstance(userInfo: UserInfo): optimizely.OptimizelyUserContext | null; getVuid(): string | undefined; } @@ -347,8 +347,8 @@ class OptimizelyReactSDKClient implements ReactSDKClient { } if (userInfo.id) { - this.userContext = this._client.createUserContext(userInfo.id, userInfo.attributes); - return this.userContext; + userContext = this._client.createUserContext(userInfo.id, userInfo.attributes); + return userContext; } return null; @@ -371,15 +371,6 @@ class OptimizelyReactSDKClient implements ReactSDKClient { return await this.userContext.fetchQualifiedSegments(options); } - public getQualifedSegments(): string[] | null { - if (!this.userContext) { - logger.warn('Unable to get qualified segments for user because Optimizely user context failed to initialize.'); - return null; - } - - return this.userContext.qualifiedSegments; - } - public async setUser(userInfo: UserInfo): Promise { this.isUserReady = true; From af22f35e6e87cd06662715decd3d2fed26ed4dde Mon Sep 17 00:00:00 2001 From: Mike Chu Date: Fri, 3 Nov 2023 13:33:33 +0000 Subject: [PATCH 11/13] test: update tests per PR request --- src/client.spec.ts | 19 +------------------ 1 file changed, 1 insertion(+), 18 deletions(-) diff --git a/src/client.spec.ts b/src/client.spec.ts index 2def0b47..ed0428fa 100644 --- a/src/client.spec.ts +++ b/src/client.spec.ts @@ -1644,24 +1644,6 @@ describe('ReactSDKClient', () => { expect(vuid).toBeUndefined(); }); - it('should call the JS getVuid if a user set', async () => { - await instance.setUser({ - id: 'user1', - }); - - instance.getVuid(); - - expect(mockInnerClient.getVuid).toHaveBeenCalledTimes(1); - expect(logger.warn).toHaveBeenCalledTimes(0); - }); - - it('should call the JS getVuid if even if a user is not set', async () => { - instance.getVuid(); - - expect(mockInnerClient.getVuid).toHaveBeenCalledTimes(1); - expect(logger.warn).toHaveBeenCalledTimes(0); - }); - it('should return a valid vuid', async () => { const validVuid = 'vuid_8de3bb278fce47f6b000cadc1ac'; const mockGetVuid = mockInnerClient.getVuid as jest.Mock; @@ -1670,6 +1652,7 @@ describe('ReactSDKClient', () => { const vuid = instance.getVuid(); expect(vuid).toMatch(vuidFormat); + expect(vuid).toEqual(validVuid); }); }); From b40dd7608cc4b7edf35572b48347477b964ef7a5 Mon Sep 17 00:00:00 2001 From: Mike Chu Date: Fri, 3 Nov 2023 16:30:38 +0000 Subject: [PATCH 12/13] feat: add getUserContext --- src/client.spec.ts | 59 +++++++++++++++------------------------------- src/client.ts | 20 +++++++++++++++- 2 files changed, 38 insertions(+), 41 deletions(-) diff --git a/src/client.spec.ts b/src/client.spec.ts index ed0428fa..75338359 100644 --- a/src/client.spec.ts +++ b/src/client.spec.ts @@ -1656,64 +1656,43 @@ describe('ReactSDKClient', () => { }); }); - describe('getUserContextInstance', () => { + describe('getUserContext', () => { let instance: ReactSDKClient; beforeEach(async () => { instance = createInstance(config); }); - it('should log a warning if client is not defined', () => { + it('should log a warning and return null if client is not defined', () => { // @ts-ignore instance._client = null; - instance.getUserContextInstance({ id: 'user1' }); + instance.getUserContext(); expect(logger.warn).toHaveBeenCalledTimes(1); - expect(logger.warn).toBeCalledWith("Unable to get user context for user id \"%s\" because Optimizely client failed to initialize.", "user1"); + expect(logger.warn).toBeCalledWith("Unable to get user context because Optimizely client failed to initialize."); }); - it('should return null if userContext is not initialized', () => { - // @ts-ignore - instance.userContext = null; - - const context = instance.getUserContextInstance({ id: 'user1' }); - - expect(context).toBeDefined(); - }); - - it('should test that this.userContext are equal', () => { - const expectedUserInfo = { id: 'user1', attributes: { custom: 'attribute' } } as utils.UserInfo; - jest.spyOn(utils, 'areUsersEqual'); - // @ts-ignore - instance.userContext = mockOptimizelyUserContext; - // @ts-ignore - instance.user = expectedUserInfo; - - instance.getUserContextInstance(expectedUserInfo); - - expect(utils.areUsersEqual).toBeCalledTimes(1); - expect(utils.areUsersEqual).toHaveBeenCalledWith(expectedUserInfo, expectedUserInfo); - }); + + it('should log a warning and return null if setUser is not called first', () => { + instance.getUserContext(); - it('should return userContext if userContext is not defined', () => { - const expectedUserInfo = { id: 'user1', attributes: { custom: 'attribute' } } as utils.UserInfo; - // @ts-ignore - instance.userContext = null; - - const actualContext = instance.getUserContextInstance(expectedUserInfo); - - expect(actualContext).toBeDefined(); + expect(logger.warn).toHaveBeenCalledTimes(1); + expect(logger.warn).toBeCalledWith("Unable to get user context because user was not set."); }); - it('should set and return userContext if userContext is defined', () => { - const expectedUserInfo = { id: 'user1', attributes: { custom: 'attribute' } } as utils.UserInfo; - // @ts-ignore - instance.userContext = {}; + it('should return a userContext if setUser is called', () => { + instance.setUser({ + id: 'user1', + attributes: { + foo: 'bar', + }, + }); - const actualContext = instance.getUserContextInstance(expectedUserInfo); + const currentUserContext = instance.getUserContext(); - expect(actualContext).toBeDefined(); + expect(logger.warn).toHaveBeenCalledTimes(0); + expect(currentUserContext).not.toBeNull(); }); }); }); diff --git a/src/client.ts b/src/client.ts index 7d718652..ebbb9ac5 100644 --- a/src/client.ts +++ b/src/client.ts @@ -181,7 +181,7 @@ export interface ReactSDKClient extends Omit; - getUserContextInstance(userInfo: UserInfo): optimizely.OptimizelyUserContext | null; + getUserContext(): optimizely.OptimizelyUserContext | null; getVuid(): string | undefined; } @@ -330,6 +330,24 @@ class OptimizelyReactSDKClient implements ReactSDKClient { }); } + public getUserContext(): optimizely.OptimizelyUserContext | null { + if (!this._client) { + logger.warn( + 'Unable to get user context because Optimizely client failed to initialize.' + ); + return null; + } + + if (!this.userContext) { + logger.warn( + 'Unable to get user context because user was not set.' + ); + return null; + } + + return this.userContext; + } + public getUserContextInstance(userInfo: UserInfo): optimizely.OptimizelyUserContext | null { if (!this._client) { logger.warn( From 9d54ef15b62e4e773b0c6728f462df9455ce6520 Mon Sep 17 00:00:00 2001 From: Mike Chu Date: Fri, 3 Nov 2023 16:33:08 +0000 Subject: [PATCH 13/13] chore: lint fixes --- src/client.spec.ts | 4 +--- src/client.ts | 26 +++++++++++++------------- 2 files changed, 14 insertions(+), 16 deletions(-) diff --git a/src/client.spec.ts b/src/client.spec.ts index 75338359..4eb884c5 100644 --- a/src/client.spec.ts +++ b/src/client.spec.ts @@ -29,8 +29,6 @@ import * as optimizely from '@optimizely/optimizely-sdk'; import { createInstance, OnReadyResult, ReactSDKClient } from './client'; import { logger } from './logger'; -import * as utils from './utils'; -import { OptimizelyUserContext } from '@optimizely/optimizely-sdk'; interface MockedReactSDKClient extends ReactSDKClient { client: optimizely.Client; @@ -1673,7 +1671,7 @@ describe('ReactSDKClient', () => { expect(logger.warn).toBeCalledWith("Unable to get user context because Optimizely client failed to initialize."); }); - + it('should log a warning and return null if setUser is not called first', () => { instance.getUserContext(); diff --git a/src/client.ts b/src/client.ts index ebbb9ac5..e1f0e9ce 100644 --- a/src/client.ts +++ b/src/client.ts @@ -52,7 +52,7 @@ const default_user: UserInfo = { export interface ReactSDKClient extends Omit { user: UserInfo; - onReady(opts?: { timeout?: number }): Promise; + onReady(opts?: { timeout?: number; }): Promise; setUser(userInfo: UserInfo): Promise; onUserUpdate(handler: OnUserUpdateHandler): DisposeFn; isReady(): boolean; @@ -123,7 +123,7 @@ export interface ReactSDKClient extends Omit {}; + this.userPromiseResolver = () => { }; const configWithClientInfo = { ...config, @@ -295,7 +295,7 @@ class OptimizelyReactSDKClient implements ReactSDKClient { return this.isUsingSdkKey; } - public onReady(config: { timeout?: number } = {}): Promise { + public onReady(config: { timeout?: number; } = {}): Promise { let timeoutId: number | undefined; let timeout: number = DEFAULT_ON_READY_TIMEOUT; if (config && config.timeout !== undefined) { @@ -523,7 +523,7 @@ class OptimizelyReactSDKClient implements ReactSDKClient { options: optimizely.OptimizelyDecideOption[] = [], overrideUserId?: string, overrideAttributes?: optimizely.UserAttributes - ): { [key: string]: OptimizelyDecision } { + ): { [key: string]: OptimizelyDecision; } { if (!this._client) { logger.warn('Unable to evaluate features for keys because Optimizely client failed to initialize.'); return {}; @@ -539,7 +539,7 @@ class OptimizelyReactSDKClient implements ReactSDKClient { const optlyUserContext = this.getUserContextInstance(user); if (optlyUserContext) { return Object.entries(optlyUserContext.decideForKeys(keys, options)).reduce( - (decisions: { [key: string]: OptimizelyDecision }, [key, decision]) => { + (decisions: { [key: string]: OptimizelyDecision; }, [key, decision]) => { decisions[key] = { ...decision, userContext: { @@ -559,7 +559,7 @@ class OptimizelyReactSDKClient implements ReactSDKClient { options: optimizely.OptimizelyDecideOption[] = [], overrideUserId?: string, overrideAttributes?: optimizely.UserAttributes - ): { [key: string]: OptimizelyDecision } { + ): { [key: string]: OptimizelyDecision; } { if (!this._client) { logger.warn('Unable to evaluate all feature decisions because Optimizely client is not initialized.'); return {}; @@ -575,7 +575,7 @@ class OptimizelyReactSDKClient implements ReactSDKClient { const optlyUserContext = this.getUserContextInstance(user); if (optlyUserContext) { return Object.entries(optlyUserContext.decideAll(options)).reduce( - (decisions: { [key: string]: OptimizelyDecision }, [key, decision]) => { + (decisions: { [key: string]: OptimizelyDecision; }, [key, decision]) => { decisions[key] = { ...decision, userContext: { @@ -1055,7 +1055,7 @@ class OptimizelyReactSDKClient implements ReactSDKClient { featureKey: string, overrideUserId: string, overrideAttributes?: optimizely.UserAttributes - ): { [variableKey: string]: unknown } | null { + ): { [variableKey: string]: unknown; } | null { if (!this._client) { logger.warn( 'Unable to get all feature variables from feature "%s" because Optimizely client failed to initialize.', @@ -1184,7 +1184,7 @@ class OptimizelyReactSDKClient implements ReactSDKClient { * Cleanup method for killing an running timers and flushing eventQueue * @returns {Promise<{ success: boolean; reason?: string }>} */ - public close(): Promise<{ success: boolean; reason?: string }> { + public close(): Promise<{ success: boolean; reason?: string; }> { if (!this._client) { /** * Note: @@ -1193,7 +1193,7 @@ class OptimizelyReactSDKClient implements ReactSDKClient { * - If we resolve as "false", then the cleanup for timers and the event queue will never trigger. * - Not triggering cleanup may lead to memory leaks and other inefficiencies. */ - return new Promise<{ success: boolean; reason: string }>((resolve, reject) => + return new Promise<{ success: boolean; reason: string; }>((resolve, reject) => resolve({ success: true, reason: 'Optimizely client is not initialized.',