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
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@eppo/js-client-sdk-common",
"version": "2.1.0",
"version": "2.1.1",
"description": "Eppo SDK for client-side JavaScript applications (base for both web and react native)",
"main": "dist/index.js",
"files": [
Expand Down
15 changes: 14 additions & 1 deletion src/client/eppo-client.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1160,7 +1160,7 @@ describe('Eppo Client constructed with configuration request parameters', () =>
mock.teardown();
});

it('Fetches initial configuration', async () => {
it('Fetches initial configuration with parameters in constructor', async () => {
client = new EppoClient(storage, requestConfiguration);
client.setIsGracefulFailureMode(false);
// no configuration loaded
Expand All @@ -1172,6 +1172,19 @@ describe('Eppo Client constructed with configuration request parameters', () =>
expect(variation).toBe('green');
});

it('Fetches initial configuration with parameters provided later', async () => {
client = new EppoClient(storage);
client.setIsGracefulFailureMode(false);
client.setConfigurationRequestParameters(requestConfiguration);
// no configuration loaded
let variation = client.getAssignment(subjectForGreenVariation, flagKey);
expect(variation).toBeNull();
// have client fetch configurations
await client.fetchFlagConfigurations();
variation = client.getAssignment(subjectForGreenVariation, flagKey);
expect(variation).toBe('green');
Comment on lines +1183 to +1185
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

very nice

});

it.each([
{ pollAfterSuccessfulInitialization: false },
{ pollAfterSuccessfulInitialization: true },
Expand Down
41 changes: 26 additions & 15 deletions src/client/eppo-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,10 @@ export interface IEppoClient {

useCustomAssignmentCache(cache: AssignmentCache<Cacheable>): void;

setConfigurationRequestParameters(
configurationRequestParameters: ExperimentConfigurationRequestParameters,
): void;

fetchFlagConfigurations(): void;

stopPolling(): void;
Expand All @@ -141,21 +145,27 @@ export default class EppoClient implements IEppoClient {
private isGracefulFailureMode = true;
private assignmentCache: AssignmentCache<Cacheable> | undefined;
private configurationStore: IConfigurationStore;
private configurationRequestConfig: ExperimentConfigurationRequestParameters | undefined;
private configurationRequestParameters: ExperimentConfigurationRequestParameters | undefined;
private requestPoller: IPoller | undefined;

constructor(
configurationStore: IConfigurationStore,
configurationRequestConfig?: ExperimentConfigurationRequestParameters,
configurationRequestParameters?: ExperimentConfigurationRequestParameters,
) {
this.configurationStore = configurationStore;
this.configurationRequestConfig = configurationRequestConfig;
this.configurationRequestParameters = configurationRequestParameters;
}

public setConfigurationRequestParameters(
configurationRequestParameters: ExperimentConfigurationRequestParameters,
) {
this.configurationRequestParameters = configurationRequestParameters;
}

public async fetchFlagConfigurations() {
if (!this.configurationRequestConfig) {
if (!this.configurationRequestParameters) {
throw new Error(
'Eppo SDK unable to fetch flag configurations without a request configuration',
'Eppo SDK unable to fetch flag configurations without configuration request parameters',
);
}

Expand All @@ -165,13 +175,13 @@ export default class EppoClient implements IEppoClient {
}

const axiosInstance = axios.create({
baseURL: this.configurationRequestConfig.baseUrl || DEFAULT_BASE_URL,
timeout: this.configurationRequestConfig.requestTimeoutMs || DEFAULT_REQUEST_TIMEOUT_MS,
baseURL: this.configurationRequestParameters.baseUrl || DEFAULT_BASE_URL,
timeout: this.configurationRequestParameters.requestTimeoutMs || DEFAULT_REQUEST_TIMEOUT_MS,
});
const httpClient = new HttpClient(axiosInstance, {
apiKey: this.configurationRequestConfig.apiKey,
sdkName: this.configurationRequestConfig.sdkName,
sdkVersion: this.configurationRequestConfig.sdkVersion,
apiKey: this.configurationRequestParameters.apiKey,
sdkName: this.configurationRequestParameters.sdkName,
sdkVersion: this.configurationRequestParameters.sdkVersion,
});
const configurationRequestor = new ExperimentConfigurationRequestor(
this.configurationStore,
Expand All @@ -183,16 +193,17 @@ export default class EppoClient implements IEppoClient {
configurationRequestor.fetchAndStoreConfigurations.bind(configurationRequestor),
{
maxStartRetries:
this.configurationRequestConfig.numInitialRequestRetries ??
this.configurationRequestParameters.numInitialRequestRetries ??
DEFAULT_INITIAL_CONFIG_REQUEST_RETRIES,
maxPollRetries:
this.configurationRequestConfig.numPollRequestRetries ??
this.configurationRequestParameters.numPollRequestRetries ??
DEFAULT_POLL_CONFIG_REQUEST_RETRIES,
pollAfterSuccessfulStart:
this.configurationRequestConfig.pollAfterSuccessfulInitialization ?? false,
this.configurationRequestParameters.pollAfterSuccessfulInitialization ?? false,
pollAfterFailedStart:
this.configurationRequestConfig.pollAfterFailedInitialization ?? false,
errorOnFailedStart: this.configurationRequestConfig.throwOnFailedInitialization ?? false,
this.configurationRequestParameters.pollAfterFailedInitialization ?? false,
errorOnFailedStart:
this.configurationRequestParameters.throwOnFailedInitialization ?? false,
},
);

Expand Down