New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@amplitude/experiment-js-client

Package Overview
Dependencies
Maintainers
16
Versions
84
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@amplitude/experiment-js-client - npm Package Compare versions

Comparing version 1.2.0 to 1.3.0

dist/types/src/types/source.d.ts

11

CHANGELOG.md

@@ -6,2 +6,13 @@ # Change Log

# [1.3.0](https://github.com/amplitude/experiment-js-client/compare/v1.2.0...v1.3.0) (2021-10-18)
### Features
* unset user properties when variant evaluates to none or is a fallback ([#13](https://github.com/amplitude/experiment-js-client/issues/13)) ([dbab7e8](https://github.com/amplitude/experiment-js-client/commit/dbab7e83659628edcd4fca71e001fc38cae6b27b))
# [1.2.0](https://github.com/amplitude/experiment-js-client/compare/v1.1.1...v1.2.0) (2021-08-12)

@@ -8,0 +19,0 @@

277

dist/experiment.umd.js

@@ -7,53 +7,4 @@ (function (global, factory) {

/**
* Determines the primary source of variants before falling back.
*
* @category Configuration
*/
(function (Source) {
/**
* The default way to source variants within your application. Before the
* assignments are fetched, `getVariant(s)` will fallback to local storage
* first, then `initialVariants` if local storage is empty. This option
* effectively falls back to an assignment fetched previously.
*/
Source["LocalStorage"] = "localStorage";
/**
* This bootstrap option is used primarily for servers-side rendering using an
* Experiment server SDK. This bootstrap option always prefers the config
* `initialVariants` over data in local storage, even if variants are fetched
* successfully and stored locally.
*/
Source["InitialVariants"] = "initialVariants";
})(exports.Source || (exports.Source = {}));
/**
Defaults for Experiment Config options
var safeGlobal = typeof globalThis !== 'undefined' ? globalThis : global || self;
| **Option** | **Default** |
|------------------|-----------------------------------|
| **debug** | `false` |
| **fallbackVariant** | `null` |
| **initialVariants** | `null` |
| **source** | `Source.LocalStorage` |
| **serverUrl** | `"https://api.lab.amplitude.com"` |
| **assignmentTimeoutMillis** | `10000` |
| **retryFailedAssignment** | `true` |
| **userProvider** | `null` |
| **analyticsProvider** | `null` |
*
* @category Configuration
*/
var Defaults = {
debug: false,
fallbackVariant: {},
initialVariants: {},
source: exports.Source.LocalStorage,
serverUrl: 'https://api.lab.amplitude.com',
fetchTimeoutMillis: 10000,
retryFetchOnFailure: true,
userProvider: null,
analyticsProvider: null,
};
/**

@@ -104,7 +55,16 @@ * An AmplitudeUserProvider injects information from the Amplitude SDK into

AmplitudeAnalyticsProvider.prototype.track = function (event) {
if (event.userProperties) {
this.amplitudeInstance.setUserProperties(event.userProperties);
}
this.amplitudeInstance.logEvent(event.name, event.properties);
};
AmplitudeAnalyticsProvider.prototype.setUserProperty = function (event) {
var _a;
var _b;
// if the variant has a value, set the user property and log an event
this.amplitudeInstance.setUserProperties((_a = {},
_a[event.userProperty] = (_b = event.variant) === null || _b === void 0 ? void 0 : _b.value,
_a));
};
AmplitudeAnalyticsProvider.prototype.unsetUserProperty = function (event) {
// if the variant does not have a value, unset the user property
this.amplitudeInstance.identify(new safeGlobal.amplitude.Identify().unset(event.userProperty));
};
return AmplitudeAnalyticsProvider;

@@ -287,5 +247,81 @@ }());

var version = "1.2.0";
var version = "1.3.0";
/**
* Determines the primary source of variants before falling back.
*
* @category Source
*/
(function (Source) {
/**
* The default way to source variants within your application. Before the
* assignments are fetched, `getVariant(s)` will fallback to local storage
* first, then `initialVariants` if local storage is empty. This option
* effectively falls back to an assignment fetched previously.
*/
Source["LocalStorage"] = "localStorage";
/**
* This bootstrap option is used primarily for servers-side rendering using an
* Experiment server SDK. This bootstrap option always prefers the config
* `initialVariants` over data in local storage, even if variants are fetched
* successfully and stored locally.
*/
Source["InitialVariants"] = "initialVariants";
})(exports.Source || (exports.Source = {}));
/**
* Indicates from which source the variant() function determines the variant
*
* @category Source
*/
var VariantSource;
(function (VariantSource) {
VariantSource["LocalStorage"] = "storage";
VariantSource["InitialVariants"] = "initial";
VariantSource["SecondaryLocalStoraage"] = "secondary-storage";
VariantSource["SecondaryInitialVariants"] = "secondary-initial";
VariantSource["FallbackInline"] = "fallback-inline";
VariantSource["FallbackConfig"] = "fallback-config";
})(VariantSource || (VariantSource = {}));
/**
* Returns true if the VariantSource is one of the fallbacks (inline or config)
*
* @param source a {@link VariantSource}
* @returns true if source is {@link VariantSource.FallbackInline} or {@link VariantSource.FallbackConfig}
*/
var isFallback = function (source) {
return (source === VariantSource.FallbackInline ||
source === VariantSource.FallbackConfig);
};
/**
Defaults for Experiment Config options
| **Option** | **Default** |
|------------------|-----------------------------------|
| **debug** | `false` |
| **fallbackVariant** | `null` |
| **initialVariants** | `null` |
| **source** | `Source.LocalStorage` |
| **serverUrl** | `"https://api.lab.amplitude.com"` |
| **assignmentTimeoutMillis** | `10000` |
| **retryFailedAssignment** | `true` |
| **userProvider** | `null` |
| **analyticsProvider** | `null` |
*
* @category Configuration
*/
var Defaults = {
debug: false,
fallbackVariant: {},
initialVariants: {},
source: exports.Source.LocalStorage,
serverUrl: 'https://api.lab.amplitude.com',
fetchTimeoutMillis: 10000,
retryFetchOnFailure: true,
userProvider: null,
analyticsProvider: null,
};
/**
* @packageDocumentation

@@ -400,4 +436,2 @@ * @internal

var safeGlobal = typeof globalThis !== 'undefined' ? globalThis : global || self;
/**

@@ -437,19 +471,28 @@ * @packageDocumentation

*/
var ExposureEvent = /** @class */ (function () {
function ExposureEvent(user, key, variant) {
var _a;
this.name = '[Experiment] Exposure';
this.key = key;
this.variant = variant;
this.properties = {
var exposureEvent = function (user, key, variant, source) {
var _a;
var name = '[Experiment] Exposure';
var value = variant === null || variant === void 0 ? void 0 : variant.value;
var userProperty = "[Experiment] " + key;
return {
name: name,
user: user,
key: key,
variant: variant,
userProperty: userProperty,
properties: {
key: key,
variant: variant.value,
};
this.userProperties = (_a = {},
_a["[Experiment] " + key] = variant.value,
_a);
}
return ExposureEvent;
}());
variant: value,
source: source,
},
userProperties: (_a = {},
_a[userProperty] = value,
_a),
};
};
var isNullOrUndefined = function (value) {
return value === null || value === undefined;
};
var Backoff = /** @class */ (function () {

@@ -701,5 +744,5 @@ function Backoff(attempts, min, max, scalar) {

*
* If an {@link ExperimentAnalyticsProvider} is configured, this function will
* call the provider with an {@link ExposureEvent}. The exposure event does
* not count towards your event volume within Amplitude.
* If an {@link ExperimentAnalyticsProvider} is configured and trackExposure is
* true, this function will call the provider with an {@link ExposureEvent}.
* The exposure event does not count towards your event volume within Amplitude.
*

@@ -712,15 +755,85 @@ * @param key The key to get the variant for.

ExperimentClient.prototype.variant = function (key, fallback) {
var _a, _b, _c;
var _a, _b, _c, _d, _e;
if (!this.apiKey) {
return { value: undefined };
}
var sourceVariant = this.sourceVariants()[key];
if (sourceVariant === null || sourceVariant === void 0 ? void 0 : sourceVariant.value) {
(_a = this.config.analyticsProvider) === null || _a === void 0 ? void 0 : _a.track(new ExposureEvent(this.addContext(this.getUser()), key, this.convertVariant(sourceVariant)));
var _f = this.variantAndSource(key, fallback), source = _f.source, variant = _f.variant;
if (isFallback(source) || !(variant === null || variant === void 0 ? void 0 : variant.value)) {
// fallbacks indicate not being allocated into an experiment, so
// we can unset the property
(_b = (_a = this.config.analyticsProvider) === null || _a === void 0 ? void 0 : _a.unsetUserProperty) === null || _b === void 0 ? void 0 : _b.call(_a, exposureEvent(this.addContext(this.getUser()), key, variant, source));
}
var variant = (_c = (_b = sourceVariant !== null && sourceVariant !== void 0 ? sourceVariant : fallback) !== null && _b !== void 0 ? _b : this.secondaryVariants()[key]) !== null && _c !== void 0 ? _c : this.config.fallbackVariant;
var converted = this.convertVariant(variant);
this.debug("[Experiment] variant for " + key + " is " + converted.value);
return converted;
else if (variant === null || variant === void 0 ? void 0 : variant.value) {
// only track when there's a value for a non fallback variant
var event_1 = exposureEvent(this.addContext(this.getUser()), key, variant, source);
(_d = (_c = this.config.analyticsProvider) === null || _c === void 0 ? void 0 : _c.setUserProperty) === null || _d === void 0 ? void 0 : _d.call(_c, event_1);
(_e = this.config.analyticsProvider) === null || _e === void 0 ? void 0 : _e.track(event_1);
}
this.debug("[Experiment] variant for " + key + " is " + variant.value);
return variant;
};
ExperimentClient.prototype.variantAndSource = function (key, fallback) {
if (this.config.source === exports.Source.InitialVariants) {
// for source = InitialVariants, fallback order goes:
// 1. InitialFlags
// 2. Local Storage
// 3. Function fallback
// 4. Config fallback
var sourceVariant = this.sourceVariants()[key];
if (!isNullOrUndefined(sourceVariant)) {
return {
variant: this.convertVariant(sourceVariant),
source: VariantSource.InitialVariants,
};
}
var secondaryVariant = this.secondaryVariants()[key];
if (!isNullOrUndefined(secondaryVariant)) {
return {
variant: this.convertVariant(secondaryVariant),
source: VariantSource.SecondaryLocalStoraage,
};
}
if (!isNullOrUndefined(fallback)) {
return {
variant: this.convertVariant(fallback),
source: VariantSource.FallbackInline,
};
}
return {
variant: this.convertVariant(this.config.fallbackVariant),
source: VariantSource.FallbackConfig,
};
}
else {
// for source = LocalStorage, fallback order goes:
// 1. Local Storage
// 2. Function fallback
// 3. InitialFlags
// 4. Config fallback
var sourceVariant = this.sourceVariants()[key];
if (!isNullOrUndefined(sourceVariant)) {
return {
variant: this.convertVariant(sourceVariant),
source: VariantSource.LocalStorage,
};
}
if (!isNullOrUndefined(fallback)) {
return {
variant: this.convertVariant(fallback),
source: VariantSource.FallbackInline,
};
}
var secondaryVariant = this.secondaryVariants()[key];
if (!isNullOrUndefined(secondaryVariant)) {
return {
variant: this.convertVariant(secondaryVariant),
source: VariantSource.SecondaryInitialVariants,
};
}
return {
variant: this.convertVariant(this.config.fallbackVariant),
source: VariantSource.FallbackConfig,
};
}
};
/**

@@ -727,0 +840,0 @@ * Returns all variants for the user.

import { ExperimentAnalyticsProvider, ExperimentUserProvider } from './types/provider';
import { Source } from './types/source';
import { Variant, Variants } from './types/variant';
/**
* Determines the primary source of variants before falling back.
*
* @category Configuration
*/
export declare enum Source {
/**
* The default way to source variants within your application. Before the
* assignments are fetched, `getVariant(s)` will fallback to local storage
* first, then `initialVariants` if local storage is empty. This option
* effectively falls back to an assignment fetched previously.
*/
LocalStorage = "localStorage",
/**
* This bootstrap option is used primarily for servers-side rendering using an
* Experiment server SDK. This bootstrap option always prefers the config
* `initialVariants` over data in local storage, even if variants are fetched
* successfully and stored locally.
*/
InitialVariants = "initialVariants"
}
/**
* @category Configuration
*/
export interface ExperimentConfig {

@@ -28,0 +8,0 @@ /**

@@ -66,5 +66,5 @@ /**

*
* If an {@link ExperimentAnalyticsProvider} is configured, this function will
* call the provider with an {@link ExposureEvent}. The exposure event does
* not count towards your event volume within Amplitude.
* If an {@link ExperimentAnalyticsProvider} is configured and trackExposure is
* true, this function will call the provider with an {@link ExposureEvent}.
* The exposure event does not count towards your event volume within Amplitude.
*

@@ -77,2 +77,3 @@ * @param key The key to get the variant for.

variant(key: string, fallback?: string | Variant): Variant;
private variantAndSource;
/**

@@ -79,0 +80,0 @@ * Returns all variants for the user.

@@ -7,3 +7,3 @@ /**

*/
export { ExperimentConfig, Source } from './config';
export { ExperimentConfig } from './config';
export { AmplitudeUserProvider, AmplitudeAnalyticsProvider, } from './integration/amplitude';

@@ -15,3 +15,4 @@ export { Experiment } from './factory';

export { ExperimentUserProvider, ExperimentAnalyticsProvider, } from './types/provider';
export { Source } from './types/source';
export { ExperimentUser } from './types/user';
export { Variant, Variants } from './types/variant';
import { ExperimentAnalyticsEvent } from '../types/analytics';
import { ExperimentUserProvider, ExperimentAnalyticsProvider } from '../types/provider';
import { ExperimentUser } from '../types/user';
declare global {
var amplitude: any;
}
declare type AmplitudeIdentify = {
set(property: string, value: unknown): void;
unset(property: string): void;
};
declare type AmplitudeInstance = {

@@ -9,2 +16,3 @@ options?: AmplitudeOptions;

setUserProperties(userProperties: Record<string, unknown>): void;
identify(identify: AmplitudeIdentify): void;
};

@@ -47,3 +55,5 @@ declare type AmplitudeOptions = {

track(event: ExperimentAnalyticsEvent): void;
setUserProperty(event: ExperimentAnalyticsEvent): void;
unsetUserProperty(event: ExperimentAnalyticsEvent): void;
}
export {};

@@ -0,1 +1,2 @@

import { VariantSource } from './source';
import { ExperimentUser } from './user';

@@ -20,2 +21,9 @@ import { Variant } from './variant';

* {@link ExperimentAnalyticsProvider}.
* This is equivalent to
* ```
* {
* "key": key,
* "variant": variant,
* }
* ```
*/

@@ -25,13 +33,10 @@ properties: Record<string, string>;

* User properties to identify with the user prior to sending the event.
* This is equivalent to
* ```
* {
* [userProperty]: variant
* }
* ```
*/
userProperties?: Record<string, unknown>;
}
/**
* Event for tracking a user's exposure to a variant. This event will not count
* towards your analytics event volume.
*/
export declare class ExposureEvent implements ExperimentAnalyticsEvent {
name: string;
properties: Record<string, string>;
userProperties?: Record<string, unknown>;
/**

@@ -49,3 +54,11 @@ * The user exposed to the flag/experiment variant.

variant: Variant;
constructor(user: ExperimentUser, key: string, variant: Variant);
/**
* The user property for the flag/experiment (auto-generated from the key)
*/
userProperty: string;
}
/**
* Event for tracking a user's exposure to a variant. This event will not count
* towards your analytics event volume.
*/
export declare const exposureEvent: (user: ExperimentUser, key: string, variant: Variant, source: VariantSource) => ExperimentAnalyticsEvent;

@@ -18,3 +18,23 @@ import { ExperimentAnalyticsEvent } from './analytics';

export interface ExperimentAnalyticsProvider {
/**
* Wraps an analytics event track call. This is typically called by the
* experiment client after setting user properties to track an
* "[Experiment] Exposure" event
* @param event see {@link ExperimentAnalyticsEvent}
*/
track(event: ExperimentAnalyticsEvent): void;
/**
* Wraps an analytics identify or set user property call. This is typically
* called by the experiment client before sending an
* "[Experiment] Exposure" event.
* @param event see {@link ExperimentAnalyticsEvent}
*/
setUserProperty?(event: ExperimentAnalyticsEvent): void;
/**
* Wraps an analytics unset user property call. This is typically
* called by the experiment client when a user has been evaluated to use
* a fallback variant.
* @param event see {@link ExperimentAnalyticsEvent}
*/
unsetUserProperty?(event: ExperimentAnalyticsEvent): void;
}
{
"name": "@amplitude/experiment-js-client",
"version": "1.2.0",
"version": "1.3.0",
"description": "Javascript Client SDK for Amplitude Experiment",

@@ -34,3 +34,3 @@ "main": "dist/experiment.umd.js",

},
"gitHead": "5c67aba98fd8e61cba4897328d75ef955bdc5923"
"gitHead": "1e45f1b8314b0398d6a7d1ae9e7a5851e0f96ec6"
}
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc