diff --git a/src/index.ts b/src/index.ts index 70374bd..34029c7 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,6 +1,7 @@ import $ from 'jquery'; import { tests, + testsObservable, config, getUserAgentInfo, getTest, @@ -18,7 +19,12 @@ import { uiFactory } from './ui'; initialize(); -const ui = uiFactory(tests, reset, getCurrentTestVariation, getUserAgentInfo); +const ui = uiFactory( + testsObservable, + reset, + getCurrentTestVariation, + getUserAgentInfo +); $(() => { if (shouldShowUI()) { diff --git a/src/main.ts b/src/main.ts index 2d49db9..d4fc213 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,6 +1,7 @@ import _getUserAgentInfo, { UserAgentInfo } from './useragentinfo'; import userSession, { UserSession } from './usersession'; import { SplitTest, InternalVariation } from './splittest'; +import { BehavioralSubject } from './behavioral-subject'; export { SplitTest } from './splittest'; import { TrackingDataExtender, @@ -21,6 +22,9 @@ export interface UserConfig { const userAgentInfo = _getUserAgentInfo(); export const tests: SplitTest[] = []; +export const testsObservable: BehavioralSubject< + SplitTest[] +> = new BehavioralSubject(tests); export function config(userConfig: UserConfig = {}) { if (userConfig.cookieName) { @@ -106,6 +110,7 @@ export function create(name: string): SplitTest { baseTrackingDataExtenderFactory() ); tests.push(test); + test.changes.subscribe(() => testsObservable.next(tests)); return test; } diff --git a/src/splittest.ts b/src/splittest.ts index bf523dd..0fffed9 100644 --- a/src/splittest.ts +++ b/src/splittest.ts @@ -1,5 +1,6 @@ import { UserAgentInfo } from './useragentinfo'; import userSession from './usersession'; +import { BehavioralSubject } from './behavioral-subject'; import { TrackingDataExtender, trackingDataExtenderFactory, @@ -31,6 +32,7 @@ export interface InternalVariation extends Variation { export class SplitTest { isInitialized = false; + changes = new BehavioralSubject(this); private condition: ConditionFunction; private readonly _variations: InternalVariation[] = []; @@ -85,6 +87,7 @@ export class SplitTest { weight: typeof variation.weight === 'number' ? variation.weight : 1 }); this.normalizeVariationWeights(); + this.changes.next(this); return this; } @@ -127,6 +130,7 @@ export class SplitTest { this.trackViewed(); } this.isInitialized = true; + this.changes.next(this); return true; } diff --git a/src/ui.ts b/src/ui.ts index 5105701..b1511c1 100644 --- a/src/ui.ts +++ b/src/ui.ts @@ -1,6 +1,7 @@ import $ from 'jquery'; import { InternalVariation, SplitTest } from './splittest'; import { UserAgentInfo } from './useragentinfo'; +import { BehavioralSubject } from './behavioral-subject'; declare const require: any; @@ -13,7 +14,7 @@ function getVariationPercentage(variation: InternalVariation): string { } export const uiFactory = ( - tests: SplitTest[], + tests: BehavioralSubject, reset: () => void, getCurrentTestVariation: (testName: string) => string, getUserAgentInfo: () => UserAgentInfo @@ -79,8 +80,18 @@ export const uiFactory = ( const style = document.createElement('style'); style.innerHTML = require('./main.css'); + const testListEl = document.createElement('div'); + testListEl.className = 'test-list'; + + tests.subscribe(list => { + while (testListEl.hasChildNodes()) { + testListEl.removeChild(testListEl.lastChild); + } + testListEl.innerHTML = list.map(renderTest).join(''); + }); + $abTestContainer = $(`
`).append( - `
${tests.map(renderTest).join('')}
` + testListEl ); $(``) @@ -102,7 +113,7 @@ export const uiFactory = ( function show() { if (isInitialized) { $abTestContainer.removeClass('hideme'); - } else if (tests.length > 0) { + } else { showSplitTestUi(); } }