From a38ef14489d595eeeda85792c0ccf7d8f7ae0491 Mon Sep 17 00:00:00 2001 From: Nick Pleis Date: Tue, 28 Mar 2023 21:23:16 -0700 Subject: [PATCH] Made configuration store async --- .eslintcache | 1 - .gitignore | 1 + package.json | 2 +- src/client/eppo-client.spec.ts | 95 +++++++++++++++-------- src/client/eppo-client.ts | 8 +- src/configuration-store.ts | 4 +- src/experiment-configuration-requestor.ts | 2 +- 7 files changed, 71 insertions(+), 42 deletions(-) delete mode 100644 .eslintcache diff --git a/.eslintcache b/.eslintcache deleted file mode 100644 index 7f41b869..00000000 --- a/.eslintcache +++ /dev/null @@ -1 +0,0 @@ -[{"/Users/nick/projects/js-client-sdk-common/src/assignment-logger.ts":"1","/Users/nick/projects/js-client-sdk-common/src/client/eppo-client.spec.ts":"2","/Users/nick/projects/js-client-sdk-common/src/client/eppo-client.ts":"3","/Users/nick/projects/js-client-sdk-common/src/configuration-store.ts":"4","/Users/nick/projects/js-client-sdk-common/src/constants.ts":"5","/Users/nick/projects/js-client-sdk-common/src/dto/allocation-dto.ts":"6","/Users/nick/projects/js-client-sdk-common/src/dto/experiment-configuration-dto.ts":"7","/Users/nick/projects/js-client-sdk-common/src/dto/rule-dto.ts":"8","/Users/nick/projects/js-client-sdk-common/src/dto/variation-dto.ts":"9","/Users/nick/projects/js-client-sdk-common/src/experiment-configuration-requestor.ts":"10","/Users/nick/projects/js-client-sdk-common/src/http-client.ts":"11","/Users/nick/projects/js-client-sdk-common/src/index.spec.ts":"12","/Users/nick/projects/js-client-sdk-common/src/index.ts":"13","/Users/nick/projects/js-client-sdk-common/src/rule_evaluator.spec.ts":"14","/Users/nick/projects/js-client-sdk-common/src/rule_evaluator.ts":"15","/Users/nick/projects/js-client-sdk-common/src/shard.ts":"16","/Users/nick/projects/js-client-sdk-common/src/validation.ts":"17","/Users/nick/projects/js-client-sdk-common/test/testHelpers.ts":"18"},{"size":893,"mtime":1679282040448,"results":"19","hashOfConfig":"20"},{"size":8936,"mtime":1680038760666,"results":"21","hashOfConfig":"20"},{"size":5310,"mtime":1680038659507,"results":"22","hashOfConfig":"20"},{"size":118,"mtime":1680038668737,"results":"23","hashOfConfig":"20"},{"size":346,"mtime":1679282040449,"results":"24","hashOfConfig":"20"},{"size":135,"mtime":1679282040449,"results":"25","hashOfConfig":"20"},{"size":291,"mtime":1679282040449,"results":"26","hashOfConfig":"20"},{"size":396,"mtime":1679282040449,"results":"27","hashOfConfig":"20"},{"size":220,"mtime":1679282040449,"results":"28","hashOfConfig":"20"},{"size":797,"mtime":1680038687033,"results":"29","hashOfConfig":"20"},{"size":854,"mtime":1679286586855,"results":"30","hashOfConfig":"20"},{"size":88,"mtime":1679282040450,"results":"31","hashOfConfig":"20"},{"size":472,"mtime":1680038705256,"results":"32","hashOfConfig":"20"},{"size":5392,"mtime":1679282040450,"results":"33","hashOfConfig":"20"},{"size":2485,"mtime":1680033855312,"results":"34","hashOfConfig":"20"},{"size":579,"mtime":1679282040451,"results":"35","hashOfConfig":"20"},{"size":225,"mtime":1679282040451,"results":"36","hashOfConfig":"20"},{"size":1235,"mtime":1680032856679,"results":"37","hashOfConfig":"20"},{"filePath":"38","messages":"39","suppressedMessages":"40","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},"109tjyf",{"filePath":"41","messages":"42","suppressedMessages":"43","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"44","messages":"45","suppressedMessages":"46","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"47","messages":"48","suppressedMessages":"49","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"50","messages":"51","suppressedMessages":"52","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"53","messages":"54","suppressedMessages":"55","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"56","messages":"57","suppressedMessages":"58","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"59","messages":"60","suppressedMessages":"61","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"62","messages":"63","suppressedMessages":"64","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"65","messages":"66","suppressedMessages":"67","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"68","messages":"69","suppressedMessages":"70","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"71","messages":"72","suppressedMessages":"73","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"74","messages":"75","suppressedMessages":"76","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"77","messages":"78","suppressedMessages":"79","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"80","messages":"81","suppressedMessages":"82","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"83","messages":"84","suppressedMessages":"85","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"86","messages":"87","suppressedMessages":"88","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"89","messages":"90","suppressedMessages":"91","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},"/Users/nick/projects/js-client-sdk-common/src/assignment-logger.ts",[],["92"],"/Users/nick/projects/js-client-sdk-common/src/client/eppo-client.spec.ts",[],["93","94"],"/Users/nick/projects/js-client-sdk-common/src/client/eppo-client.ts",[],["95","96"],"/Users/nick/projects/js-client-sdk-common/src/configuration-store.ts",[],[],"/Users/nick/projects/js-client-sdk-common/src/constants.ts",[],[],"/Users/nick/projects/js-client-sdk-common/src/dto/allocation-dto.ts",[],[],"/Users/nick/projects/js-client-sdk-common/src/dto/experiment-configuration-dto.ts",[],[],"/Users/nick/projects/js-client-sdk-common/src/dto/rule-dto.ts",[],["97"],"/Users/nick/projects/js-client-sdk-common/src/dto/variation-dto.ts",[],["98"],"/Users/nick/projects/js-client-sdk-common/src/experiment-configuration-requestor.ts",[],[],"/Users/nick/projects/js-client-sdk-common/src/http-client.ts",[],["99"],"/Users/nick/projects/js-client-sdk-common/src/index.spec.ts",[],[],"/Users/nick/projects/js-client-sdk-common/src/index.ts",[],[],"/Users/nick/projects/js-client-sdk-common/src/rule_evaluator.spec.ts",[],[],"/Users/nick/projects/js-client-sdk-common/src/rule_evaluator.ts",[],["100","101","102","103","104","105","106","107"],"/Users/nick/projects/js-client-sdk-common/src/shard.ts",[],[],"/Users/nick/projects/js-client-sdk-common/src/validation.ts",[],[],"/Users/nick/projects/js-client-sdk-common/test/testHelpers.ts",[],["108"],{"ruleId":"109","severity":1,"message":"110","line":27,"column":37,"nodeType":"111","messageId":"112","endLine":27,"endColumn":40,"suggestions":"113","suppressions":"114"},{"ruleId":"115","severity":2,"message":"116","line":23,"column":21,"nodeType":"117","messageId":"118","endLine":23,"endColumn":50,"suppressions":"119"},{"ruleId":"109","severity":1,"message":"110","line":291,"column":41,"nodeType":"111","messageId":"112","endLine":291,"endColumn":44,"suggestions":"120","suppressions":"121"},{"ruleId":"109","severity":1,"message":"110","line":31,"column":40,"nodeType":"111","messageId":"112","endLine":31,"endColumn":43,"suggestions":"122","suppressions":"123"},{"ruleId":"109","severity":1,"message":"110","line":98,"column":39,"nodeType":"111","messageId":"112","endLine":98,"endColumn":42,"suggestions":"124","suppressions":"125"},{"ruleId":"109","severity":1,"message":"110","line":15,"column":10,"nodeType":"111","messageId":"112","endLine":15,"endColumn":13,"suggestions":"126","suppressions":"127"},{"ruleId":"109","severity":1,"message":"110","line":9,"column":10,"nodeType":"111","messageId":"112","endLine":9,"endColumn":13,"suggestions":"128","suppressions":"129"},{"ruleId":"109","severity":1,"message":"110","line":30,"column":34,"nodeType":"111","messageId":"112","endLine":30,"endColumn":37,"suggestions":"130","suppressions":"131"},{"ruleId":"109","severity":1,"message":"110","line":4,"column":68,"nodeType":"111","messageId":"112","endLine":4,"endColumn":71,"suggestions":"132","suppressions":"133"},{"ruleId":"109","severity":1,"message":"110","line":13,"column":56,"nodeType":"111","messageId":"112","endLine":13,"endColumn":59,"suggestions":"134","suppressions":"135"},{"ruleId":"109","severity":1,"message":"110","line":19,"column":37,"nodeType":"111","messageId":"112","endLine":19,"endColumn":40,"suggestions":"136","suppressions":"137"},{"ruleId":"109","severity":1,"message":"110","line":25,"column":62,"nodeType":"111","messageId":"112","endLine":25,"endColumn":65,"suggestions":"138","suppressions":"139"},{"ruleId":"109","severity":1,"message":"110","line":48,"column":34,"nodeType":"111","messageId":"112","endLine":48,"endColumn":37,"suggestions":"140","suppressions":"141"},{"ruleId":"109","severity":1,"message":"110","line":52,"column":37,"nodeType":"111","messageId":"112","endLine":52,"endColumn":40,"suggestions":"142","suppressions":"143"},{"ruleId":"109","severity":1,"message":"110","line":61,"column":19,"nodeType":"111","messageId":"112","endLine":61,"endColumn":22,"suggestions":"144","suppressions":"145"},{"ruleId":"109","severity":1,"message":"110","line":62,"column":19,"nodeType":"111","messageId":"112","endLine":62,"endColumn":22,"suggestions":"146","suppressions":"147"},{"ruleId":"109","severity":1,"message":"110","line":16,"column":83,"nodeType":"111","messageId":"112","endLine":16,"endColumn":86,"suggestions":"148","suppressions":"149"},"@typescript-eslint/no-explicit-any","Unexpected any. Specify a different type.","TSAnyKeyword","unexpectedAny",["150","151"],["152"],"@typescript-eslint/no-var-requires","Require statement not part of import statement.","CallExpression","noVarReqs",["153"],["154","155"],["156"],["157","158"],["159"],["160","161"],["162"],["163","164"],["165"],["166","167"],["168"],["169","170"],["171"],["172","173"],["174"],["175","176"],["177"],["178","179"],["180"],["181","182"],["183"],["184","185"],["186"],["187","188"],["189"],["190","191"],["192"],["193","194"],["195"],["196","197"],["198"],{"messageId":"199","fix":"200","desc":"201"},{"messageId":"202","fix":"203","desc":"204"},{"kind":"205","justification":"206"},{"kind":"205","justification":"206"},{"messageId":"199","fix":"207","desc":"201"},{"messageId":"202","fix":"208","desc":"204"},{"kind":"205","justification":"206"},{"messageId":"199","fix":"209","desc":"201"},{"messageId":"202","fix":"210","desc":"204"},{"kind":"205","justification":"206"},{"messageId":"199","fix":"211","desc":"201"},{"messageId":"202","fix":"212","desc":"204"},{"kind":"205","justification":"206"},{"messageId":"199","fix":"213","desc":"201"},{"messageId":"202","fix":"214","desc":"204"},{"kind":"205","justification":"206"},{"messageId":"199","fix":"215","desc":"201"},{"messageId":"202","fix":"216","desc":"204"},{"kind":"205","justification":"206"},{"messageId":"199","fix":"217","desc":"201"},{"messageId":"202","fix":"218","desc":"204"},{"kind":"205","justification":"206"},{"messageId":"199","fix":"219","desc":"201"},{"messageId":"202","fix":"220","desc":"204"},{"kind":"205","justification":"206"},{"messageId":"199","fix":"221","desc":"201"},{"messageId":"202","fix":"222","desc":"204"},{"kind":"205","justification":"206"},{"messageId":"199","fix":"223","desc":"201"},{"messageId":"202","fix":"224","desc":"204"},{"kind":"205","justification":"206"},{"messageId":"199","fix":"225","desc":"201"},{"messageId":"202","fix":"226","desc":"204"},{"kind":"205","justification":"206"},{"messageId":"199","fix":"227","desc":"201"},{"messageId":"202","fix":"228","desc":"204"},{"kind":"205","justification":"206"},{"messageId":"199","fix":"229","desc":"201"},{"messageId":"202","fix":"230","desc":"204"},{"kind":"205","justification":"206"},{"messageId":"199","fix":"231","desc":"201"},{"messageId":"202","fix":"232","desc":"204"},{"kind":"205","justification":"206"},{"messageId":"199","fix":"233","desc":"201"},{"messageId":"202","fix":"234","desc":"204"},{"kind":"205","justification":"206"},{"messageId":"199","fix":"235","desc":"201"},{"messageId":"202","fix":"236","desc":"204"},{"kind":"205","justification":"206"},"suggestUnknown",{"range":"237","text":"238"},"Use `unknown` instead, this will force you to explicitly, and safely assert the type is correct.","suggestNever",{"range":"237","text":"239"},"Use `never` instead, this is useful when instantiating generic type parameters that you don't need to know the type of.","directive","",{"range":"240","text":"238"},{"range":"240","text":"239"},{"range":"241","text":"238"},{"range":"241","text":"239"},{"range":"242","text":"238"},{"range":"242","text":"239"},{"range":"243","text":"238"},{"range":"243","text":"239"},{"range":"244","text":"238"},{"range":"244","text":"239"},{"range":"245","text":"238"},{"range":"245","text":"239"},{"range":"246","text":"238"},{"range":"246","text":"239"},{"range":"247","text":"238"},{"range":"247","text":"239"},{"range":"248","text":"238"},{"range":"248","text":"239"},{"range":"249","text":"238"},{"range":"249","text":"239"},{"range":"250","text":"238"},{"range":"250","text":"239"},{"range":"251","text":"238"},{"range":"251","text":"239"},{"range":"252","text":"238"},{"range":"252","text":"239"},{"range":"253","text":"238"},{"range":"253","text":"239"},{"range":"254","text":"238"},{"range":"254","text":"239"},[521,524],"unknown","never",[8712,8715],[1305,1308],[3802,3805],[309,312],[186,189],[742,745],[189,192],[400,403],[641,644],[842,845],[1732,1735],[1892,1895],[2257,2260],[2280,2283],[644,647]] \ No newline at end of file diff --git a/.gitignore b/.gitignore index dca583ad..95145adf 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,7 @@ logs/ temp .env +.eslintcache yarn-error.log test/data diff --git a/package.json b/package.json index 588019f4..8f1f1848 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@eppo/js-client-sdk-common", - "version": "1.0.0", + "version": "1.0.1", "description": "Eppo SDK for client-side JavaScript applications (base for both web and react native)", "main": "dist/index.js", "files": [ diff --git a/src/client/eppo-client.spec.ts b/src/client/eppo-client.spec.ts index f45e5007..c228ca25 100644 --- a/src/client/eppo-client.spec.ts +++ b/src/client/eppo-client.spec.ts @@ -25,12 +25,12 @@ const packageJson = require('../../package.json'); class TestConfigurationStore implements IConfigurationStore { private store = {}; - public get(key: string): T { + public async get(key: string): Promise { const rval = this.store[key]; return rval ? JSON.parse(rval) : null; } - public setEntries(entries: Record) { + public async setEntries(entries: Record): Promise { Object.entries(entries).forEach(([key, val]) => { this.store[key] = JSON.stringify(val); }); @@ -128,11 +128,11 @@ describe('EppoClient E2E test', () => { storage.setEntries({ [experimentName]: mockExperimentConfig }); }); - it('Invokes logger for queued events', () => { + it('Invokes logger for queued events', async () => { const mockLogger = td.object(); const client = new EppoClient(storage); - client.getAssignment('subject-to-be-logged', experimentName); + await client.getAssignment('subject-to-be-logged', experimentName); client.setLogger(mockLogger); expect(td.explain(mockLogger.logAssignment).callCount).toEqual(1); @@ -141,12 +141,12 @@ describe('EppoClient E2E test', () => { ); }); - it('Does not log same queued event twice', () => { + it('Does not log same queued event twice', async () => { const mockLogger = td.object(); const client = new EppoClient(storage); - client.getAssignment('subject-to-be-logged', experimentName); + await client.getAssignment('subject-to-be-logged', experimentName); client.setLogger(mockLogger); expect(td.explain(mockLogger.logAssignment).callCount).toEqual(1); @@ -154,12 +154,12 @@ describe('EppoClient E2E test', () => { expect(td.explain(mockLogger.logAssignment).callCount).toEqual(1); }); - it('Does not invoke logger for events that exceed queue size', () => { + it('Does not invoke logger for events that exceed queue size', async () => { const mockLogger = td.object(); const client = new EppoClient(storage); for (let i = 0; i < MAX_EVENT_QUEUE_SIZE + 100; i++) { - client.getAssignment(`subject-to-be-logged-${i}`, experimentName); + await client.getAssignment(`subject-to-be-logged-${i}`, experimentName); } client.setLogger(mockLogger); expect(td.explain(mockLogger.logAssignment).callCount).toEqual(MAX_EVENT_QUEUE_SIZE); @@ -176,21 +176,31 @@ describe('EppoClient E2E test', () => { expectedAssignments, }: IAssignmentTestCase) => { `---- Test Case for ${experiment} Experiment ----`; - const assignments = subjectsWithAttributes - ? getAssignmentsWithSubjectAttributes(subjectsWithAttributes, experiment) - : getAssignments(subjects, experiment); + + let assignments = null; + if (subjectsWithAttributes) { + assignments = await getAssignmentsWithSubjectAttributes( + subjectsWithAttributes, + experiment, + ); + } else { + assignments = await getAssignments(subjects, experiment); + } + expect(assignments).toEqual(expectedAssignments); }, ); }); - it('returns null if getAssignment was called for the subject before any RAC was loaded', () => { - expect(globalClient.getAssignment(sessionOverrideSubject, sessionOverrideExperiment)).toEqual( - null, + it('returns null if getAssignment was called for the subject before any RAC was loaded', async () => { + const assigment = await globalClient.getAssignment( + sessionOverrideSubject, + sessionOverrideExperiment, ); + expect(assigment).toEqual(null); }); - it('returns subject from overrides when enabled is true', () => { + it('returns subject from overrides when enabled is true', async () => { window.localStorage.setItem( experimentName, JSON.stringify({ @@ -201,11 +211,11 @@ describe('EppoClient E2E test', () => { }), ); const client = new EppoClient(storage); - const assignment = client.getAssignment('subject-10', experimentName); + const assignment = await client.getAssignment('subject-10', experimentName); expect(assignment).toEqual('control'); }); - it('returns subject from overrides when enabled is false', () => { + it('returns subject from overrides when enabled is false', async () => { const entry = { ...mockExperimentConfig, enabled: false, @@ -217,11 +227,11 @@ describe('EppoClient E2E test', () => { storage.setEntries({ [experimentName]: entry }); const client = new EppoClient(storage); - const assignment = client.getAssignment('subject-10', experimentName); + const assignment = await client.getAssignment('subject-10', experimentName); expect(assignment).toEqual('control'); }); - it('logs variation assignment', () => { + it('logs variation assignment', async () => { const mockLogger = td.object(); storage.setEntries({ [experimentName]: mockExperimentConfig }); @@ -229,14 +239,14 @@ describe('EppoClient E2E test', () => { client.setLogger(mockLogger); const subjectAttributes = { foo: 3 }; - const assignment = client.getAssignment('subject-10', experimentName, subjectAttributes); + const assignment = await client.getAssignment('subject-10', experimentName, subjectAttributes); expect(assignment).toEqual('control'); expect(td.explain(mockLogger.logAssignment).callCount).toEqual(1); expect(td.explain(mockLogger.logAssignment).calls[0].args[0].subject).toEqual('subject-10'); }); - it('handles logging exception', () => { + it('handles logging exception', async () => { const mockLogger = td.object(); td.when(mockLogger.logAssignment(td.matchers.anything())).thenThrow(new Error('logging error')); @@ -245,12 +255,12 @@ describe('EppoClient E2E test', () => { client.setLogger(mockLogger); const subjectAttributes = { foo: 3 }; - const assignment = client.getAssignment('subject-10', experimentName, subjectAttributes); + const assignment = await client.getAssignment('subject-10', experimentName, subjectAttributes); expect(assignment).toEqual('control'); }); - it('only returns variation if subject matches rules', () => { + it('only returns variation if subject matches rules', async () => { const entry = { ...mockExperimentConfig, rules: [ @@ -270,21 +280,27 @@ describe('EppoClient E2E test', () => { storage.setEntries({ [experimentName]: entry }); const client = new EppoClient(storage); - let assignment = client.getAssignment('subject-10', experimentName, { appVersion: 9 }); + let assignment = await client.getAssignment('subject-10', experimentName, { appVersion: 9 }); expect(assignment).toEqual(null); - assignment = client.getAssignment('subject-10', experimentName); + assignment = await client.getAssignment('subject-10', experimentName); expect(assignment).toEqual(null); - assignment = client.getAssignment('subject-10', experimentName, { appVersion: 11 }); + assignment = await client.getAssignment('subject-10', experimentName, { appVersion: 11 }); expect(assignment).toEqual('control'); }); - function getAssignments(subjects: string[], experiment: string): string[] { - return subjects.map((subjectKey) => { - return globalClient.getAssignment(subjectKey, experiment); - }); + async function getAssignments(subjects: string[], experiment: string): string[] { + const rval: string[] = []; + + for (const index in subjects) { + const subjectKey = subjects[index]; + const assignment = await globalClient.getAssignment(subjectKey, experiment); + rval.push(assignment); + } + + return rval; } - function getAssignmentsWithSubjectAttributes( + async function getAssignmentsWithSubjectAttributes( subjectsWithAttributes: { subjectKey: string; // eslint-disable-next-line @typescript-eslint/no-explicit-any @@ -292,8 +308,19 @@ describe('EppoClient E2E test', () => { }[], experiment: string, ): string[] { - return subjectsWithAttributes.map((subject) => { - return globalClient.getAssignment(subject.subjectKey, experiment, subject.subjectAttributes); - }); + const rval: string[] = []; + + for (const index in subjectsWithAttributes) { + const subject = subjectsWithAttributes[index]; + const assignment = await globalClient.getAssignment( + subject.subjectKey, + experiment, + subject.subjectAttributes, + ); + + rval.push(assignment); + } + + return rval; } }); diff --git a/src/client/eppo-client.ts b/src/client/eppo-client.ts index f47e10e4..d83dbdf5 100644 --- a/src/client/eppo-client.ts +++ b/src/client/eppo-client.ts @@ -29,7 +29,7 @@ export interface IEppoClient { experimentKey: string, // eslint-disable-next-line @typescript-eslint/no-explicit-any subjectAttributes?: Record, - ): string; + ): Promise; } export default class EppoClient implements IEppoClient { @@ -38,11 +38,13 @@ export default class EppoClient implements IEppoClient { constructor(private configurationStore: IConfigurationStore) {} - getAssignment(subjectKey: string, experimentKey: string, subjectAttributes = {}): string { + async getAssignment(subjectKey: string, experimentKey: string, subjectAttributes = {}): string { validateNotBlank(subjectKey, 'Invalid argument: subjectKey cannot be blank'); validateNotBlank(experimentKey, 'Invalid argument: experimentKey cannot be blank'); - const experimentConfig = this.configurationStore.get(experimentKey); + const experimentConfig = await this.configurationStore.get( + experimentKey, + ); const allowListOverride = this.getSubjectVariationOverride(subjectKey, experimentConfig); if (allowListOverride) return allowListOverride; diff --git a/src/configuration-store.ts b/src/configuration-store.ts index 90e14804..52ad9d2e 100644 --- a/src/configuration-store.ts +++ b/src/configuration-store.ts @@ -1,4 +1,4 @@ export interface IConfigurationStore { - get(key: string): T; - setEntries(entries: Record): void; + get(key: string): Promise; + setEntries(entries: Record): Promise; } diff --git a/src/experiment-configuration-requestor.ts b/src/experiment-configuration-requestor.ts index f9cdb7e2..2b8eebaf 100644 --- a/src/experiment-configuration-requestor.ts +++ b/src/experiment-configuration-requestor.ts @@ -13,7 +13,7 @@ export default class ExperimentConfigurationRequestor { async fetchAndStoreConfigurations(): Promise> { const responseData = await this.httpClient.get(RAC_ENDPOINT); - this.configurationStore.setEntries(responseData.flags); + await this.configurationStore.setEntries(responseData.flags); return responseData.flags; } }