Skip to content

Commit 2c1cc7a

Browse files
authored
fix: Handle default flush interval for browser SDK. (#822)
The browser SDK was incorrectly handling its default flush interval configuration. There are two layers to defaults for the browser SDK. The first is defaults which differ from the base configuration defaults, second is defaults for browser specific configuration. The base defaults were being applied to the browser specific configuration, which meant those changes were being lost and instead the base default was being used instead. Fixes: SDK-1199
1 parent 2c09c3b commit 2c1cc7a

File tree

3 files changed

+40
-19
lines changed

3 files changed

+40
-19
lines changed

packages/sdk/browser/__tests__/options.test.ts

+22-7
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { jest } from '@jest/globals';
22

33
import { LDLogger } from '@launchdarkly/js-client-sdk-common';
44

5-
import validateOptions, { filterToBaseOptions } from '../src/options';
5+
import validateBrowserOptions, { filterToBaseOptionsWithDefaults } from '../src/options';
66

77
let logger: LDLogger;
88

@@ -16,7 +16,7 @@ beforeEach(() => {
1616
});
1717

1818
it('logs no warnings when all configuration is valid', () => {
19-
validateOptions(
19+
validateBrowserOptions(
2020
{
2121
fetchGoals: true,
2222
eventUrlTransformer: (url: string) => url,
@@ -31,7 +31,7 @@ it('logs no warnings when all configuration is valid', () => {
3131
});
3232

3333
it('warns for invalid configuration', () => {
34-
validateOptions(
34+
validateBrowserOptions(
3535
{
3636
// @ts-ignore
3737
fetchGoals: 'yes',
@@ -50,8 +50,8 @@ it('warns for invalid configuration', () => {
5050
);
5151
});
5252

53-
it('applies default options', () => {
54-
const opts = validateOptions({}, logger);
53+
it('applies default browser-specific options', () => {
54+
const opts = validateBrowserOptions({}, logger);
5555

5656
expect(opts.fetchGoals).toBe(true);
5757
expect(opts.eventUrlTransformer).toBeDefined();
@@ -69,9 +69,24 @@ it('filters to base options', () => {
6969
eventUrlTransformer: (url: string) => url,
7070
};
7171

72-
const baseOpts = filterToBaseOptions(opts);
72+
const baseOpts = filterToBaseOptionsWithDefaults(opts);
7373
expect(baseOpts.debug).toBe(false);
74-
expect(Object.keys(baseOpts).length).toEqual(1);
74+
expect(Object.keys(baseOpts).length).toEqual(2);
7575
expect(baseOpts).not.toHaveProperty('fetchGoals');
7676
expect(baseOpts).not.toHaveProperty('eventUrlTransformer');
77+
expect(baseOpts.flushInterval).toEqual(2);
78+
});
79+
80+
it('applies default overrides to common config flushInterval', () => {
81+
const opts = {};
82+
const result = filterToBaseOptionsWithDefaults(opts);
83+
expect(result.flushInterval).toEqual(2);
84+
});
85+
86+
it('does not override common config flushInterval if it is set', () => {
87+
const opts = {
88+
flushInterval: 15,
89+
};
90+
const result = filterToBaseOptionsWithDefaults(opts);
91+
expect(result.flushInterval).toEqual(15);
7792
});

packages/sdk/browser/src/BrowserClient.ts

+6-3
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import { BrowserIdentifyOptions as LDIdentifyOptions } from './BrowserIdentifyOp
2121
import { registerStateDetection } from './BrowserStateDetector';
2222
import GoalManager from './goals/GoalManager';
2323
import { Goal, isClick } from './goals/Goals';
24-
import validateOptions, { BrowserOptions, filterToBaseOptions } from './options';
24+
import validateBrowserOptions, { BrowserOptions, filterToBaseOptionsWithDefaults } from './options';
2525
import BrowserPlatform from './platform/BrowserPlatform';
2626

2727
/**
@@ -116,13 +116,16 @@ export class BrowserClient extends LDClientImpl implements LDClient {
116116
const baseUrl = options.baseUri ?? 'https://clientsdk.launchdarkly.com';
117117

118118
const platform = overridePlatform ?? new BrowserPlatform(logger);
119-
const validatedBrowserOptions = validateOptions(options, logger);
119+
// Only the browser-specific options are in validatedBrowserOptions.
120+
const validatedBrowserOptions = validateBrowserOptions(options, logger);
121+
// The base options are in baseOptionsWithDefaults.
122+
const baseOptionsWithDefaults = filterToBaseOptionsWithDefaults({ ...options, logger });
120123
const { eventUrlTransformer } = validatedBrowserOptions;
121124
super(
122125
clientSideId,
123126
autoEnvAttributes,
124127
platform,
125-
filterToBaseOptions({ ...options, logger }),
128+
baseOptionsWithDefaults,
126129
(
127130
flagManager: FlagManager,
128131
configuration: Configuration,

packages/sdk/browser/src/options.ts

+12-9
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,14 @@ const validators: { [Property in keyof BrowserOptions]: TypeValidator | undefine
7373
streaming: TypeValidators.Boolean,
7474
};
7575

76-
export function filterToBaseOptions(opts: BrowserOptions): LDOptionsBase {
77-
const baseOptions: LDOptionsBase = { ...opts };
76+
function withBrowserDefaults(opts: BrowserOptions): BrowserOptions {
77+
const output = { ...opts };
78+
output.flushInterval ??= DEFAULT_FLUSH_INTERVAL_SECONDS;
79+
return output;
80+
}
81+
82+
export function filterToBaseOptionsWithDefaults(opts: BrowserOptions): LDOptionsBase {
83+
const baseOptions: LDOptionsBase = withBrowserDefaults(opts);
7884

7985
// Remove any browser specific configuration keys so we don't get warnings from
8086
// the base implementation for unknown configuration.
@@ -84,14 +90,11 @@ export function filterToBaseOptions(opts: BrowserOptions): LDOptionsBase {
8490
return baseOptions;
8591
}
8692

87-
function applyBrowserDefaults(opts: BrowserOptions) {
88-
// eslint-disable-next-line no-param-reassign
89-
opts.flushInterval ??= DEFAULT_FLUSH_INTERVAL_SECONDS;
90-
}
91-
92-
export default function validateOptions(opts: BrowserOptions, logger: LDLogger): ValidatedOptions {
93+
export default function validateBrowserOptions(
94+
opts: BrowserOptions,
95+
logger: LDLogger,
96+
): ValidatedOptions {
9397
const output: ValidatedOptions = { ...optDefaults };
94-
applyBrowserDefaults(output);
9598

9699
Object.entries(validators).forEach((entry) => {
97100
const [key, validator] = entry as [keyof BrowserOptions, TypeValidator];

0 commit comments

Comments
 (0)