@splitsoftware/splitio-redux
Advanced tools
Comparing version 1.13.1-rc.5 to 1.13.1-rc.6
@@ -120,3 +120,3 @@ import { __assign } from "tslib"; | ||
} | ||
// @TODO remove `evalOnReadyFromCache` config option, since `false` value has no effect on shared clients (they are ready from cache immediately) and on the main client if its ready from cache when `getTreatments` is called | ||
// @TODO breaking: consider removing `evalOnReadyFromCache` config option, since `false` value has no effect on shared clients (they are ready from cache immediately) and on the main client if its ready from cache when `getTreatments` is called | ||
// If the SDK is not ready from cache and flag `evalOnReadyFromCache`, it stores the action to execute when ready from cache | ||
@@ -129,3 +129,7 @@ if (!status_1.isReadyFromCache && params.evalOnReadyFromCache) { | ||
var treatments = __getTreatments(client_1, [params]); | ||
return addTreatments(params.key || splitSdk.config.core.key, treatments); | ||
// Shared clients might be ready from cache immediately, so we need to dispatch a single action that updates treatments and `isReadyFromCache` status atomically | ||
// @TODO handle this corner case by refactoring actions into a single action that includes both the client status and optional evaluation/s, to minimize state changes and avoid edge cases | ||
return status_1.isReadyFromCache && !status_1.isReady && !isMainClient(params.key) ? | ||
splitReadyFromCacheWithEvaluations(params.key, treatments, status_1.lastUpdate, true) : | ||
addTreatments(params.key || splitSdk.config.core.key, treatments); | ||
} | ||
@@ -189,21 +193,14 @@ else { | ||
// On SDK ready from cache, dispatch `splitReadyFromCache` action | ||
var status = __getStatus(client); | ||
if (status.isReadyFromCache) { // can be true immediately for shared clients | ||
if (splitSdk.dispatch) | ||
splitSdk.dispatch(splitReadyFromCache(status.lastUpdate, key)); | ||
} | ||
else { | ||
client.once(client.Event.SDK_READY_FROM_CACHE, function onReadyFromCache() { | ||
if (!splitSdk.dispatch) | ||
return; | ||
var lastUpdate = __getStatus(client).lastUpdate; | ||
if (client.evalOnReadyFromCache.length) { | ||
var treatments = __getTreatments(client, client.evalOnReadyFromCache); | ||
splitSdk.dispatch(splitReadyFromCacheWithEvaluations(key || splitSdk.config.core.key, treatments, lastUpdate, key && true)); | ||
} | ||
else { | ||
splitSdk.dispatch(splitReadyFromCache(lastUpdate, key)); | ||
} | ||
}); | ||
} | ||
client.once(client.Event.SDK_READY_FROM_CACHE, function onReadyFromCache() { | ||
if (!splitSdk.dispatch) | ||
return; | ||
var lastUpdate = __getStatus(client).lastUpdate; | ||
if (client.evalOnReadyFromCache.length) { | ||
var treatments = __getTreatments(client, client.evalOnReadyFromCache); | ||
splitSdk.dispatch(splitReadyFromCacheWithEvaluations(key || splitSdk.config.core.key, treatments, lastUpdate, key && true)); | ||
} | ||
else { | ||
splitSdk.dispatch(splitReadyFromCache(lastUpdate, key)); | ||
} | ||
}); | ||
// On SDK update, evaluate the registered `getTreatments` actions and dispatch `splitUpdate` action | ||
@@ -210,0 +207,0 @@ client.on(client.Event.SDK_UPDATE, function onUpdate() { |
// Default value for the key where the Split piece of state is expected to be mounted. | ||
export var DEFAULT_SPLIT_STATE_SLICE = 'splitio'; | ||
export var VERSION = 'redux-' + '1.13.1-rc.5'; | ||
export var VERSION = 'redux-' + '1.13.1-rc.6'; | ||
// Treatments | ||
@@ -5,0 +5,0 @@ export var ON = 'on'; |
@@ -124,3 +124,3 @@ "use strict"; | ||
} | ||
// @TODO remove `evalOnReadyFromCache` config option, since `false` value has no effect on shared clients (they are ready from cache immediately) and on the main client if its ready from cache when `getTreatments` is called | ||
// @TODO breaking: consider removing `evalOnReadyFromCache` config option, since `false` value has no effect on shared clients (they are ready from cache immediately) and on the main client if its ready from cache when `getTreatments` is called | ||
// If the SDK is not ready from cache and flag `evalOnReadyFromCache`, it stores the action to execute when ready from cache | ||
@@ -133,3 +133,7 @@ if (!status_1.isReadyFromCache && params.evalOnReadyFromCache) { | ||
var treatments = __getTreatments(client_2, [params]); | ||
return (0, actions_1.addTreatments)(params.key || exports.splitSdk.config.core.key, treatments); | ||
// Shared clients might be ready from cache immediately, so we need to dispatch a single action that updates treatments and `isReadyFromCache` status atomically | ||
// @TODO handle this corner case by refactoring actions into a single action that includes both the client status and optional evaluation/s, to minimize state changes and avoid edge cases | ||
return status_1.isReadyFromCache && !status_1.isReady && !(0, utils_1.isMainClient)(params.key) ? | ||
(0, actions_1.splitReadyFromCacheWithEvaluations)(params.key, treatments, status_1.lastUpdate, true) : | ||
(0, actions_1.addTreatments)(params.key || exports.splitSdk.config.core.key, treatments); | ||
} | ||
@@ -194,21 +198,14 @@ else { | ||
// On SDK ready from cache, dispatch `splitReadyFromCache` action | ||
var status = (0, utils_1.__getStatus)(client); | ||
if (status.isReadyFromCache) { // can be true immediately for shared clients | ||
if (splitSdk.dispatch) | ||
splitSdk.dispatch((0, actions_1.splitReadyFromCache)(status.lastUpdate, key)); | ||
} | ||
else { | ||
client.once(client.Event.SDK_READY_FROM_CACHE, function onReadyFromCache() { | ||
if (!splitSdk.dispatch) | ||
return; | ||
var lastUpdate = (0, utils_1.__getStatus)(client).lastUpdate; | ||
if (client.evalOnReadyFromCache.length) { | ||
var treatments = __getTreatments(client, client.evalOnReadyFromCache); | ||
splitSdk.dispatch((0, actions_1.splitReadyFromCacheWithEvaluations)(key || splitSdk.config.core.key, treatments, lastUpdate, key && true)); | ||
} | ||
else { | ||
splitSdk.dispatch((0, actions_1.splitReadyFromCache)(lastUpdate, key)); | ||
} | ||
}); | ||
} | ||
client.once(client.Event.SDK_READY_FROM_CACHE, function onReadyFromCache() { | ||
if (!splitSdk.dispatch) | ||
return; | ||
var lastUpdate = (0, utils_1.__getStatus)(client).lastUpdate; | ||
if (client.evalOnReadyFromCache.length) { | ||
var treatments = __getTreatments(client, client.evalOnReadyFromCache); | ||
splitSdk.dispatch((0, actions_1.splitReadyFromCacheWithEvaluations)(key || splitSdk.config.core.key, treatments, lastUpdate, key && true)); | ||
} | ||
else { | ||
splitSdk.dispatch((0, actions_1.splitReadyFromCache)(lastUpdate, key)); | ||
} | ||
}); | ||
// On SDK update, evaluate the registered `getTreatments` actions and dispatch `splitUpdate` action | ||
@@ -215,0 +212,0 @@ client.on(client.Event.SDK_UPDATE, function onUpdate() { |
@@ -6,3 +6,3 @@ "use strict"; | ||
exports.DEFAULT_SPLIT_STATE_SLICE = 'splitio'; | ||
exports.VERSION = 'redux-' + '1.13.1-rc.5'; | ||
exports.VERSION = 'redux-' + '1.13.1-rc.6'; | ||
// Treatments | ||
@@ -9,0 +9,0 @@ exports.ON = 'on'; |
{ | ||
"name": "@splitsoftware/splitio-redux", | ||
"version": "1.13.1-rc.5", | ||
"version": "1.13.1-rc.6", | ||
"description": "A library to easily use Split JS SDK with Redux and React Redux", | ||
@@ -5,0 +5,0 @@ "main": "lib/index.js", |
@@ -296,3 +296,2 @@ /** Mocks */ | ||
// getting the evaluation result and validating it matches the results from SDK calls | ||
const treatments = action.payload.treatments; | ||
expect(splitSdk.factory.client().getTreatmentsWithConfig).toHaveBeenNthCalledWith(3, ['split1'], undefined); | ||
@@ -304,3 +303,3 @@ expect(splitSdk.factory.client().getTreatmentsWithConfig).toHaveBeenNthCalledWith(4, ['split2', 'split3'], attributes); | ||
}; | ||
expect(treatments).toEqual(expectedTreatments); | ||
expect(action.payload.treatments).toEqual(expectedTreatments); | ||
@@ -529,17 +528,14 @@ expect(splitSdk.factory.client().getTreatmentsWithConfig).toBeCalledTimes(4); // control assertion - getTreatmentsWithConfig calls | ||
const actionResult = store.dispatch<any>(initSplitSdk({ config: sdkBrowserConfig })); | ||
(splitSdk.factory as any).client().__emitter__.emit(Event.SDK_READY_FROM_CACHE); | ||
(splitSdk.factory as any).client().__emitter__.emit(Event.SDK_READY); | ||
actionResult.then(() => { | ||
// SPLIT_READY should have been dispatched | ||
expect(store.getActions().length).toBe(1); | ||
let action = store.getActions()[0]; | ||
expect(action).toEqual({ | ||
type: SPLIT_READY, | ||
payload: { | ||
timestamp: expect.any(Number) | ||
} | ||
}); | ||
// SDK_READY_FROM_CACHE & SPLIT_READY should have been dispatched | ||
expect(store.getActions()).toEqual([{ | ||
type: SPLIT_READY_FROM_CACHE, payload: { timestamp: expect.any(Number) } | ||
}, { | ||
type: SPLIT_READY, payload: { timestamp: expect.any(Number) } | ||
}]); | ||
// If SDK is ready for the main key and a getTreatment is dispatched for a different user key: | ||
// the item is added to the 'evalOnReady' list of the new client, | ||
// If getTreatment is dispatched for a different user key, the item is added to the 'evalOnReady' list of the new client | ||
store.dispatch<any>(getTreatments({ splitNames: 'split2', key: 'other-user-key' })); | ||
@@ -550,17 +546,21 @@ expect(getClient(splitSdk).evalOnReady.length).toEqual(0); // control assertion - no evaluations were registered for SDK_READY on main client | ||
// and an ADD_TREATMENTS action is dispatched with control treatments without calling SDK client. | ||
action = store.getActions()[1]; | ||
// If SDK was ready from cache, the SPLIT_READY_FROM_CACHE_WITH_EVALUATIONS action is dispatched for the new clients, calling SDK client to evaluate from cache | ||
let action = store.getActions()[2]; | ||
expect(action).toEqual({ | ||
type: ADD_TREATMENTS, | ||
type: SPLIT_READY_FROM_CACHE_WITH_EVALUATIONS, | ||
payload: { | ||
key: 'other-user-key', | ||
treatments: getControlTreatmentsWithConfig(['split2']) | ||
timestamp: 0, | ||
treatments: expect.any(Object), | ||
nonDefaultKey: true | ||
} | ||
}); | ||
expect(splitSdk.factory.client('other-user-key').getTreatmentsWithConfig).toBeCalledTimes(0); | ||
expect(splitSdk.factory.client('other-user-key').getTreatmentsWithConfig).lastCalledWith(['split2'], undefined); | ||
expect(splitSdk.factory.client('other-user-key').getTreatmentsWithConfig).toHaveLastReturnedWith(action.payload.treatments); | ||
(splitSdk.factory as any).client('other-user-key').__emitter__.emit(Event.SDK_READY, 'other-user-key'); | ||
// The SPLIT_READY_WITH_EVALUATIONS action is dispatched synchronously once the SDK is ready for the new user key | ||
action = store.getActions()[2]; | ||
action = store.getActions()[3]; | ||
expect(action).toEqual({ | ||
@@ -577,5 +577,4 @@ type: SPLIT_READY_WITH_EVALUATIONS, | ||
// getting the evaluation result and validating it matches the results from SDK | ||
const treatments = action.payload.treatments; | ||
expect(splitSdk.factory.client('other-user-key').getTreatmentsWithConfig).lastCalledWith(['split2'], undefined); | ||
expect(splitSdk.factory.client('other-user-key').getTreatmentsWithConfig).toHaveLastReturnedWith(treatments); | ||
expect(splitSdk.factory.client('other-user-key').getTreatmentsWithConfig).toHaveLastReturnedWith(action.payload.treatments); | ||
@@ -587,3 +586,3 @@ expect(getClient(splitSdk).evalOnUpdate).toEqual({}); // control assertion | ||
store.dispatch<any>(getTreatments({ splitNames: 'split2', attributes, key: 'other-user-key', evalOnUpdate: true })); | ||
action = store.getActions()[3]; | ||
action = store.getActions()[4]; | ||
expect(action).toEqual({ | ||
@@ -601,3 +600,3 @@ type: ADD_TREATMENTS, | ||
(splitSdk.factory as any).client('other-user-key').__emitter__.emit(Event.SDK_UPDATE); | ||
action = store.getActions()[4]; | ||
action = store.getActions()[5]; | ||
expect(action).toEqual({ | ||
@@ -618,3 +617,3 @@ type: SPLIT_UPDATE_WITH_EVALUATIONS, | ||
store.dispatch<any>(getTreatments({ splitNames: 'split2', key: 'other-user-key', evalOnUpdate: false })); | ||
action = store.getActions()[5]; | ||
action = store.getActions()[6]; | ||
expect(action).toEqual({ | ||
@@ -633,3 +632,3 @@ type: ADD_TREATMENTS, | ||
(splitSdk.factory as any).client('other-user-key').__emitter__.emit(Event.SDK_UPDATE); | ||
action = store.getActions()[6]; | ||
action = store.getActions()[7]; | ||
expect(action).toEqual({ | ||
@@ -643,4 +642,4 @@ type: SPLIT_UPDATE, | ||
expect(store.getActions().length).toBe(7); // control assertion - no more actions after the update. | ||
expect(splitSdk.factory.client('other-user-key').getTreatmentsWithConfig).toBeCalledTimes(4); // control assertion - called 4 times, in actions SPLIT_READY_FROM_CACHE_WITH_EVALUATIONS, SPLIT_READY_WITH_EVALUATIONS, SPLIT_UPDATE_WITH_EVALUATIONS and ADD_TREATMENTS. | ||
expect(store.getActions().length).toBe(8); // control assertion - no more actions after the update. | ||
expect(splitSdk.factory.client('other-user-key').getTreatmentsWithConfig).toBeCalledTimes(5); // control assertion - called 5 times, in actions SPLIT_READY_FROM_CACHE_WITH_EVALUATIONS, SPLIT_READY_WITH_EVALUATIONS, ADD_TREATMENTS, SPLIT_UPDATE_WITH_EVALUATIONS and ADD_TREATMENTS. | ||
@@ -647,0 +646,0 @@ done(); |
@@ -191,7 +191,7 @@ /** Mocks */ | ||
getTreatments({ key: 'user_2', splitNames: ['split_1'] }); | ||
(splitSdk.factory as any).client().__emitter__.emit(Event.SDK_READY_FROM_CACHE); | ||
(splitSdk.factory as any).client('user_2').__emitter__.emit(Event.SDK_READY); | ||
(splitSdk.factory as any).client().__emitter__.emit(Event.SDK_READY); | ||
(splitSdk.factory as any).client('user_2').__emitter__.emit(Event.SDK_READY_FROM_CACHE); | ||
// Main client | ||
const MAIN_CLIENT_STATUS = { ...STATUS_INITIAL, isReadyFromCache: true, isOperational: true, lastUpdate: (splitSdk.factory.client() as any).__getStatus().lastUpdate }; | ||
const MAIN_CLIENT_STATUS = { ...STATUS_INITIAL, isReadyFromCache: true, isReady: true, isOperational: true, lastUpdate: (splitSdk.factory.client() as any).__getStatus().lastUpdate }; | ||
expect(getStatus()).toEqual(MAIN_CLIENT_STATUS); | ||
@@ -202,3 +202,3 @@ expect(getStatus(sdkBrowserConfig.core.key)).toEqual(MAIN_CLIENT_STATUS); | ||
// Client for user_2 | ||
const USER_2_STATUS = { ...STATUS_INITIAL, isReady: true, isReadyFromCache: true, isOperational: true, lastUpdate: (splitSdk.factory.client('user_2') as any).__getStatus().lastUpdate }; | ||
const USER_2_STATUS = { ...STATUS_INITIAL, isReadyFromCache: true, isOperational: true, lastUpdate: (splitSdk.factory.client('user_2') as any).__getStatus().lastUpdate }; | ||
expect(getStatus('user_2')).toEqual(USER_2_STATUS); | ||
@@ -205,0 +205,0 @@ expect(getStatus({ matchingKey: 'user_2', bucketingKey: '' })).toEqual(USER_2_STATUS); |
@@ -33,3 +33,3 @@ import { EventEmitter } from 'events'; | ||
// isReadyFromCache is a shared status among clients | ||
// ATM, isReadyFromCache is shared among clients | ||
let isReadyFromCache = false; | ||
@@ -36,0 +36,0 @@ |
@@ -151,3 +151,3 @@ import { SplitFactory } from '@splitsoftware/splitio'; | ||
// @TODO remove `evalOnReadyFromCache` config option, since `false` value has no effect on shared clients (they are ready from cache immediately) and on the main client if its ready from cache when `getTreatments` is called | ||
// @TODO breaking: consider removing `evalOnReadyFromCache` config option, since `false` value has no effect on shared clients (they are ready from cache immediately) and on the main client if its ready from cache when `getTreatments` is called | ||
// If the SDK is not ready from cache and flag `evalOnReadyFromCache`, it stores the action to execute when ready from cache | ||
@@ -161,3 +161,8 @@ if (!status.isReadyFromCache && params.evalOnReadyFromCache) { | ||
const treatments = __getTreatments(client, [params]); | ||
return addTreatments(params.key || (splitSdk.config as SplitIO.IBrowserSettings).core.key, treatments); | ||
// Shared clients might be ready from cache immediately, so we need to dispatch a single action that updates treatments and `isReadyFromCache` status atomically | ||
// @TODO handle this corner case by refactoring actions into a single action that includes both the client status and optional evaluation/s, to minimize state changes and avoid edge cases | ||
return status.isReadyFromCache && !status.isReady && !isMainClient(params.key) ? | ||
splitReadyFromCacheWithEvaluations(params.key, treatments, status.lastUpdate, true) : | ||
addTreatments(params.key || (splitSdk.config as SplitIO.IBrowserSettings).core.key, treatments); | ||
} else { | ||
@@ -248,19 +253,14 @@ // Otherwise, it adds control treatments to the store, without calling the SDK (no impressions sent) | ||
// On SDK ready from cache, dispatch `splitReadyFromCache` action | ||
const status = __getStatus(client); | ||
if (status.isReadyFromCache) { // can be true immediately for shared clients | ||
if (splitSdk.dispatch) splitSdk.dispatch(splitReadyFromCache(status.lastUpdate, key)); | ||
} else { | ||
client.once(client.Event.SDK_READY_FROM_CACHE, function onReadyFromCache() { | ||
if (!splitSdk.dispatch) return; | ||
client.once(client.Event.SDK_READY_FROM_CACHE, function onReadyFromCache() { | ||
if (!splitSdk.dispatch) return; | ||
const lastUpdate = __getStatus(client).lastUpdate; | ||
if (client.evalOnReadyFromCache.length) { | ||
const treatments = __getTreatments(client, client.evalOnReadyFromCache); | ||
const lastUpdate = __getStatus(client).lastUpdate; | ||
if (client.evalOnReadyFromCache.length) { | ||
const treatments = __getTreatments(client, client.evalOnReadyFromCache); | ||
splitSdk.dispatch(splitReadyFromCacheWithEvaluations(key || (splitSdk.config as SplitIO.IBrowserSettings).core.key, treatments, lastUpdate, key && true)); | ||
} else { | ||
splitSdk.dispatch(splitReadyFromCache(lastUpdate, key)); | ||
} | ||
}); | ||
} | ||
splitSdk.dispatch(splitReadyFromCacheWithEvaluations(key || (splitSdk.config as SplitIO.IBrowserSettings).core.key, treatments, lastUpdate, key && true)); | ||
} else { | ||
splitSdk.dispatch(splitReadyFromCache(lastUpdate, key)); | ||
} | ||
}); | ||
@@ -267,0 +267,0 @@ // On SDK update, evaluate the registered `getTreatments` actions and dispatch `splitUpdate` action |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
295858
5753