Skip to content
This repository was archived by the owner on Jun 21, 2023. It is now read-only.

Commit e07181e

Browse files
authored
refactor: Removed dependency on lodash.forOwn (optimizely#399)
Summary: Removed lodash.forOwn function and replaced all the uses with other implementations. This is part of an effort to remove lodash dependency to reduce bundle size. Test Plan: All Unit tests and Full Stack SDK compatibility passed
1 parent 59cdad4 commit e07181e

File tree

7 files changed

+71
-70
lines changed

7 files changed

+71
-70
lines changed

packages/optimizely-sdk/lib/core/event_builder/event_helpers.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,8 @@ exports.buildConversionEvent = function buildConversionEvent(config) {
140140
function buildVisitorAttributes(configObj, attributes) {
141141
var builtAttributes = [];
142142
// Omit attribute values that are not supported by the log endpoint.
143-
fns.forOwn(attributes, function(attributeValue, attributeKey) {
143+
Object.keys(attributes || {}).forEach(function(attributeKey) {
144+
var attributeValue = attributes[attributeKey];
144145
if (attributesValidator.isAttributeValid(attributeKey, attributeValue)) {
145146
var attributeId = projectConfig.getAttributeId(configObj, attributeKey, logger);
146147
if (attributeId) {

packages/optimizely-sdk/lib/core/event_builder/index.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,8 @@ function getCommonEventParams(options) {
6161
};
6262

6363
// Omit attribute values that are not supported by the log endpoint.
64-
fns.forOwn(attributes, function(attributeValue, attributeKey) {
64+
Object.keys(attributes || {}).forEach(function(attributeKey) {
65+
var attributeValue = attributes[attributeKey];
6566
if (attributeValidator.isAttributeValid(attributeKey, attributeValue)) {
6667
var attributeId = projectConfig.getAttributeId(options.configObj, attributeKey, options.logger);
6768
if (attributeId) {

packages/optimizely-sdk/lib/core/notification_center/index.js

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

1717
var enums = require('../../utils/enums');
18-
var fns = require('../../utils/fns');
1918
var jsSdkUtils = require('@optimizely/js-sdk-utils');
2019

2120
var LOG_LEVEL = enums.LOG_LEVEL;
@@ -37,7 +36,8 @@ function NotificationCenter(options) {
3736
this.logger = options.logger;
3837
this.errorHandler = options.errorHandler;
3938
this.__notificationListeners = {};
40-
fns.forOwn(enums.NOTIFICATION_TYPES, function(notificationTypeEnum) {
39+
40+
jsSdkUtils.objectValues(enums.NOTIFICATION_TYPES).forEach(function(notificationTypeEnum) {
4141
this.__notificationListeners[notificationTypeEnum] = [];
4242
}.bind(this));
4343
this.__listenerId = 1;
@@ -101,7 +101,9 @@ NotificationCenter.prototype.removeNotificationListener = function (listenerId)
101101
try {
102102
var indexToRemove;
103103
var typeToRemove;
104-
fns.forOwn(this.__notificationListeners, function (listenersForType, notificationType) {
104+
105+
Object.keys(this.__notificationListeners).some(function(notificationType) {
106+
var listenersForType = this.__notificationListeners[notificationType];
105107
(listenersForType || []).every(function(listenerEntry, i) {
106108
if (listenerEntry.id === listenerId) {
107109
indexToRemove = i;
@@ -111,10 +113,10 @@ NotificationCenter.prototype.removeNotificationListener = function (listenerId)
111113
return true
112114
});
113115
if (indexToRemove !== undefined && typeToRemove !== undefined) {
114-
return false;
116+
return true;
115117
}
116-
});
117-
118+
}.bind(this));
119+
118120
if (indexToRemove !== undefined && typeToRemove !== undefined) {
119121
this.__notificationListeners[typeToRemove].splice(indexToRemove, 1);
120122
return true;
@@ -131,7 +133,7 @@ NotificationCenter.prototype.removeNotificationListener = function (listenerId)
131133
*/
132134
NotificationCenter.prototype.clearAllNotificationListeners = function () {
133135
try{
134-
fns.forOwn(enums.NOTIFICATION_TYPES, function (notificationTypeEnum) {
136+
jsSdkUtils.objectValues(enums.NOTIFICATION_TYPES).forEach(function (notificationTypeEnum) {
135137
this.__notificationListeners[notificationTypeEnum] = [];
136138
}.bind(this));
137139
} catch (e) {

packages/optimizely-sdk/lib/core/project_config/index.js

Lines changed: 22 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
*/
1616
var fns = require('../../utils/fns');
1717
var enums = require('../../utils/enums');
18-
var sprintf = require('@optimizely/js-sdk-utils').sprintf;
18+
var jsSdkUtils = require('@optimizely/js-sdk-utils');
1919
var configValidator = require('../../utils/config_validator');
2020
var projectConfigSchema = require('./project_config_schema');
2121

@@ -60,7 +60,7 @@ module.exports = {
6060
});
6161

6262
projectConfig.rolloutIdMap = fns.keyBy(projectConfig.rollouts || [], 'id');
63-
fns.forOwn(projectConfig.rolloutIdMap, function(rollout) {
63+
jsSdkUtils.objectValues(projectConfig.rolloutIdMap || {}).forEach(function (rollout) {
6464
(rollout.experiments || []).forEach(function(experiment) {
6565
projectConfig.experiments.push(fns.cloneDeep(experiment));
6666
// Creates { <variationKey>: <variation> } map inside of the experiment
@@ -79,8 +79,7 @@ module.exports = {
7979

8080
// Creates { <variationId>: { key: <variationKey>, id: <variationId> } } mapping for quick lookup
8181
fns.assign(projectConfig.variationIdMap, fns.keyBy(experiment.variations, 'id'));
82-
83-
fns.forOwn(experiment.variationKeyMap, function(variation) {
82+
jsSdkUtils.objectValues(experiment.variationKeyMap || {}).forEach(function (variation) {
8483
if (variation.variables) {
8584
projectConfig.variationVariableUsageMap[variation.id] = fns.keyBy(variation.variables, 'id');
8685
}
@@ -92,7 +91,7 @@ module.exports = {
9291
projectConfig.experimentFeatureMap = {};
9392

9493
projectConfig.featureKeyMap = fns.keyBy(projectConfig.featureFlags || [], 'key');
95-
fns.forOwn(projectConfig.featureKeyMap, function(feature) {
94+
jsSdkUtils.objectValues(projectConfig.featureKeyMap || {}).forEach(function (feature) {
9695
feature.variableKeyMap = fns.keyBy(feature.variables, 'key');
9796
(feature.experimentIds || []).forEach(function(experimentId) {
9897
// Add this experiment in experiment-feature map.
@@ -123,7 +122,7 @@ module.exports = {
123122
getExperimentId: function(projectConfig, experimentKey) {
124123
var experiment = projectConfig.experimentKeyMap[experimentKey];
125124
if (!experiment) {
126-
throw new Error(sprintf(ERROR_MESSAGES.INVALID_EXPERIMENT_KEY, MODULE_NAME, experimentKey));
125+
throw new Error(jsSdkUtils.sprintf(ERROR_MESSAGES.INVALID_EXPERIMENT_KEY, MODULE_NAME, experimentKey));
127126
}
128127
return experiment.id;
129128
},
@@ -138,7 +137,7 @@ module.exports = {
138137
getLayerId: function(projectConfig, experimentId) {
139138
var experiment = projectConfig.experimentIdMap[experimentId];
140139
if (!experiment) {
141-
throw new Error(sprintf(ERROR_MESSAGES.INVALID_EXPERIMENT_ID, MODULE_NAME, experimentId));
140+
throw new Error(jsSdkUtils.sprintf(ERROR_MESSAGES.INVALID_EXPERIMENT_ID, MODULE_NAME, experimentId));
142141
}
143142
return experiment.layerId;
144143
},
@@ -156,14 +155,14 @@ module.exports = {
156155
if (attribute) {
157156
if (hasReservedPrefix) {
158157
logger.log(LOG_LEVEL.WARN,
159-
sprintf('Attribute %s unexpectedly has reserved prefix %s; using attribute ID instead of reserved attribute name.', attributeKey, RESERVED_ATTRIBUTE_PREFIX));
158+
jsSdkUtils.sprintf('Attribute %s unexpectedly has reserved prefix %s; using attribute ID instead of reserved attribute name.', attributeKey, RESERVED_ATTRIBUTE_PREFIX));
160159
}
161160
return attribute.id;
162161
} else if (hasReservedPrefix) {
163162
return attributeKey;
164163
}
165164

166-
logger.log(LOG_LEVEL.DEBUG, sprintf(ERROR_MESSAGES.UNRECOGNIZED_ATTRIBUTE, MODULE_NAME, attributeKey));
165+
logger.log(LOG_LEVEL.DEBUG, jsSdkUtils.sprintf(ERROR_MESSAGES.UNRECOGNIZED_ATTRIBUTE, MODULE_NAME, attributeKey));
167166
return null;
168167
},
169168

@@ -191,7 +190,7 @@ module.exports = {
191190
getExperimentStatus: function(projectConfig, experimentKey) {
192191
var experiment = projectConfig.experimentKeyMap[experimentKey];
193192
if (!experiment) {
194-
throw new Error(sprintf(ERROR_MESSAGES.INVALID_EXPERIMENT_KEY, MODULE_NAME, experimentKey));
193+
throw new Error(jsSdkUtils.sprintf(ERROR_MESSAGES.INVALID_EXPERIMENT_KEY, MODULE_NAME, experimentKey));
195194
}
196195
return experiment.status;
197196
},
@@ -225,7 +224,7 @@ module.exports = {
225224
getExperimentAudienceConditions: function(projectConfig, experimentKey) {
226225
var experiment = projectConfig.experimentKeyMap[experimentKey];
227226
if (!experiment) {
228-
throw new Error(sprintf(ERROR_MESSAGES.INVALID_EXPERIMENT_KEY, MODULE_NAME, experimentKey));
227+
throw new Error(jsSdkUtils.sprintf(ERROR_MESSAGES.INVALID_EXPERIMENT_KEY, MODULE_NAME, experimentKey));
229228
}
230229

231230
return experiment.audienceConditions || experiment.audienceIds;
@@ -274,7 +273,7 @@ module.exports = {
274273
}
275274
}
276275

277-
throw new Error(sprintf(ERROR_MESSAGES.EXPERIMENT_KEY_NOT_IN_DATAFILE, MODULE_NAME, experimentKey));
276+
throw new Error(jsSdkUtils.sprintf(ERROR_MESSAGES.EXPERIMENT_KEY_NOT_IN_DATAFILE, MODULE_NAME, experimentKey));
278277
},
279278

280279
/**
@@ -287,7 +286,7 @@ module.exports = {
287286
getTrafficAllocation: function(projectConfig, experimentKey) {
288287
var experiment = projectConfig.experimentKeyMap[experimentKey];
289288
if (!experiment) {
290-
throw new Error(sprintf(ERROR_MESSAGES.INVALID_EXPERIMENT_KEY, MODULE_NAME, experimentKey));
289+
throw new Error(jsSdkUtils.sprintf(ERROR_MESSAGES.INVALID_EXPERIMENT_KEY, MODULE_NAME, experimentKey));
291290
}
292291
return experiment.trafficAllocation;
293292
},
@@ -307,7 +306,7 @@ module.exports = {
307306
}
308307
}
309308

310-
logger.log(LOG_LEVEL.ERROR, sprintf(ERROR_MESSAGES.INVALID_EXPERIMENT_ID, MODULE_NAME, experimentId));
309+
logger.log(LOG_LEVEL.ERROR, jsSdkUtils.sprintf(ERROR_MESSAGES.INVALID_EXPERIMENT_ID, MODULE_NAME, experimentId));
311310
return null;
312311
},
313312

@@ -328,7 +327,7 @@ module.exports = {
328327
}
329328
}
330329

331-
logger.log(LOG_LEVEL.ERROR, sprintf(ERROR_MESSAGES.FEATURE_NOT_IN_DATAFILE, MODULE_NAME, featureKey));
330+
logger.log(LOG_LEVEL.ERROR, jsSdkUtils.sprintf(ERROR_MESSAGES.FEATURE_NOT_IN_DATAFILE, MODULE_NAME, featureKey));
332331
return null;
333332
},
334333

@@ -346,13 +345,13 @@ module.exports = {
346345
getVariableForFeature: function(projectConfig, featureKey, variableKey, logger) {
347346
var feature = projectConfig.featureKeyMap[featureKey];
348347
if (!feature) {
349-
logger.log(LOG_LEVEL.ERROR, sprintf(ERROR_MESSAGES.FEATURE_NOT_IN_DATAFILE, MODULE_NAME, featureKey));
348+
logger.log(LOG_LEVEL.ERROR, jsSdkUtils.sprintf(ERROR_MESSAGES.FEATURE_NOT_IN_DATAFILE, MODULE_NAME, featureKey));
350349
return null;
351350
}
352351

353352
var variable = feature.variableKeyMap[variableKey];
354353
if (!variable) {
355-
logger.log(LOG_LEVEL.ERROR, sprintf(ERROR_MESSAGES.VARIABLE_KEY_NOT_IN_DATAFILE, MODULE_NAME, variableKey, featureKey));
354+
logger.log(LOG_LEVEL.ERROR, jsSdkUtils.sprintf(ERROR_MESSAGES.VARIABLE_KEY_NOT_IN_DATAFILE, MODULE_NAME, variableKey, featureKey));
356355
return null;
357356
}
358357

@@ -377,7 +376,7 @@ module.exports = {
377376
}
378377

379378
if (!projectConfig.variationVariableUsageMap.hasOwnProperty(variation.id)) {
380-
logger.log(LOG_LEVEL.ERROR, sprintf(ERROR_MESSAGES.VARIATION_ID_NOT_IN_DATAFILE_NO_EXPERIMENT, MODULE_NAME, variation.id));
379+
logger.log(LOG_LEVEL.ERROR, jsSdkUtils.sprintf(ERROR_MESSAGES.VARIATION_ID_NOT_IN_DATAFILE_NO_EXPERIMENT, MODULE_NAME, variation.id));
381380
return null;
382381
}
383382

@@ -409,7 +408,7 @@ module.exports = {
409408
switch (variableType) {
410409
case FEATURE_VARIABLE_TYPES.BOOLEAN:
411410
if (variableValue !== 'true' && variableValue !== 'false') {
412-
logger.log(LOG_LEVEL.ERROR, sprintf(ERROR_MESSAGES.UNABLE_TO_CAST_VALUE, MODULE_NAME, variableValue, variableType));
411+
logger.log(LOG_LEVEL.ERROR, jsSdkUtils.sprintf(ERROR_MESSAGES.UNABLE_TO_CAST_VALUE, MODULE_NAME, variableValue, variableType));
413412
castValue = null;
414413
} else {
415414
castValue = variableValue === 'true';
@@ -419,15 +418,15 @@ module.exports = {
419418
case FEATURE_VARIABLE_TYPES.INTEGER:
420419
castValue = parseInt(variableValue, 10);
421420
if (isNaN(castValue)) {
422-
logger.log(LOG_LEVEL.ERROR, sprintf(ERROR_MESSAGES.UNABLE_TO_CAST_VALUE, MODULE_NAME, variableValue, variableType));
421+
logger.log(LOG_LEVEL.ERROR, jsSdkUtils.sprintf(ERROR_MESSAGES.UNABLE_TO_CAST_VALUE, MODULE_NAME, variableValue, variableType));
423422
castValue = null;
424423
}
425424
break;
426425

427426
case FEATURE_VARIABLE_TYPES.DOUBLE:
428427
castValue = parseFloat(variableValue);
429428
if (isNaN(castValue)) {
430-
logger.log(LOG_LEVEL.ERROR, sprintf(ERROR_MESSAGES.UNABLE_TO_CAST_VALUE, MODULE_NAME, variableValue, variableType));
429+
logger.log(LOG_LEVEL.ERROR, jsSdkUtils.sprintf(ERROR_MESSAGES.UNABLE_TO_CAST_VALUE, MODULE_NAME, variableValue, variableType));
431430
castValue = null;
432431
}
433432
break;
@@ -485,10 +484,10 @@ module.exports = {
485484
tryCreatingProjectConfig: function(config) {
486485
configValidator.validateDatafile(config.datafile);
487486
if (config.skipJSONValidation === true) {
488-
config.logger.log(LOG_LEVEL.INFO, sprintf(LOG_MESSAGES.SKIPPING_JSON_VALIDATION, MODULE_NAME));
487+
config.logger.log(LOG_LEVEL.INFO, jsSdkUtils.sprintf(LOG_MESSAGES.SKIPPING_JSON_VALIDATION, MODULE_NAME));
489488
} else if (config.jsonSchemaValidator) {
490489
config.jsonSchemaValidator.validate(projectConfigSchema, config.datafile);
491-
config.logger.log(LOG_LEVEL.INFO, sprintf(LOG_MESSAGES.VALID_DATAFILE, MODULE_NAME));
490+
config.logger.log(LOG_LEVEL.INFO, jsSdkUtils.sprintf(LOG_MESSAGES.VALID_DATAFILE, MODULE_NAME));
492491
}
493492
return module.exports.createProjectConfig(config.datafile);
494493
},

0 commit comments

Comments
 (0)