Skip to content

Commit d9d2a15

Browse files
authored
feat: Evaluation Details (#90)
1 parent cab78cb commit d9d2a15

File tree

6 files changed

+101
-20
lines changed

6 files changed

+101
-20
lines changed

.vscode/settings.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"eslint.format.enable": true,
33
"editor.codeActionsOnSave": {
4-
"source.fixAll.eslint": true
4+
"source.fixAll.eslint": "explicit"
55
}
66
}

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@eppo/js-client-sdk",
3-
"version": "3.3.0",
3+
"version": "3.4.0",
44
"description": "Eppo SDK for client-side JavaScript applications",
55
"main": "dist/index.js",
66
"files": [
@@ -56,6 +56,6 @@
5656
"webpack-cli": "^4.10.0"
5757
},
5858
"dependencies": {
59-
"@eppo/js-client-sdk-common": "3.5.0"
59+
"@eppo/js-client-sdk-common": "4.0.0"
6060
}
6161
}

src/index.spec.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import {
1111
HybridConfigurationStore,
1212
IAsyncStore,
1313
AssignmentCache,
14+
EppoClient,
1415
} from '@eppo/js-client-sdk-common';
1516
import * as td from 'testdouble';
1617

@@ -31,7 +32,6 @@ import { ServingStoreUpdateStrategy } from './isolatable-hybrid.store';
3132
import {
3233
offlineInit,
3334
IAssignmentLogger,
34-
IEppoClient,
3535
getInstance,
3636
init,
3737
IClientConfig,
@@ -171,7 +171,7 @@ const mockObfuscatedUfcFlagConfig: Flag = {
171171
};
172172

173173
describe('EppoJSClient E2E test', () => {
174-
let globalClient: IEppoClient;
174+
let globalClient: EppoClient;
175175
let mockLogger: IAssignmentLogger;
176176

177177
beforeAll(async () => {
@@ -412,9 +412,9 @@ describe('initialization options', () => {
412412
} as unknown as Record<'flags', Record<string, Flag>>;
413413

414414
// eslint-disable-next-line @typescript-eslint/ban-types
415-
let init: (config: IClientConfig) => Promise<IEppoClient>;
415+
let init: (config: IClientConfig) => Promise<EppoClient>;
416416
// eslint-disable-next-line @typescript-eslint/ban-types
417-
let getInstance: () => IEppoClient;
417+
let getInstance: () => EppoClient;
418418

419419
beforeEach(async () => {
420420
jest.isolateModules(() => {
@@ -626,7 +626,7 @@ describe('initialization options', () => {
626626
test.each([false, true])(
627627
'Wait or not for fetch when cache is expired - %s',
628628
async (useExpiredCache) => {
629-
let updatedStoreEntries = null;
629+
let updatedStoreEntries: Record<string, Flag> | null = null;
630630
const mockStore: IAsyncStore<Flag> = {
631631
isInitialized() {
632632
return true;
@@ -816,7 +816,7 @@ describe('initialization options', () => {
816816
expect(mockStoreEntries).toEqual(mockConfigResponse.flags);
817817
});
818818

819-
test.each(['always', 'expired', 'empty'])(
819+
test.each(['always', 'expired', 'empty'] as ServingStoreUpdateStrategy[])(
820820
'Fetch updates cache according to the "%s" update strategy',
821821
async (updateOnFetch: ServingStoreUpdateStrategy) => {
822822
// Mock fetch so first call works immediately, and all others takes time

src/index.ts

Lines changed: 86 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import {
22
IAssignmentLogger,
33
validation,
4-
IEppoClient,
54
EppoClient,
65
FlagConfigurationRequestParameters,
76
Flag,
@@ -10,6 +9,9 @@ import {
109
ObfuscatedFlag,
1110
ApiEndpoints,
1211
applicationLogger,
12+
IAssignmentDetails,
13+
BanditActions,
14+
BanditSubjectAttributes,
1315
} from '@eppo/js-client-sdk-common';
1416

1517
import { assignmentCacheFactory } from './cache/assignment-cache-factory';
@@ -125,9 +127,9 @@ export interface IClientConfigSync {
125127

126128
// Export the common types and classes from the SDK.
127129
export {
128-
IAssignmentLogger,
130+
IAssignmentDetails,
129131
IAssignmentEvent,
130-
IEppoClient,
132+
IAssignmentLogger,
131133
IAsyncStore,
132134
Flag,
133135
ObfuscatedFlag,
@@ -166,6 +168,16 @@ export class EppoJSClient extends EppoClient {
166168
return super.getStringAssignment(flagKey, subjectKey, subjectAttributes, defaultValue);
167169
}
168170

171+
public getStringAssignmentDetails(
172+
flagKey: string,
173+
subjectKey: string,
174+
subjectAttributes: Record<string, AttributeType>,
175+
defaultValue: string,
176+
): IAssignmentDetails<string> {
177+
EppoJSClient.getAssignmentInitializationCheck();
178+
return super.getStringAssignmentDetails(flagKey, subjectKey, subjectAttributes, defaultValue);
179+
}
180+
169181
/**
170182
* @deprecated Use getBooleanAssignment instead
171183
*/
@@ -188,6 +200,16 @@ export class EppoJSClient extends EppoClient {
188200
return super.getBooleanAssignment(flagKey, subjectKey, subjectAttributes, defaultValue);
189201
}
190202

203+
public getBooleanAssignmentDetails(
204+
flagKey: string,
205+
subjectKey: string,
206+
subjectAttributes: Record<string, AttributeType>,
207+
defaultValue: boolean,
208+
): IAssignmentDetails<boolean> {
209+
EppoJSClient.getAssignmentInitializationCheck();
210+
return super.getBooleanAssignmentDetails(flagKey, subjectKey, subjectAttributes, defaultValue);
211+
}
212+
191213
public getIntegerAssignment(
192214
flagKey: string,
193215
subjectKey: string,
@@ -198,6 +220,16 @@ export class EppoJSClient extends EppoClient {
198220
return super.getIntegerAssignment(flagKey, subjectKey, subjectAttributes, defaultValue);
199221
}
200222

223+
public getIntegerAssignmentDetails(
224+
flagKey: string,
225+
subjectKey: string,
226+
subjectAttributes: Record<string, AttributeType>,
227+
defaultValue: number,
228+
): IAssignmentDetails<number> {
229+
EppoJSClient.getAssignmentInitializationCheck();
230+
return super.getIntegerAssignmentDetails(flagKey, subjectKey, subjectAttributes, defaultValue);
231+
}
232+
201233
public getNumericAssignment(
202234
flagKey: string,
203235
subjectKey: string,
@@ -208,6 +240,16 @@ export class EppoJSClient extends EppoClient {
208240
return super.getNumericAssignment(flagKey, subjectKey, subjectAttributes, defaultValue);
209241
}
210242

243+
public getNumericAssignmentDetails(
244+
flagKey: string,
245+
subjectKey: string,
246+
subjectAttributes: Record<string, AttributeType>,
247+
defaultValue: number,
248+
): IAssignmentDetails<number> {
249+
EppoJSClient.getAssignmentInitializationCheck();
250+
return super.getNumericAssignmentDetails(flagKey, subjectKey, subjectAttributes, defaultValue);
251+
}
252+
211253
public getJSONAssignment(
212254
flagKey: string,
213255
subjectKey: string,
@@ -218,6 +260,44 @@ export class EppoJSClient extends EppoClient {
218260
return super.getJSONAssignment(flagKey, subjectKey, subjectAttributes, defaultValue);
219261
}
220262

263+
public getJSONAssignmentDetails(
264+
flagKey: string,
265+
subjectKey: string,
266+
subjectAttributes: Record<string, AttributeType>,
267+
defaultValue: object,
268+
): IAssignmentDetails<object> {
269+
EppoJSClient.getAssignmentInitializationCheck();
270+
return super.getJSONAssignmentDetails(flagKey, subjectKey, subjectAttributes, defaultValue);
271+
}
272+
273+
public getBanditAction(
274+
flagKey: string,
275+
subjectKey: string,
276+
subjectAttributes: BanditSubjectAttributes,
277+
actions: BanditActions,
278+
defaultValue: string,
279+
): Omit<IAssignmentDetails<string>, 'evaluationDetails'> {
280+
EppoJSClient.getAssignmentInitializationCheck();
281+
return super.getBanditAction(flagKey, subjectKey, subjectAttributes, actions, defaultValue);
282+
}
283+
284+
public getBanditActionDetails(
285+
flagKey: string,
286+
subjectKey: string,
287+
subjectAttributes: BanditSubjectAttributes,
288+
actions: BanditActions,
289+
defaultValue: string,
290+
): IAssignmentDetails<string> {
291+
EppoJSClient.getAssignmentInitializationCheck();
292+
return super.getBanditActionDetails(
293+
flagKey,
294+
subjectKey,
295+
subjectAttributes,
296+
actions,
297+
defaultValue,
298+
);
299+
}
300+
221301
private static getAssignmentInitializationCheck() {
222302
if (!EppoJSClient.initialized) {
223303
applicationLogger.warn('Eppo SDK assignment requested before init() completed');
@@ -242,7 +322,7 @@ export function buildStorageKeySuffix(apiKey: string): string {
242322
* @returns a singleton client instance
243323
* @public
244324
*/
245-
export function offlineInit(config: IClientConfigSync): IEppoClient {
325+
export function offlineInit(config: IClientConfigSync): EppoClient {
246326
const isObfuscated = config.isObfuscated ?? false;
247327
const throwOnFailedInitialization = config.throwOnFailedInitialization ?? true;
248328

@@ -297,7 +377,7 @@ export function offlineInit(config: IClientConfigSync): IEppoClient {
297377
* @param config - client configuration
298378
* @public
299379
*/
300-
export async function init(config: IClientConfig): Promise<IEppoClient> {
380+
export async function init(config: IClientConfig): Promise<EppoClient> {
301381
validation.validateNotBlank(config.apiKey, 'API key required');
302382
let initializationError: Error | undefined;
303383
const instance = EppoJSClient.instance;
@@ -441,7 +521,7 @@ export async function init(config: IClientConfig): Promise<IEppoClient> {
441521
* @returns a singleton client instance
442522
* @public
443523
*/
444-
export function getInstance(): IEppoClient {
524+
export function getInstance(): EppoClient {
445525
return EppoJSClient.instance;
446526
}
447527

src/isolatable-hybrid.store.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ export class IsolatableHybridConfigurationStore<T> extends HybridConfigurationSt
1919
}
2020

2121
/** @Override */
22-
public async setEntries(entries: Record<string, T>): Promise<void> {
22+
public async setEntries(entries: Record<string, T>): Promise<boolean> {
2323
if (this.persistentStore) {
2424
// always update persistent store
2525
await this.persistentStore.setEntries(entries);
@@ -41,5 +41,6 @@ export class IsolatableHybridConfigurationStore<T> extends HybridConfigurationSt
4141
if (updateServingStore) {
4242
this.servingStore.setEntries(entries);
4343
}
44+
return updateServingStore;
4445
}
4546
}

yarn.lock

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -380,10 +380,10 @@
380380
resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz#1d572bfbbe14b7704e0ba0f39b74815b84870d70"
381381
integrity sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==
382382

383-
"@eppo/js-client-sdk-common@3.5.0":
384-
version "3.5.0"
385-
resolved "https://registry.yarnpkg.com/@eppo/js-client-sdk-common/-/js-client-sdk-common-3.5.0.tgz#456616067a7044707828eea596cf6915d9c21c71"
386-
integrity sha512-uCzPXRq7Z7Ir8a9XDz0YU3TP5F1vKYtKqXSjRjqViDSBBfbdTkHBNh1zeA3hEdpppjQKZHExbV1Stl0rmNWznw==
383+
"@eppo/js-client-sdk-common@4.0.0":
384+
version "4.0.0"
385+
resolved "https://registry.yarnpkg.com/@eppo/js-client-sdk-common/-/js-client-sdk-common-4.0.0.tgz#39dea02745b641915fa4e925d75a12ca5b1e9503"
386+
integrity sha512-aMru8KESyNJDU/fm5jVENUhpa1jB88FUncT/xnjgiWPuTLLrpi10Qshoj7Lloi8IjlwFSFMjDjtpuQoLKPpQXA==
387387
dependencies:
388388
js-base64 "^3.7.7"
389389
md5 "^2.3.0"

0 commit comments

Comments
 (0)