@eppo/js-client-sdk-common
Advanced tools
Comparing version 2.1.0 to 2.1.1-alpha.0
@@ -23,2 +23,7 @@ import { AssignmentCache, Cacheable } from '../assignment-cache'; | ||
getAssignment(subjectKey: string, flagKey: string, subjectAttributes?: Record<string, any>, assignmentHooks?: IAssignmentHooks): string | null; | ||
_pollerStats(): any; | ||
_getStringAssignmentWithReason(subjectKey: string, flagKey: string, subjectAttributes?: Record<string, any>, assignmentHooks?: IAssignmentHooks, obfuscated?: boolean): { | ||
assignment: string | null; | ||
reason: string; | ||
}; | ||
/** | ||
@@ -67,2 +72,13 @@ * Maps a subject to a variation for a given experiment. | ||
constructor(configurationStore: IConfigurationStore, configurationRequestConfig?: ExperimentConfigurationRequestParameters); | ||
/** | ||
* @deprecated added for temporary debugging | ||
*/ | ||
_pollerStats(): { | ||
initializations: number; | ||
attemptedPolls: number; | ||
failedPolls: number; | ||
succeededPolls: number; | ||
pollDurations: number[]; | ||
failureMessages: string[]; | ||
}; | ||
fetchFlagConfigurations(): Promise<void>; | ||
@@ -72,2 +88,9 @@ stopPolling(): void; | ||
getStringAssignment(subjectKey: string, flagKey: string, subjectAttributes?: Record<string, any>, assignmentHooks?: IAssignmentHooks | undefined, obfuscated?: boolean): string | null; | ||
/** | ||
* @deprecated added for temporary debugging | ||
*/ | ||
_getStringAssignmentWithReason(subjectKey: string, flagKey: string, subjectAttributes?: Record<string, any>, assignmentHooks?: IAssignmentHooks | undefined, obfuscated?: boolean): { | ||
assignment: string | null; | ||
reason: string; | ||
}; | ||
getBoolAssignment(subjectKey: string, flagKey: string, subjectAttributes?: Record<string, any>, assignmentHooks?: IAssignmentHooks | undefined, obfuscated?: boolean): boolean | null; | ||
@@ -74,0 +97,0 @@ getNumericAssignment(subjectKey: string, flagKey: string, subjectAttributes?: Record<string, EppoValue>, assignmentHooks?: IAssignmentHooks | undefined, obfuscated?: boolean): number | null; |
@@ -23,2 +23,8 @@ "use strict"; | ||
} | ||
/** | ||
* @deprecated added for temporary debugging | ||
*/ | ||
_pollerStats() { | ||
return (0, poller_1._pollerStats)(); | ||
} | ||
async fetchFlagConfigurations() { | ||
@@ -80,2 +86,29 @@ var _a, _b, _c, _d, _e; | ||
} | ||
/** | ||
* @deprecated added for temporary debugging | ||
*/ | ||
_getStringAssignmentWithReason(subjectKey, flagKey, | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
subjectAttributes = {}, assignmentHooks, obfuscated = false) { | ||
var _a; | ||
let assignment = null; | ||
let reason = 'Unknown; pre-getAssignmentVariation'; | ||
try { | ||
const eppoValue = this.getAssignmentVariation(subjectKey, flagKey, subjectAttributes, assignmentHooks, obfuscated, eppo_value_1.ValueType.StringType); | ||
const eppoValueAssignment = eppoValue.stringValue; | ||
reason = (_a = eppoValue.reason) !== null && _a !== void 0 ? _a : 'Unknown; post-getAssignmentVariation'; | ||
if (eppoValueAssignment === undefined) { | ||
assignment = null; | ||
reason += '; coalesced to null'; | ||
} | ||
else { | ||
assignment = eppoValueAssignment; | ||
} | ||
} | ||
catch (error) { | ||
reason = 'Caught error: ' + error.message + '\n' + error.stack; | ||
this.rethrowIfNotGraceful(error); | ||
} | ||
return { assignment, reason }; | ||
} | ||
getBoolAssignment(subjectKey, flagKey, | ||
@@ -151,4 +184,6 @@ // eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
const allowListOverride = this.getSubjectVariationOverride(subjectKey, experimentConfig, expectedValueType); | ||
allowListOverride.reason = 'In override list'; | ||
if (!allowListOverride.isNullType()) { | ||
if (!allowListOverride.isExpectedType()) { | ||
nullAssignment.assignment.reason = 'Allow list override is not the expected type'; | ||
return nullAssignment; | ||
@@ -159,9 +194,14 @@ } | ||
// Check for disabled flag. | ||
if (!(experimentConfig === null || experimentConfig === void 0 ? void 0 : experimentConfig.enabled)) | ||
if (!(experimentConfig === null || experimentConfig === void 0 ? void 0 : experimentConfig.enabled)) { | ||
nullAssignment.assignment.reason = 'Experiment is not enabled'; | ||
return nullAssignment; | ||
} | ||
// check for overridden assignment via hook | ||
const overriddenAssignment = assignmentHooks === null || assignmentHooks === void 0 ? void 0 : assignmentHooks.onPreAssignment(flagKey, subjectKey); | ||
if (overriddenAssignment !== null && overriddenAssignment !== undefined) { | ||
if (!overriddenAssignment.isExpectedType()) | ||
if (!overriddenAssignment.isExpectedType()) { | ||
nullAssignment.assignment.reason = 'Override via hook is wrong type'; | ||
return nullAssignment; | ||
} | ||
overriddenAssignment.reason = 'Overriden via hook'; | ||
return Object.assign(Object.assign({}, nullAssignment), { assignment: overriddenAssignment }); | ||
@@ -171,8 +211,12 @@ } | ||
const matchedRule = (0, rule_evaluator_1.findMatchingRule)(subjectAttributes || {}, experimentConfig.rules, obfuscated); | ||
if (!matchedRule) | ||
if (!matchedRule) { | ||
nullAssignment.assignment.reason = 'No matching targeting rule'; | ||
return nullAssignment; | ||
} | ||
// Check if subject is in allocation sample. | ||
const allocation = experimentConfig.allocations[matchedRule.allocationKey]; | ||
if (!this.isInExperimentSample(subjectKey, flagKey, experimentConfig, allocation)) | ||
if (!this.isInExperimentSample(subjectKey, flagKey, experimentConfig, allocation)) { | ||
nullAssignment.assignment.reason = 'Not in experiment sample'; | ||
return nullAssignment; | ||
} | ||
// Compute variation for subject. | ||
@@ -183,2 +227,3 @@ const { subjectShards } = experimentConfig; | ||
let holdoutVariation = null; | ||
let variationReason = ''; | ||
const holdoutShard = (0, shard_1.getShard)(`holdout-${subjectKey}`, subjectShards); | ||
@@ -189,2 +234,3 @@ const matchingHoldout = holdouts === null || holdouts === void 0 ? void 0 : holdouts.find((holdout) => { | ||
assignedVariation = variations.find((variation) => variation.variationKey === statusQuoVariationKey); | ||
variationReason = 'Holdout during in-flight experiment, status quo variation'; | ||
// Only log the holdout variation if this is a rollout allocation | ||
@@ -194,2 +240,3 @@ // Only rollout allocations have shippedShardRange specified | ||
holdoutVariation = assignment_logger_1.HoldoutVariationEnum.STATUS_QUO; | ||
variationReason = 'Holdout after rollout, status quo variation'; | ||
} | ||
@@ -200,2 +247,3 @@ } | ||
holdoutVariation = assignment_logger_1.HoldoutVariationEnum.ALL_SHIPPED; | ||
variationReason = 'Holdout after rollout, shipped variation'; | ||
} | ||
@@ -208,10 +256,17 @@ return assignedVariation; | ||
assignedVariation = variations.find((variation) => (0, shard_1.isShardInRange)(assignmentShard, variation.shardRange)); | ||
variationReason = 'Normal assignment randomization'; | ||
} | ||
const variationEppoValue = eppo_value_1.EppoValue.generateEppoValue(expectedValueType, assignedVariation === null || assignedVariation === void 0 ? void 0 : assignedVariation.value, assignedVariation === null || assignedVariation === void 0 ? void 0 : assignedVariation.typedValue); | ||
variationEppoValue.reason = variationReason; | ||
const typeMismatchAssignment = nullAssignment; | ||
typeMismatchAssignment.assignment.reason = 'Uexpected variation assignment type'; | ||
const internalAssignment = { | ||
allocationKey: matchedRule.allocationKey, | ||
assignment: eppo_value_1.EppoValue.generateEppoValue(expectedValueType, assignedVariation === null || assignedVariation === void 0 ? void 0 : assignedVariation.value, assignedVariation === null || assignedVariation === void 0 ? void 0 : assignedVariation.typedValue), | ||
assignment: variationEppoValue, | ||
holdoutKey, | ||
holdoutVariation: holdoutVariation, | ||
}; | ||
return internalAssignment.assignment.isExpectedType() ? internalAssignment : nullAssignment; | ||
return internalAssignment.assignment.isExpectedType() | ||
? internalAssignment | ||
: typeMismatchAssignment; | ||
} | ||
@@ -218,0 +273,0 @@ setLogger(logger) { |
@@ -15,2 +15,3 @@ export declare enum ValueType { | ||
objectValue: object | undefined; | ||
reason: string | undefined; | ||
private constructor(); | ||
@@ -17,0 +18,0 @@ static generateEppoValue(expectedValueType?: ValueType, value?: string, typedValue?: boolean | number | string | object): EppoValue; |
@@ -5,2 +5,13 @@ export interface IPoller { | ||
} | ||
/** | ||
* @deprecated added for temporary debugging | ||
*/ | ||
export declare function _pollerStats(): { | ||
initializations: number; | ||
attemptedPolls: number; | ||
failedPolls: number; | ||
succeededPolls: number; | ||
pollDurations: number[]; | ||
failureMessages: string[]; | ||
}; | ||
export default function initPoller(intervalMs: number, callback: () => Promise<any>, options?: { | ||
@@ -7,0 +18,0 @@ maxPollRetries?: number; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports._pollerStats = void 0; | ||
const constants_1 = require("./constants"); | ||
// Basic stats | ||
let initializations = 0; | ||
let attemptedPolls = 0; | ||
let failedPolls = 0; | ||
let succeededPolls = 0; | ||
const pollDurations = []; | ||
const failureMessages = []; | ||
/** | ||
* @deprecated added for temporary debugging | ||
*/ | ||
function _pollerStats() { | ||
return { | ||
initializations, | ||
attemptedPolls, | ||
failedPolls, | ||
succeededPolls, | ||
pollDurations, | ||
failureMessages, | ||
}; | ||
} | ||
exports._pollerStats = _pollerStats; | ||
// TODO: change this to a class with methods instead of something that returns a function | ||
@@ -8,2 +30,3 @@ function initPoller(intervalMs, | ||
callback, options) { | ||
initializations += 1; | ||
let stopped = false; | ||
@@ -22,3 +45,7 @@ let failedAttempts = 0; | ||
try { | ||
attemptedPolls += 1; | ||
const timerStart = Date.now(); | ||
await callback(); | ||
pollDurations.push(Date.now() - timerStart); | ||
succeededPolls += 1; | ||
startRequestSuccess = true; | ||
@@ -29,2 +56,4 @@ previousPollFailed = false; | ||
catch (pollingError) { | ||
failedPolls += 1; | ||
failureMessages.push(pollingError.message); | ||
previousPollFailed = true; | ||
@@ -81,4 +110,8 @@ console.warn(`Eppo SDK encountered an error with initial poll of configurations: ${pollingError.message}`); | ||
try { | ||
attemptedPolls += 1; | ||
const timerStart = Date.now(); | ||
await callback(); | ||
pollDurations.push(Date.now() - timerStart); | ||
// If no error, reset any retrying | ||
succeededPolls += 1; | ||
failedAttempts = 0; | ||
@@ -92,2 +125,4 @@ nextPollMs = intervalMs; | ||
catch (error) { | ||
failedPolls += 1; | ||
failureMessages.push(error.message); | ||
previousPollFailed = true; | ||
@@ -94,0 +129,0 @@ console.warn(`Eppo SDK encountered an error polling configurations: ${error.message}`); |
{ | ||
"name": "@eppo/js-client-sdk-common", | ||
"version": "2.1.0", | ||
"version": "2.1.1-alpha.0", | ||
"description": "Eppo SDK for client-side JavaScript applications (base for both web and react native)", | ||
@@ -5,0 +5,0 @@ "main": "dist/index.js", |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
568757
1599
1