tas-client-umd
This module is a repackaging of the tas-client
module as a UMD module.
Purpose
This package is intended to be used as an endpoint client to query, refetch, and cache data from an experimentation service (or any given endpoint). The endpoint result must follow the required structure for experimentation data.
Usage
First, your client should implement an IExperimentationFilterProvider
, IExperimentationTelemetry
, and IKeyValueStorage
.
interface IExperimentationFilterProvider {
getFilters(): Map<string, any>;
}
interface IExperimentationTelemetry {
setSharedProperty(name: string, value: string): void;
postEvent(eventName: string, props: Map<string, string>): void;
}
interface IKeyValueStorage {
getValue<T>(key: string, defaultValue?: T): Promise<T | undefined>;
setValue<T>(key: string, value: T): void;
}
Next, they can be used in the TASClient
constructor:
const tasClient = new TASClient({
filterProviders: [filterProvider],
telemetry: telemetry,
storageKey: storageKey,
keyValueStorage: keyValueStorage,
assignmentContextTelemetryPropertyName: '<assignmentContextTelemetryPropertyName>',
telemetryEventName: '<telemetryEventName>',
endpoint: '<tas-endpoint>',
refetchInterval: refetchInterval,
});
assignmentContextTelemetryPropertyName
is a property that is added to every telemetry event for experimentation result calculations.
telemetryEventName
is the name of the event which is posted every time experiment data is queried.
The client provides a variety of functions, but the most basic is getTreatmentVariable(configId: string, name: string)
.
Once you have an instance of IExperimentationService
you can call getTreatmentVariable
to get the value of a treatment variable.
NOTE: If you haven't awaited the IExperimentationService
's initializePromise
, you need to use getTreatmentVariableAsync
.
Typings for Quick Reference
declare module 'tas-client-umd' {
export interface IExperimentationFilterProvider {
getFilters(): Map<string, any>;
}
export interface IExperimentationService {
readonly initializePromise: Promise<void>;
readonly initialFetch: Promise<void>;
isFlightEnabled(flight: string): boolean;
isCachedFlightEnabled(flight: string): Promise<boolean>;
isFlightEnabledAsync(flight: string): Promise<boolean>;
getTreatmentVariable<T extends boolean | number | string>(configId: string, name: string): T | undefined;
getTreatmentVariableAsync<T extends boolean | number | string>(configId: string, name: string, checkCache?: boolean): Promise<T | undefined>;
}
export interface IExperimentationTelemetry {
setSharedProperty(name: string, value: string): void;
postEvent(eventName: string, props: Map<string, string>): void;
}
export interface IKeyValueStorage {
getValue<T>(key: string, defaultValue?: T): Promise<T | undefined>;
setValue<T>(key: string, value: T): void;
}
interface ConfigData {
Id: string;
Parameters: Parameters;
}
interface Parameters {
[key: string]: boolean | number | string;
}
interface FeatureData {
features: string[];
assignmentContext: string;
configs: ConfigData[];
}
interface IFeatureProvider {
getFeatures(): Promise<FeatureData>;
}
abstract class BaseFeatureProvider implements IFeatureProvider {
protected telemetry: IExperimentationTelemetry;
private fetchPromise?;
private isFetching;
constructor(telemetry: IExperimentationTelemetry);
getFeatures(): Promise<FeatureData>;
protected abstract fetch(): Promise<FeatureData>;
}
abstract class FilteredFeatureProvider extends BaseFeatureProvider {
protected telemetry: IExperimentationTelemetry;
protected filterProviders: IExperimentationFilterProvider[];
constructor(telemetry: IExperimentationTelemetry, filterProviders: IExperimentationFilterProvider[]);
private cachedTelemetryEvents: any[];
protected getFilters(): Map<string, any>;
protected PostEventToTelemetry(headers: any): void;
}
interface TASFeatureData {
Features: any[];
Flights: any[];
Configs: ConfigData[];
ParameterGroups: any[];
FlightingVersion: number;
ImpressionId: string;
FlightingEnrichments: any;
AssignmentContext: string;
}
export interface ExperimentationServiceConfig {
telemetry: IExperimentationTelemetry;
endpoint: string;
filterProviders?: IExperimentationFilterProvider[];
featuresTelemetryPropertyName?: string;
assignmentContextTelemetryPropertyName: string;
telemetryEventName: string;
refetchInterval?: number;
storageKey?: string;
keyValueStorage?: IKeyValueStorage;
}
class MemoryKeyValueStorage implements IKeyValueStorage {
private storage;
getValue<T>(key: string, defaultValue?: T): Promise<T | undefined>;
setValue<T>(key: string, value: T): void;
}
abstract class ExperimentationServiceBase implements IExperimentationService {
protected telemetry: IExperimentationTelemetry;
protected assignmentContextTelemetryPropertyName: string;
protected telemetryEventName: string;
protected storageKey?: string | undefined;
protected storage?: IKeyValueStorage | undefined;
protected featureProviders?: IFeatureProvider[];
protected fetchPromise?: Promise<FeatureData[]>;
protected featuresConsumed: boolean;
private loadCachePromise;
readonly initializePromise: Promise<void>;
readonly initialFetch: Promise<void>;
private cachedTelemetryEvents;
private _features;
private get features();
private set features(value);
constructor(telemetry: IExperimentationTelemetry, assignmentContextTelemetryPropertyName: string, telemetryEventName: string, storageKey?: string | undefined, storage?: IKeyValueStorage | undefined);
protected getFeaturesAsync(overrideInMemoryFeatures?: boolean): Promise<FeatureData>;
protected updateFeatures(featureResults: FeatureData[], overrideInMemoryFeatures?: boolean): void;
private loadCachedFeatureData;
isFlightEnabled(flight: string): boolean;
isCachedFlightEnabled(flight: string): Promise<boolean>;
isFlightEnabledAsync(flight: string): Promise<boolean>;
getTreatmentVariable<T extends boolean | number | string>(configId: string, name: string): T | undefined;
getTreatmentVariableAsync<T extends boolean | number | string>(configId: string, name: string, checkCache?: boolean): Promise<T | undefined>;
private PostEventToTelemetry;
protected invokeInit(): void;
protected abstract init(): void;
protected addFeatureProvider(...providers: IFeatureProvider[]): void;
}
class PollingService {
private fetchInterval;
private intervalHandle?;
onTick: (() => Promise<void>) | undefined;
constructor(fetchInterval: number);
StopPolling(): void;
OnPollTick(callback: () => Promise<void>): void;
StartPolling(pollImmediately?: boolean): void;
}
abstract class ExperimentationServiceAutoPolling extends ExperimentationServiceBase {
protected telemetry: IExperimentationTelemetry;
protected filterProviders: IExperimentationFilterProvider[];
protected refreshRateMs: number;
protected assignmentContextTelemetryPropertyName: string;
protected telemetryEventName: string;
protected storageKey?: string | undefined;
protected storage?: IKeyValueStorage | undefined;
private pollingService?;
constructor(telemetry: IExperimentationTelemetry, filterProviders: IExperimentationFilterProvider[], refreshRateMs: number, assignmentContextTelemetryPropertyName: string, telemetryEventName: string, storageKey?: string | undefined, storage?: IKeyValueStorage | undefined);
protected init(): void;
protected getFeaturesAsync(overrideInMemoryFeatures?: boolean): Promise<FeatureData>;
}
export class ExperimentationService extends ExperimentationServiceAutoPolling {
private options;
static REFRESH_RATE_IN_MINUTES: number;
protected featureProviders?: IFeatureProvider[];
constructor(options: ExperimentationServiceConfig);
protected init(): void;
}
}