From 8b8651d353b6663c3fc0d9df5c682fcd28b8ad77 Mon Sep 17 00:00:00 2001 From: Nicolas Janvier Date: Wed, 2 Sep 2020 16:24:15 +0200 Subject: [PATCH 1/4] feat: add sessionPersister to config --- src/index.ts | 2 ++ src/main.ts | 3 +++ 2 files changed, 5 insertions(+) diff --git a/src/index.ts b/src/index.ts index 9185589..00ec097 100644 --- a/src/index.ts +++ b/src/index.ts @@ -12,6 +12,7 @@ import { } from './main'; import { SplitTest } from './splitTest'; import { uiFactory } from './ui'; +import { UserSessionPersister } from './userSessionPersister'; const ui = uiFactory( testsObservable, @@ -47,6 +48,7 @@ export { reset, ui, SplitTest, + UserSessionPersister, }; export default { diff --git a/src/main.ts b/src/main.ts index 773e7ad..dd4be4b 100644 --- a/src/main.ts +++ b/src/main.ts @@ -30,6 +30,9 @@ export function config(userConfig: Partial = {}) { if (userConfig.onVariationChange) { _config.onVariationChange = userConfig.onVariationChange; } + if (userConfig.sessionPersister) { + _config.sessionPersister = userConfig.sessionPersister; + } } /** From d55e76e7486f9553aaf9d7add997a3832851b181 Mon Sep 17 00:00:00 2001 From: Nicolas Janvier Date: Thu, 3 Sep 2020 13:38:48 +0200 Subject: [PATCH 2/4] feat: add in memory storage --- src/index.ts | 4 ++- src/main.ts | 2 ++ src/userSessionPersister.ts | 58 ++++++++++++++++++++----------------- 3 files changed, 37 insertions(+), 27 deletions(-) diff --git a/src/index.ts b/src/index.ts index 00ec097..0e8ceac 100644 --- a/src/index.ts +++ b/src/index.ts @@ -12,7 +12,7 @@ import { } from './main'; import { SplitTest } from './splitTest'; import { uiFactory } from './ui'; -import { UserSessionPersister } from './userSessionPersister'; +import { UserSessionPersister, InMemoryPersister, CookiePersister } from './userSessionPersister'; const ui = uiFactory( testsObservable, @@ -49,6 +49,8 @@ export { ui, SplitTest, UserSessionPersister, + InMemoryPersister, + CookiePersister, }; export default { diff --git a/src/main.ts b/src/main.ts index dd4be4b..0c44bd0 100644 --- a/src/main.ts +++ b/src/main.ts @@ -31,7 +31,9 @@ export function config(userConfig: Partial = {}) { _config.onVariationChange = userConfig.onVariationChange; } if (userConfig.sessionPersister) { + const userSession = _config.sessionPersister.loadUserSession() || ''; _config.sessionPersister = userConfig.sessionPersister; + _config.sessionPersister.saveUserSession(userSession, _config.userSessionDaysToLive); } } diff --git a/src/userSessionPersister.ts b/src/userSessionPersister.ts index 41a18a2..679503a 100644 --- a/src/userSessionPersister.ts +++ b/src/userSessionPersister.ts @@ -1,40 +1,46 @@ import config from './config'; - export interface UserSessionPersister { loadUserSession(): string | null; saveUserSession(userSession: string, daysToLive: number): void; } - -function createCookie(name: string, value: string, days: number): void { - let expires = ''; - if (days) { - const date = new Date(); - date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000)); - expires = '; expires=' + date.toUTCString(); +export class CookiePersister implements UserSessionPersister { + public loadUserSession() { + return CookiePersister.readCookie(config.cookieName); } - document.cookie = name + '=' + value + expires + '; path=/'; -} - -function readCookie(name: string): string | null { - const nameEq = name + '='; - const ca = document.cookie.split(';'); - for (let c of ca) { - while (c.charAt(0) === ' ') { - c = c.substring(1, c.length); + public saveUserSession(userSession: string, daysToLive: number) { + CookiePersister.createCookie(config.cookieName, userSession, daysToLive); + } + private static createCookie(name: string, value: string, days: number): void { + let expires = ''; + if (days) { + const date = new Date(); + date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000)); + expires = '; expires=' + date.toUTCString(); } - if (c.indexOf(nameEq) === 0) { - return c.substring(nameEq.length, c.length); + document.cookie = name + '=' + value + expires + '; path=/'; + } + private static readCookie(name: string): string | null { + const nameEq = name + '='; + const ca = document.cookie.split(';'); + for (let c of ca) { + while (c.charAt(0) === ' ') { + c = c.substring(1, c.length); + } + if (c.indexOf(nameEq) === 0) { + return c.substring(nameEq.length, c.length); + } } + return null; } - return null; } - -export class CookiePersister implements UserSessionPersister { +export class InMemoryPersister implements UserSessionPersister { + private endOfLife: number = 0; + private storage: string = ''; public loadUserSession() { - return readCookie(config.cookieName); + return !this.endOfLife || (Date.now() > this.endOfLife) ? '' : this.storage; } - public saveUserSession(userSession: string, daysToLive: number) { - createCookie(config.cookieName, userSession, daysToLive); + this.storage = userSession; + this.endOfLife = Date.now() + (daysToLive*24*60*60*1000); } -} +} \ No newline at end of file From 426986716067cf2a9a30b46a0281cc04f72e1ed7 Mon Sep 17 00:00:00 2001 From: Nicolas Janvier Date: Thu, 3 Sep 2020 13:49:04 +0200 Subject: [PATCH 3/4] fix: linting --- src/config.ts | 3 ++- src/cookiePersister.ts | 33 +++++++++++++++++++++++++++++ src/inMemoryPersister.ts | 13 ++++++++++++ src/index.ts | 4 +++- src/main.ts | 4 ++-- src/userSessionPersister.ts | 41 ------------------------------------- 6 files changed, 53 insertions(+), 45 deletions(-) create mode 100644 src/cookiePersister.ts create mode 100644 src/inMemoryPersister.ts diff --git a/src/config.ts b/src/config.ts index 8c24f67..a98c98d 100644 --- a/src/config.ts +++ b/src/config.ts @@ -1,7 +1,8 @@ import { Condition } from './condition'; +import { CookiePersister } from './cookiePersister'; import { removeAbTestParameter } from './query'; import { ConsoleTracking, Tracking } from './tracking'; -import { CookiePersister, UserSessionPersister } from './userSessionPersister'; +import { UserSessionPersister } from './userSessionPersister'; export interface Config { cookieName: string; diff --git a/src/cookiePersister.ts b/src/cookiePersister.ts new file mode 100644 index 0000000..8ff6587 --- /dev/null +++ b/src/cookiePersister.ts @@ -0,0 +1,33 @@ +import config from './config'; +import { UserSessionPersister } from './userSessionPersister'; + +export class CookiePersister implements UserSessionPersister { + private static createCookie(name: string, value: string, days: number): void { + let expires = ''; + if (days) { + const date = new Date(); + date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000)); + expires = '; expires=' + date.toUTCString(); + } + document.cookie = name + '=' + value + expires + '; path=/'; + } + private static readCookie(name: string): string | null { + const nameEq = name + '='; + const ca = document.cookie.split(';'); + for (let c of ca) { + while (c.charAt(0) === ' ') { + c = c.substring(1, c.length); + } + if (c.indexOf(nameEq) === 0) { + return c.substring(nameEq.length, c.length); + } + } + return null; + } + public loadUserSession() { + return CookiePersister.readCookie(config.cookieName); + } + public saveUserSession(userSession: string, daysToLive: number) { + CookiePersister.createCookie(config.cookieName, userSession, daysToLive); + } +} diff --git a/src/inMemoryPersister.ts b/src/inMemoryPersister.ts new file mode 100644 index 0000000..b0a388d --- /dev/null +++ b/src/inMemoryPersister.ts @@ -0,0 +1,13 @@ +import { UserSessionPersister } from './userSessionPersister'; + +export class InMemoryPersister implements UserSessionPersister { + private endOfLife: number = 0; + private storage: string = ''; + public loadUserSession() { + return !this.endOfLife || (Date.now() > this.endOfLife) ? '' : this.storage; + } + public saveUserSession(userSession: string, daysToLive: number) { + this.storage = userSession; + this.endOfLife = Date.now() + (daysToLive * 24 * 60 * 60 * 1000); + } +} diff --git a/src/index.ts b/src/index.ts index 0e8ceac..5f36f41 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,3 +1,5 @@ +import { CookiePersister } from './cookiePersister'; +import { InMemoryPersister } from './inMemoryPersister'; import { config, create, @@ -12,7 +14,7 @@ import { } from './main'; import { SplitTest } from './splitTest'; import { uiFactory } from './ui'; -import { UserSessionPersister, InMemoryPersister, CookiePersister } from './userSessionPersister'; +import { UserSessionPersister } from './userSessionPersister'; const ui = uiFactory( testsObservable, diff --git a/src/main.ts b/src/main.ts index 0c44bd0..aeec0c6 100644 --- a/src/main.ts +++ b/src/main.ts @@ -31,9 +31,9 @@ export function config(userConfig: Partial = {}) { _config.onVariationChange = userConfig.onVariationChange; } if (userConfig.sessionPersister) { - const userSession = _config.sessionPersister.loadUserSession() || ''; + const session = _config.sessionPersister.loadUserSession() || ''; _config.sessionPersister = userConfig.sessionPersister; - _config.sessionPersister.saveUserSession(userSession, _config.userSessionDaysToLive); + _config.sessionPersister.saveUserSession(session, _config.userSessionDaysToLive); } } diff --git a/src/userSessionPersister.ts b/src/userSessionPersister.ts index 679503a..bbdf19b 100644 --- a/src/userSessionPersister.ts +++ b/src/userSessionPersister.ts @@ -3,44 +3,3 @@ export interface UserSessionPersister { loadUserSession(): string | null; saveUserSession(userSession: string, daysToLive: number): void; } -export class CookiePersister implements UserSessionPersister { - public loadUserSession() { - return CookiePersister.readCookie(config.cookieName); - } - public saveUserSession(userSession: string, daysToLive: number) { - CookiePersister.createCookie(config.cookieName, userSession, daysToLive); - } - private static createCookie(name: string, value: string, days: number): void { - let expires = ''; - if (days) { - const date = new Date(); - date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000)); - expires = '; expires=' + date.toUTCString(); - } - document.cookie = name + '=' + value + expires + '; path=/'; - } - private static readCookie(name: string): string | null { - const nameEq = name + '='; - const ca = document.cookie.split(';'); - for (let c of ca) { - while (c.charAt(0) === ' ') { - c = c.substring(1, c.length); - } - if (c.indexOf(nameEq) === 0) { - return c.substring(nameEq.length, c.length); - } - } - return null; - } -} -export class InMemoryPersister implements UserSessionPersister { - private endOfLife: number = 0; - private storage: string = ''; - public loadUserSession() { - return !this.endOfLife || (Date.now() > this.endOfLife) ? '' : this.storage; - } - public saveUserSession(userSession: string, daysToLive: number) { - this.storage = userSession; - this.endOfLife = Date.now() + (daysToLive*24*60*60*1000); - } -} \ No newline at end of file From 79b359528bb2c2eb280f9f828c2185cdcc7f2365 Mon Sep 17 00:00:00 2001 From: Nicolas Janvier Date: Thu, 3 Sep 2020 14:11:59 +0200 Subject: [PATCH 4/4] fix: tests --- src/config.ts | 3 +-- src/cookiePersister.ts | 33 --------------------------------- src/index.ts | 3 +-- src/userSessionPersister.ts | 30 ++++++++++++++++++++++++++++++ 4 files changed, 32 insertions(+), 37 deletions(-) delete mode 100644 src/cookiePersister.ts diff --git a/src/config.ts b/src/config.ts index a98c98d..8c24f67 100644 --- a/src/config.ts +++ b/src/config.ts @@ -1,8 +1,7 @@ import { Condition } from './condition'; -import { CookiePersister } from './cookiePersister'; import { removeAbTestParameter } from './query'; import { ConsoleTracking, Tracking } from './tracking'; -import { UserSessionPersister } from './userSessionPersister'; +import { CookiePersister, UserSessionPersister } from './userSessionPersister'; export interface Config { cookieName: string; diff --git a/src/cookiePersister.ts b/src/cookiePersister.ts deleted file mode 100644 index 8ff6587..0000000 --- a/src/cookiePersister.ts +++ /dev/null @@ -1,33 +0,0 @@ -import config from './config'; -import { UserSessionPersister } from './userSessionPersister'; - -export class CookiePersister implements UserSessionPersister { - private static createCookie(name: string, value: string, days: number): void { - let expires = ''; - if (days) { - const date = new Date(); - date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000)); - expires = '; expires=' + date.toUTCString(); - } - document.cookie = name + '=' + value + expires + '; path=/'; - } - private static readCookie(name: string): string | null { - const nameEq = name + '='; - const ca = document.cookie.split(';'); - for (let c of ca) { - while (c.charAt(0) === ' ') { - c = c.substring(1, c.length); - } - if (c.indexOf(nameEq) === 0) { - return c.substring(nameEq.length, c.length); - } - } - return null; - } - public loadUserSession() { - return CookiePersister.readCookie(config.cookieName); - } - public saveUserSession(userSession: string, daysToLive: number) { - CookiePersister.createCookie(config.cookieName, userSession, daysToLive); - } -} diff --git a/src/index.ts b/src/index.ts index 5f36f41..c520121 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,4 +1,3 @@ -import { CookiePersister } from './cookiePersister'; import { InMemoryPersister } from './inMemoryPersister'; import { config, @@ -14,7 +13,7 @@ import { } from './main'; import { SplitTest } from './splitTest'; import { uiFactory } from './ui'; -import { UserSessionPersister } from './userSessionPersister'; +import { CookiePersister, UserSessionPersister } from './userSessionPersister'; const ui = uiFactory( testsObservable, diff --git a/src/userSessionPersister.ts b/src/userSessionPersister.ts index bbdf19b..ebc03ff 100644 --- a/src/userSessionPersister.ts +++ b/src/userSessionPersister.ts @@ -3,3 +3,33 @@ export interface UserSessionPersister { loadUserSession(): string | null; saveUserSession(userSession: string, daysToLive: number): void; } +export class CookiePersister implements UserSessionPersister { + private static createCookie(name: string, value: string, days: number): void { + let expires = ''; + if (days) { + const date = new Date(); + date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000)); + expires = '; expires=' + date.toUTCString(); + } + document.cookie = name + '=' + value + expires + '; path=/'; + } + private static readCookie(name: string): string | null { + const nameEq = name + '='; + const ca = document.cookie.split(';'); + for (let c of ca) { + while (c.charAt(0) === ' ') { + c = c.substring(1, c.length); + } + if (c.indexOf(nameEq) === 0) { + return c.substring(nameEq.length, c.length); + } + } + return null; + } + public loadUserSession() { + return CookiePersister.readCookie(config.cookieName); + } + public saveUserSession(userSession: string, daysToLive: number) { + CookiePersister.createCookie(config.cookieName, userSession, daysToLive); + } +}