All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
- added support for custom salt values in campaign rules to ensure consistent user bucketing across different campaigns. This allows multiple campaigns to share the same salt value, resulting in users being assigned to the same variations across those campaigns. Salt for a campaign can be configured inside VWO application only when the campaign is in the draft state.
- added new method
updateSettings
to update settings on the client instance.
- Added support to pass settings in
init
method.
- added support for Personalise rules within
Mutually Exclusive Groups
.
-
added support to wait for network response incase of edge like environment.
const { init } = require('vwo-fme-node-sdk'); const vwoClient = await init({ accountId: '123456', // VWO Account ID sdkKey: '32-alpha-numeric-sdk-key', // SDK Key shouldWaitForTrackingCalls: true, // if running on edge env });
-
Update key name from
user
touserId
for storing User ID in storage connector.class StorageConnector extends StorageConnector { constructor() { super(); } /** * Get data from storage * @param {string} featureKey * @param {string} userId * @returns {Promise<any>} */ async get(featureKey, userId) { // return await data (based on featureKey and userId) } /** * Set data in storage * @param {object} data */ async set(data) { // Set data corresponding to a featureKey and user ID // Use data.featureKey and data.userId to store the above data for a specific feature and a user } }
- Updated regular expressions for
GREATER_THAN_MATCH
,GREATER_THAN_EQUAL_TO_MATCH
,LESS_THAN_MATCH
, andLESS_THAN_EQUAL_TO_MATCH
segmentation operators
- Encode user-agent in
setAttribute
andtrackEvent
APIs before making a call to VWO server`
- Modified code to support browser and Node.js environment
- The same SDK can be used in the browser and Node.js environment without any changes in the code from the customer side
- Refactored code to use interfaces and types wherever missing or required
Client-side Javascript SDK
- Used webpack for bundling code
- Separate builds for Node.js and browser using
webpack
- SDK is compatible to be run on browser(as a Script, client-side rendering with React ,Ionic framework, etc.)
- Node.js environment can now use one single bundled file too, if required
- fix: add support for DSL where featureIdValue could be
off
- refactor: make eventProperties as third parameter
- Update dist folder
- Fix: add revenueProp in metricSchema for settings validation
- Optimizaton: if userAgent and ipAddress both are null, then no need to send call to gatewayService
- Fix: use experiment-key from rule instead of whitelisted object
- Use vwo-fme-sdk-e2e-test-settings-n-cases for importing segmentation tests instead of using hardcoded
- Handle how device was being used by User-Agent parser.
- Refactor VWO Gateway service code to handle non-US accounts
- Fix passing required headers in the network-calls for tracking user details to VWO servers
- Fix some log messages where variables were not getting interpolated correctly
- Instead of hardcoding the test-cases and expectations for
getFlag
API, we create a separate repo where tests and expectations were written in a JSON format. This is done to make sure we have common and same tests passing across our FME SDKs. Node SDK is using it as dependency - vwo-fme-sdk-e2e-test-settings-n-cases - SDK is now fully supported from Node 12+ versions. We ensured this by running exhaustive unit/E2E tests via GitHub actions for all the Node 12+ versions
- Add a new github-action to generate and publish code documentation generated via
typedoc
-
Segmentation module
- Modify how context and settings are being used inside modular segmentor code
- Cache location / User-Agent data per
getFlag
API - Single endpoint for location and User-Agent at gateway-service so that at max one call will be required to fetch data from gateway service
-
Context refactoring
-
Context is now flattened out
{ id: 'user-id', // MANDATORY ipAddress: '1.2.3.4', // OPTIONAL - required for user targeting userAgent: '...', // OPTIONAL - required for user targeting // For pre-segmentation in campaigns customVariables: { price: 300 // ... } }
-
-
Storage optimizations
-
Optimized how data is being stored and retrieved
-
Example on how to pass storage
class StorageConnector extends StorageConnector { constructor() { super(); } /** * Get data from storage * @param {string} featureKey * @param {string} userId * @returns {Promise<any>} */ async get(featureKey, userId) { // return await data (based on featureKey and userId) } /** * Set data in storage * @param {object} data */ async set(data) { // Set data corresponding to a featureKey and user ID // Use data.featureKey and data.userId to store the above data for a specific feature and a user } } init({ sdkKey: '...', accountId: '123456', storage: StorageConnector, });
-
-
Using interfaces, types, and model-driven code
- Since we are using TypeScript which helps in the definition types and catching errors while developing.
-
Overall Code refactoring
- Simplified the flow of
getFlag
API
- Simplified the flow of
-
Log messages
- Separate Repo to have all the logs in one place.
- Log messages were updated
logger: { level: LogLevelEnum.DEBUG, // DEBUG, INFO, ERROR, TRACE< WARN prefix: 'CUSTOM LOG PREFIX', // VWO-SDK default transport: { // Custom Logger debug: msg => console.log(msg), info: msg => console.log(msg), warn: msg => console.log(msg), error: msg => console.log(msg), trace: msg => console.log(msg) } } init({ sdkKey: '...', accountId: '123456', logger: logger });
-
Code inline documentation
- Entire Code was documented as per JavaScript Documentation convention.
-
Unit and E2E Testing
- Set up Test framework using
Jest
- Wrote unit and E2E tests to ensure nothing breaks while pushing new code
- Ensure criticla components are working properly on every build
- Integrate with Codecov to show coverage percentage in README
- Post status of tests running on different node versions to Wingify slack channel
- Set up Test framework using
-
onInit hook
init({ sdkKey: '...', accountId: '123456' }); onInit().then(async (vwoClient) => { const feature = await vwoClient.getFlag('feature-key', context); console.log('getFlag is: ', feature.isEnabled()); }).catch(err => { console.log('Error: ', err); });
-
Error handling
- Gracefully handle any kind of error - TypeError, NetworkError, etc.
-
Polling support
- Provide a way to fetch settings periodically and update the instance to use the latest settings
const vwoClient = await init({ sdkKey: '...', accountId: '123456', pollInterval: 5000 // in milliseconds });
-
First release of VWO Feature Management and Experimentation capabilities
const { init } = require('vwo-fme-node-sdk'); const vwoClient = await init({ accountId: '123456', // VWO Account ID sdkKey: '32-alpha-numeric-sdk-key', // SDK Key }); // set user context const userContext = { id: 'unique_user_id' }; // returns a flag object const getFlag = await vwoClient.getFlag('feature_key', userContext); // check if flag is enabled const isFlagEnabled = getFlag.isEnabled(); // get variable const intVar = getFlag.getVariable('int_variable_key'); // track event vwoClient.trackEvent('addToCart', eventProperties, userContext);