Skip to content

Commit

Permalink
Add sdk option to bypass window undefined checks (#234)
Browse files Browse the repository at this point in the history
* Add option to bypass window undefined check

* allow logger interval as well

* fix window check

* check that flush interval is setup

* bump v4.29.0
  • Loading branch information
tore-statsig authored Feb 17, 2023
1 parent 94a3378 commit 1aab3f3
Show file tree
Hide file tree
Showing 8 changed files with 112 additions and 55 deletions.
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "statsig-js",
"version": "4.28.1",
"version": "4.29.0",
"description": "Statsig JavaScript client SDK for single user environments.",
"main": "dist/index.js",
"types": "dist/index.d.ts",
Expand Down
4 changes: 2 additions & 2 deletions src/StatsigLogger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ export default class StatsigLogger {
this.flush(document.visibilityState !== 'visible');
});
}
if (typeof window === 'undefined' || window == null) {
if (!this.sdkInternal.getOptions().getIgnoreWindowUndefined() && (typeof window === 'undefined' || window == null)) {
// dont set the flush interval outside of client browser environments
return;
}
Expand Down Expand Up @@ -111,7 +111,7 @@ export default class StatsigLogger {
event.addStatsigMetadata('currentPage', parts[0]);
}
}
} catch (_e) {}
} catch (_e) { }

this.queue.push(event.toJsonObject());

Expand Down
9 changes: 5 additions & 4 deletions src/StatsigNetwork.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ export default class StatsigNetwork {
if (!this.sdkInternal.getOptions().getDisableNetworkKeepalive()) {
try {
this.canUseKeepalive = 'keepalive' in new Request('');
} catch (_e) {}
} catch (_e) { }
}
}

Expand Down Expand Up @@ -190,7 +190,7 @@ export default class StatsigNetwork {
}
const url = new URL(
this.sdkInternal.getOptions().getEventLoggingApi() +
StatsigEndpoint.LogEventBeacon,
StatsigEndpoint.LogEventBeacon,
);
url.searchParams.append('k', this.sdkInternal.getSDKKey());
payload.clientTime = Date.now() + '';
Expand Down Expand Up @@ -218,8 +218,8 @@ export default class StatsigNetwork {
return Promise.reject('fetch is not defined');
}

if (typeof window === 'undefined') {
// dont issue requests from the server
if (typeof window === 'undefined' && !this.sdkInternal.getOptions().getIgnoreWindowUndefined()) {
// by default, dont issue requests from the server
return Promise.reject('window is not defined');
}

Expand All @@ -246,6 +246,7 @@ export default class StatsigNetwork {
let shouldEncode =
endpointName === StatsigEndpoint.Initialize &&
StatsigRuntime.encodeInitializeCall &&
typeof window !== 'undefined' &&
typeof window?.btoa === 'function';

let postBody = JSON.stringify(body);
Expand Down
7 changes: 7 additions & 0 deletions src/StatsigSDKOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ export type StatsigOptions = {
initCompletionCallback?: InitCompletionCallback | null;
disableDiagnosticsLogging?: boolean;
logLevel?: LogLevel | null;
ignoreWindowUndefined?: boolean;
};

export enum LogLevel {
Expand Down Expand Up @@ -67,6 +68,7 @@ export default class StatsigSDKOptions {
private initCompletionCallback: InitCompletionCallback | null;
private disableDiagnosticsLogging: boolean;
private logLevel: LogLevel;
private ignoreWindowUndefined: boolean;

constructor(options?: StatsigOptions | null) {
if (options == null) {
Expand Down Expand Up @@ -113,6 +115,7 @@ export default class StatsigSDKOptions {
this.initCompletionCallback = options.initCompletionCallback ?? null;
this.disableDiagnosticsLogging = options.disableDiagnosticsLogging ?? false;
this.logLevel = options?.logLevel ?? LogLevel.NONE;
this.ignoreWindowUndefined = options?.ignoreWindowUndefined ?? false;
}

getApi(): string {
Expand Down Expand Up @@ -183,6 +186,10 @@ export default class StatsigSDKOptions {
return this.logLevel;
}

getIgnoreWindowUndefined(): boolean {
return this.ignoreWindowUndefined;
}

private normalizeNumberInput(
input: number | undefined,
bounds: BoundedNumberInput,
Expand Down
47 changes: 47 additions & 0 deletions src/__tests__/StatsigClientOnServer.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,51 @@ describe('Verify behavior of StatsigClient outside of browser environment', () =
await client.initializeAsync();
client.shutdown();
});

test('Client ignores window undefined if specified in options', async () => {
expect.assertions(8);

// @ts-ignore
global.fetch = jest.fn((url, params) => {
if (url.toString().includes('rgstr')) {
return Promise.resolve({ ok: true });
}
if (url.toString().includes('initialize')) {
return Promise.resolve({
ok: true,
text: () =>
Promise.resolve(
JSON.stringify(TestData),
),
});
}
});

// verify window is undefined
expect(typeof window).toBe('undefined');

const client = new StatsigClient(
'client-xyz',
{ email: '[email protected]' },
{ ignoreWindowUndefined: true },
);

await client.initializeAsync();
// flush interval is setup
// @ts-ignore
expect(client.getLogger().flushInterval).not.toBeNull();

// initialized from network (fetch mock)
expect(client.checkGate('test_gate')).toBe(false);
expect(client.checkGate('i_dont_exist')).toBe(false);
expect(client.checkGate('always_on_gate')).toBe(true);
expect(client.checkGate('on_for_statsig_email')).toBe(true);
expect(client.getConfig('test_config').get('number', 10)).toEqual(7);
expect(client.getConfig('test_config').getEvaluationDetails()).toEqual({
reason: EvaluationReason.Network,
time: expect.any(Number),
});

client.shutdown();
});
});
46 changes: 46 additions & 0 deletions src/__tests__/basic_initialize_response.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
{
"disableAutoEventLogging": true,
"gates": {
"AoZS0F06Ub+W2ONx+94rPTS7MRxuxa+GnXro5Q1uaGY=": true
},
"feature_gates": {
"AoZS0F06Ub+W2ONx+94rPTS7MRxuxa+GnXro5Q1uaGY=": {
"value": true,
"rule_id": "ruleID123",
"name": "AoZS0F06Ub+W2ONx+94rPTS7MRxuxa+GnXro5Q1uaGY=",
"secondary_exposures": [
{
"gate": "dependent_gate_1",
"gateValue": "true",
"ruleID": "rule_1"
},
{
"gate": "dependent_gate_2",
"gateValue": "false",
"ruleID": "default"
}
]
}
},
"dynamic_configs": {
"RMv0YJlLOBe7cY7HgZ3Jox34R0Wrk7jLv3DZyBETA7I=": {
"value": {
"bool": true,
"number": 2,
"string": "string",
"object": {
"key": "value",
"key2": 123
},
"boolStr1": "true",
"boolStr2": "FALSE",
"numberStr1": "3",
"numberStr2": "3.3",
"numberStr3": "3.3.3"
},
"rule_id": "ruleID"
}
},
"layer_configs": {},
"has_updates": true
}
48 changes: 2 additions & 46 deletions src/__tests__/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import Statsig from '..';
import LogEvent from '../LogEvent';
import StatsigClient from '../StatsigClient';
import { EvaluationReason } from '../StatsigStore';
import * as TestData from './basic_initialize_response.json';
let statsig: typeof Statsig;

export type StatsigInitializeResponse = {
Expand Down Expand Up @@ -38,52 +39,7 @@ describe('Verify behavior of top level index functions', () => {
ok: true,
text: () =>
Promise.resolve(
JSON.stringify({
disableAutoEventLogging: true,
gates: {
'AoZS0F06Ub+W2ONx+94rPTS7MRxuxa+GnXro5Q1uaGY=': true,
},
feature_gates: {
'AoZS0F06Ub+W2ONx+94rPTS7MRxuxa+GnXro5Q1uaGY=': {
value: true,
rule_id: 'ruleID123',
name: 'AoZS0F06Ub+W2ONx+94rPTS7MRxuxa+GnXro5Q1uaGY=',
secondary_exposures: [
{
gate: 'dependent_gate_1',
gateValue: 'true',
ruleID: 'rule_1',
},
{
gate: 'dependent_gate_2',
gateValue: 'false',
ruleID: 'default',
},
],
},
},
dynamic_configs: {
'RMv0YJlLOBe7cY7HgZ3Jox34R0Wrk7jLv3DZyBETA7I=': {
value: {
bool: true,
number: 2,
string: 'string',
object: {
key: 'value',
key2: 123,
},
boolStr1: 'true',
boolStr2: 'FALSE',
numberStr1: '3',
numberStr2: '3.3',
numberStr3: '3.3.3',
},
rule_id: 'ruleID',
},
},
layer_configs: {},
has_updates: true,
}),
JSON.stringify(TestData),
),
});
}
Expand Down

0 comments on commit 1aab3f3

Please sign in to comment.