Skip to content

Commit b5e6d99

Browse files
authored
[FSSDK-9032] enhancement: Add VUID instantiation to browser client promise dependencies (#825)
1 parent 4b5b7f4 commit b5e6d99

File tree

4 files changed

+89
-72
lines changed

4 files changed

+89
-72
lines changed

packages/optimizely-sdk/lib/optimizely/index.ts

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
***************************************************************************/
1616

1717
import { LoggerFacade, ErrorHandler } from '../modules/logging';
18-
import { sprintf, objectValues } from '../utils/fns';
18+
import { sprintf, objectValues, isBrowser } from '../utils/fns';
1919
import { NotificationCenter } from '../core/notification_center';
2020
import { EventProcessor } from '../modules/event_processor';
2121

@@ -69,6 +69,8 @@ import {
6969
ODP_USER_KEY,
7070
} from '../utils/enums';
7171

72+
import { BrowserOdpManager } from '../../lib/plugins/odp_manager/index.browser';
73+
7274
const MODULE_NAME = 'OPTIMIZELY';
7375

7476
const DEFAULT_ONREADY_TIMEOUT = 30000;
@@ -175,24 +177,20 @@ export default class Optimizely implements Client {
175177

176178
const eventProcessorStartedPromise = this.eventProcessor.start();
177179

178-
// TODO: Look into making VUID Initialization a dependent promise for Browser Contexts
179-
180-
// let dependentPromises: Promise<any>[] = [projectConfigManagerReadyPromise];
181-
182-
// if (isBrowserContext()) {
183-
// const odpManagerVuidInitializedPromise = (config.odpManager as BrowserOdpManager).initPromise;
184-
// if (odpManagerVuidInitializedPromise) {
185-
// dependentPromises.push(odpManagerVuidInitializedPromise);
186-
// }
187-
// }
188-
189-
// this.readyPromise = Promise.all(dependentPromises).then(promiseResults => {
190-
191-
this.readyPromise = Promise.all([
180+
const dependentPromises: Array<Promise<any> | void> = [
192181
projectConfigManagerReadyPromise,
193182
eventProcessorStartedPromise,
194-
// config.odpManager.initPromise,
195-
]).then(promiseResults => {
183+
];
184+
185+
// Adds VUID initialization promise as a dependency for Browser...
186+
if (isBrowser()) {
187+
const odpManagerVuidInitializedPromise = (config.odpManager as BrowserOdpManager).initPromise;
188+
if (odpManagerVuidInitializedPromise) {
189+
dependentPromises.push(odpManagerVuidInitializedPromise);
190+
}
191+
}
192+
193+
this.readyPromise = Promise.all(dependentPromises).then(promiseResults => {
196194
if (config.odpManager != null) {
197195
this.odpManager = config.odpManager;
198196
this.odpManager.eventManager?.start();
Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
import { OdpEvent } from "../../../core/odp/odp_event";
2-
import { OdpEventApiManager } from "../../../core/odp/odp_event_api_manager";
3-
import { LogHandler, LogLevel } from '../../../modules/logging';
1+
import { OdpEvent } from '../../../core/odp/odp_event';
2+
import { OdpEventApiManager } from '../../../core/odp/odp_event_api_manager';
3+
import { LogLevel } from '../../../modules/logging';
44
import { ODP_EVENT_BROWSER_ENDPOINT } from '../../../utils/enums';
55

66
const EVENT_SENDING_FAILURE_MESSAGE = 'ODP event send failed';
@@ -14,15 +14,19 @@ export class BrowserOdpEventApiManager extends OdpEventApiManager {
1414
return false;
1515
}
1616

17-
protected generateRequestData(apiHost: string, apiKey: string, events: OdpEvent[]): { method: string; endpoint: string; headers: { [key: string]: string; }; data: string; } {
18-
const method = 'GET';
17+
protected generateRequestData(
18+
apiHost: string,
19+
apiKey: string,
20+
events: OdpEvent[]
21+
): { method: string; endpoint: string; headers: { [key: string]: string }; data: string } {
22+
const method = 'GET';
1923
const event = events[0];
2024
const url = new URL(ODP_EVENT_BROWSER_ENDPOINT);
21-
event.identifiers.forEach((v, k) =>{
22-
url.searchParams.append(k, v);
25+
event.identifiers.forEach((v, k) => {
26+
url.searchParams.append(k, v);
2327
});
24-
event.data.forEach((v, k) =>{
25-
url.searchParams.append(k, v as string);
28+
event.data.forEach((v, k) => {
29+
url.searchParams.append(k, v as string);
2630
});
2731
url.searchParams.append('tracker_id', apiKey);
2832
url.searchParams.append('event_type', event.type);
@@ -32,7 +36,7 @@ export class BrowserOdpEventApiManager extends OdpEventApiManager {
3236
method,
3337
endpoint,
3438
headers: {},
35-
data: "",
39+
data: '',
3640
};
3741
}
38-
}
42+
}
Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,25 @@
1-
import { OdpEvent } from "../../../core/odp/odp_event";
2-
import { OdpEventApiManager } from "../../../core/odp/odp_event_api_manager";
1+
import { OdpEvent } from '../../../core/odp/odp_event';
2+
import { OdpEventApiManager } from '../../../core/odp/odp_event_api_manager';
33

44
export class NodeOdpEventApiManager extends OdpEventApiManager {
55
protected shouldSendEvents(events: OdpEvent[]): boolean {
66
return true;
77
}
88

9-
protected generateRequestData(apiHost: string, apiKey: string, events: OdpEvent[]): { method: string; endpoint: string; headers: { [key: string]: string; }; data: string; } {
9+
protected generateRequestData(
10+
apiHost: string,
11+
apiKey: string,
12+
events: OdpEvent[]
13+
): { method: string; endpoint: string; headers: { [key: string]: string }; data: string } {
1014
return {
1115
method: 'POST',
1216
endpoint: `${apiHost}/v3/events`,
1317
headers: {
14-
'Content-Type': 'application/json',
15-
'x-api-key': apiKey,
18+
'Content-Type': 'application/json',
19+
'x-api-key': apiKey,
1620
},
1721
data: JSON.stringify(events, this.replacer),
18-
}
22+
};
1923
}
2024

2125
private replacer(_: unknown, value: unknown) {
@@ -25,4 +29,4 @@ export class NodeOdpEventApiManager extends OdpEventApiManager {
2529
return value;
2630
}
2731
}
28-
}
32+
}

packages/optimizely-sdk/lib/utils/fns/index.ts

Lines changed: 48 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ function isSafeInteger(number: unknown): boolean {
5151

5252
export function keyBy<K>(arr: K[], key: string): { [key: string]: K } {
5353
if (!arr) return {};
54-
return keyByUtil(arr, function (item) {
54+
return keyByUtil(arr, function(item) {
5555
// eslint-disable-next-line @typescript-eslint/no-explicit-any
5656
return (item as any)[key];
5757
});
@@ -62,84 +62,84 @@ function isNumber(value: unknown): boolean {
6262
}
6363

6464
export function uuid(): string {
65-
return v4()
65+
return v4();
6666
}
6767

68-
export type Omit<T, K> = Pick<T, Exclude<keyof T, K>>
68+
export type Omit<T, K> = Pick<T, Exclude<keyof T, K>>;
6969

7070
export function getTimestamp(): number {
71-
return new Date().getTime()
71+
return new Date().getTime();
7272
}
7373

7474
/**
75-
* Validates a value is a valid TypeScript enum
76-
*
77-
* @export
78-
* @param {object} enumToCheck
79-
* @param {*} value
80-
* @returns {boolean}
81-
*/
75+
* Validates a value is a valid TypeScript enum
76+
*
77+
* @export
78+
* @param {object} enumToCheck
79+
* @param {*} value
80+
* @returns {boolean}
81+
*/
8282
// TODO[OASIS-6649]: Don't use any type
8383
// eslint-disable-next-line @typescript-eslint/no-explicit-any
8484
export function isValidEnum(enumToCheck: { [key: string]: any }, value: number | string): boolean {
85-
let found = false
85+
let found = false;
8686

87-
const keys = Object.keys(enumToCheck)
87+
const keys = Object.keys(enumToCheck);
8888
for (let index = 0; index < keys.length; index++) {
8989
if (value === enumToCheck[keys[index]]) {
90-
found = true
91-
break
90+
found = true;
91+
break;
9292
}
9393
}
94-
return found
94+
return found;
9595
}
9696

9797
export function groupBy<K>(arr: K[], grouperFn: (item: K) => string): Array<K[]> {
98-
const grouper: { [key: string]: K[] } = {}
98+
const grouper: { [key: string]: K[] } = {};
9999

100100
arr.forEach(item => {
101-
const key = grouperFn(item)
102-
grouper[key] = grouper[key] || []
103-
grouper[key].push(item)
104-
})
101+
const key = grouperFn(item);
102+
grouper[key] = grouper[key] || [];
103+
grouper[key].push(item);
104+
});
105105

106-
return objectValues(grouper)
106+
return objectValues(grouper);
107107
}
108108

109109
export function objectValues<K>(obj: { [key: string]: K }): K[] {
110-
return Object.keys(obj).map(key => obj[key])
110+
return Object.keys(obj).map(key => obj[key]);
111111
}
112112

113113
export function objectEntries<K>(obj: { [key: string]: K }): [string, K][] {
114-
return Object.keys(obj).map(key => [key, obj[key]])
114+
return Object.keys(obj).map(key => [key, obj[key]]);
115115
}
116116

117117
export function find<K>(arr: K[], cond: (arg: K) => boolean): K | undefined {
118-
let found
118+
let found;
119119

120120
for (const item of arr) {
121121
if (cond(item)) {
122-
found = item
123-
break
122+
found = item;
123+
break;
124124
}
125125
}
126126

127-
return found
127+
return found;
128128
}
129129

130130
export function keyByUtil<K>(arr: K[], keyByFn: (item: K) => string): { [key: string]: K } {
131-
const map: { [key: string]: K } = {}
131+
const map: { [key: string]: K } = {};
132132
arr.forEach(item => {
133-
const key = keyByFn(item)
134-
map[key] = item
135-
})
136-
return map
133+
const key = keyByFn(item);
134+
map[key] = item;
135+
});
136+
return map;
137137
}
138138

139139
// TODO[OASIS-6649]: Don't use any type
140140
// eslint-disable-next-line @typescript-eslint/no-explicit-any
141141
export function sprintf(format: string, ...args: any[]): string {
142-
let i = 0
142+
let i = 0;
143143
return format.replace(/%s/g, function() {
144144
const arg = args[i++];
145145
const type = typeof arg;
@@ -150,11 +150,9 @@ export function sprintf(format: string, ...args: any[]): string {
150150
} else {
151151
return String(arg);
152152
}
153-
})
153+
});
154154
}
155155

156-
157-
158156
/**
159157
* Checks two string arrays for equality.
160158
* @param arrayA First Array to be compared against.
@@ -165,6 +163,18 @@ export function checkArrayEquality(arrayA: string[], arrayB: string[]): boolean
165163
return arrayA.length === arrayB.length && arrayA.every((item, index) => item === arrayB[index]);
166164
}
167165

166+
/**
167+
* Checks the current running context
168+
* @returns {boolean} True if window object exists.
169+
*/
170+
export function isBrowser(): boolean {
171+
if (typeof window === 'object' && typeof process !== 'object' && typeof require !== 'function') {
172+
return true;
173+
}
174+
175+
return false;
176+
}
177+
168178
export default {
169179
assign,
170180
checkArrayEquality,
@@ -181,4 +191,5 @@ export default {
181191
find,
182192
keyByUtil,
183193
sprintf,
194+
isBrowser,
184195
};

0 commit comments

Comments
 (0)