Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main' into feat/analytics_clickh…
Browse files Browse the repository at this point in the history
…ouse_db
  • Loading branch information
Tim-53 committed Jul 20, 2024
2 parents 9431e15 + da5695d commit 1e07e39
Show file tree
Hide file tree
Showing 29 changed files with 196 additions and 43 deletions.
7 changes: 7 additions & 0 deletions apps/angular-example/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# angular-example

## 0.0.18

### Patch Changes

- @tryabby/angular@2.0.8
- @tryabby/devtools@5.0.1

## 0.0.17

### Patch Changes
Expand Down
2 changes: 1 addition & 1 deletion apps/angular-example/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "angular-example",
"version": "0.0.17",
"version": "0.0.18",
"private": true,
"scripts": {
"ng": "ng",
Expand Down
9 changes: 9 additions & 0 deletions apps/web/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
# web

## 0.2.36

### Patch Changes

- Updated dependencies [31d14b7]
- @tryabby/core@5.3.0
- @tryabby/next@5.1.1
- @tryabby/devtools@5.0.1

## 0.2.35

### Patch Changes
Expand Down
1 change: 1 addition & 0 deletions apps/web/abby.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,6 @@ export default defineConfig(
remoteConfig: {
abc: "JSON",
},
cookies: { disableByDefault: true, expiresInDays: 30 },
}
);
2 changes: 1 addition & 1 deletion apps/web/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "web",
"version": "0.2.35",
"version": "0.2.36",
"private": true,
"scripts": {
"build": "next build",
Expand Down
1 change: 1 addition & 0 deletions apps/web/src/components/Pricing.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ function PricingElement({
<Fragment key={feature}>
<AiOutlineCheckCircle className={clsx("text-xl")} />
<span
suppressHydrationWarning
className={clsx(
"flex items-center",
i === 0 ? "font-semibold" : "te"
Expand Down
1 change: 1 addition & 0 deletions apps/web/src/pages/devtools.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ const { useAbby, AbbyProvider, useFeatureFlag, withDevtools, __abby__ } =
},
},
flags: ["ToggleMeIfYoureExcited", "showEasterEgg", "showHeading"],
cookies: { disableByDefault: true, expiresInDays: 30 },
});

export const AbbyProdDevtools = withDevtools(abbyDevtools, {
Expand Down
1 change: 1 addition & 0 deletions apps/web/src/pages/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ const { useAbby, AbbyProvider, useFeatureFlag, __abby__, withDevtools } =
},
},
flags: ["ForceDarkTheme"],
cookies: { disableByDefault: true, expiresInDays: 30 },
});

const Devtools = withDevtools(DevtoolsFactory, {
Expand Down
5 changes: 1 addition & 4 deletions apps/web/src/server/trpc/router/flags.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ export const flagRouter = router({
},
},
},
orderBy: { createdAt: "asc" },
include: {
values: { include: { environment: true } },
},
Expand Down Expand Up @@ -161,7 +162,6 @@ export const flagRouter = router({
include: {
project: {
include: { environments: { select: { name: true } } },
select: { id: true },
},
},
});
Expand Down Expand Up @@ -278,9 +278,6 @@ export const flagRouter = router({
select: { name: true },
},
},
select: {
id: true,
},
},
},
});
Expand Down
7 changes: 7 additions & 0 deletions packages/angular/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# @tryabby/angular

## 2.0.8

### Patch Changes

- Updated dependencies [31d14b7]
- @tryabby/core@5.3.0

## 2.0.7

### Patch Changes
Expand Down
2 changes: 1 addition & 1 deletion packages/angular/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@tryabby/angular",
"version": "2.0.7",
"version": "2.0.8",
"scripts": {
"ng": "ng",
"start": "ng serve",
Expand Down
6 changes: 6 additions & 0 deletions packages/core/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# @tryabby/core

## 5.3.0

### Minor Changes

- 31d14b7: add cookie consent options

## 5.2.0

### Minor Changes
Expand Down
2 changes: 1 addition & 1 deletion packages/core/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@tryabby/core",
"version": "5.2.0",
"version": "5.3.0",
"description": "",
"main": "dist/index.js",
"files": [
Expand Down
63 changes: 59 additions & 4 deletions packages/core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,11 @@ import {
ABBY_RC_STORAGE_PREFIX,
remoteConfigStringToType,
ABBY_WINDOW_KEY,
StorageServiceOptions,
} from "./shared/";
import { HttpService } from "./shared";
import { F, O } from "ts-toolbelt";
import { getWeightedRandomVariant } from "./mathHelpers";
import { F } from "ts-toolbelt";
import { getVariantWithHeighestWeightOrFirst, getWeightedRandomVariant } from "./mathHelpers";
import { parseCookies } from "./helpers";

export * from "./shared/index";
Expand Down Expand Up @@ -72,7 +73,7 @@ type LocalData<

interface PersistentStorage {
get: (key: string) => string | null;
set: (key: string, value: string) => void;
set: (key: string, value: string, options?: StorageServiceOptions) => void;
}

export type AbbyConfig<
Expand All @@ -95,6 +96,10 @@ export type AbbyConfig<
settings?: Settings<F.NoInfer<FlagName>, F.NoInfer<RemoteConfigName>, F.NoInfer<RemoteConfig>>;
debug?: boolean;
fetch?: (typeof globalThis)["fetch"];
cookies?: {
disableByDefault?: boolean;
expiresInDays?: number;
};
__experimentalCdnUrl?: string;
};

Expand Down Expand Up @@ -125,6 +130,8 @@ export class Abby<
private testOverrides: Map<keyof Tests, Tests[keyof Tests]["variants"][number]> = new Map();
private remoteConfigOverrides = new Map<string, RemoteConfigValue>();

private COOKIE_CONSENT_KEY = "$_abcc_$";

constructor(
private config: F.Narrow<
AbbyConfig<FlagName, Tests, Environments, RemoteConfigName, RemoteConfig>
Expand Down Expand Up @@ -153,6 +160,17 @@ export class Abby<
},
{} as Record<RemoteConfigName, RemoteConfigValue>
);

if (persistantTestStorage) {
this.persistantTestStorage = {
get: (...args) => persistantTestStorage.get(...args),
set: (...args) => {
if (config.cookies?.disableByDefault) return;
const [key, value] = args;
persistantTestStorage.set(key, value, { expiresInDays: config.cookies?.expiresInDays });
},
};
}
}

/**
Expand Down Expand Up @@ -425,7 +443,9 @@ export class Abby<

return persistedValue;
}

if (this.config.cookies?.disableByDefault) {
return getVariantWithHeighestWeightOrFirst(variants, weights);
}
const weightedVariant = getWeightedRandomVariant(variants, weights);
this.persistantTestStorage?.set(key as string, weightedVariant);

Expand Down Expand Up @@ -531,6 +551,13 @@ export class Abby<
""
);

// special case for the cookie consent
if (testName === this.COOKIE_CONSENT_KEY) {
this.config.cookies ??= {};
this.config.cookies.disableByDefault = cookieValue !== "true";
return;
}

this.testOverrides.set(testName as TestName, cookieValue);
this.persistantTestStorage?.set(testName as TestName, cookieValue);
}
Expand Down Expand Up @@ -604,4 +631,32 @@ export class Abby<
value: RemoteConfigValueStringToType<RemoteConfig[RemoteConfigName]>;
}>;
}

/**
* Enables the usage of cookies for the storage of user data
* and also sets the cookies if possible
*/
enableCookies() {
this.config.cookies ??= {};
this.config.cookies.disableByDefault = false;
this.persistantTestStorage?.set(this.COOKIE_CONSENT_KEY, "true");

Object.keys(this.#data.tests).forEach((testName) => {
this.persistantTestStorage?.set(testName, this.getTestVariant(testName as TestName));
});
}

/**
* Disables the usage of cookies for storage of user data
* and also removes all set cookies if possible
*/
disableCookies() {
this.config.cookies ??= {};
this.config.cookies.disableByDefault = true;
this.persistantTestStorage?.set(this.COOKIE_CONSENT_KEY, "false");

Object.keys(this.#data.tests).forEach((testName) => {
this.persistantTestStorage?.set(testName, this.getTestVariant(testName as TestName));
});
}
}
48 changes: 31 additions & 17 deletions packages/core/src/mathHelpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,7 @@ function getRandomDecimal() {
return Math.random();
}

function getWeightedRandomNumber<T extends Record<string, number>>(
spec: T
): keyof T {
function getWeightedRandomNumber<T extends Record<string, number>>(spec: T): keyof T {
let i: keyof T;
let sum = 0;
const r = getRandomDecimal();
Expand All @@ -27,32 +25,48 @@ function getWeightedRandomNumber<T extends Record<string, number>>(
return i!;
}

function getDefaultWeights<Variants extends ReadonlyArray<string>>(
variants: Variants
) {
return Array.from<number>({ length: variants.length }).fill(
1 / variants.length
);
function getDefaultWeights<Variants extends ReadonlyArray<string>>(variants: Variants) {
return Array.from<number>({ length: variants.length }).fill(1 / variants.length);
}

export function validateWeights<
Variants extends ReadonlyArray<string>,
Weights extends Array<number>
Weights extends Array<number>,
>(variants: Variants, weights?: Weights): Weights {
const sum = weights?.reduce((acc, weight) => acc + weight, 0);
return weights != null && sum === 1 && variants.length === weights.length
? weights
: (getDefaultWeights(variants) as Weights);
}

export function getWeightedRandomVariant<
Variants extends ReadonlyArray<string>
>(variants: Variants, weights?: Array<number>): Variants[number] {
export function getWeightedRandomVariant<Variants extends ReadonlyArray<string>>(
variants: Variants,
weights?: Array<number>
): Variants[number] {
const validatedWeights = validateWeights(variants, weights);
return getWeightedRandomNumber(
variants.reduce((acc, variant, index) => {
acc[variant as Variants[number]] = validatedWeights[index];
return acc;
}, {} as Record<Variants[number], number>)
variants.reduce(
(acc, variant, index) => {
acc[variant as Variants[number]] = validatedWeights[index];
return acc;
},
{} as Record<Variants[number], number>
)
);
}

export function getVariantWithHeighestWeightOrFirst<Variants extends ReadonlyArray<string>>(
variants: Variants,
weights?: Array<number>
): Variants[number] {
const validatedWeights = validateWeights(variants, weights);
let variantWithHeighestWeight = variants[0];

for (let i = 1; i < variants.length; i++) {
if (validatedWeights[i] > validatedWeights[i - 1]) {
variantWithHeighestWeight = variants[i];
}
}

return variantWithHeighestWeight;
}
6 changes: 5 additions & 1 deletion packages/core/src/shared/interfaces.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
export interface StorageServiceOptions {
expiresInDays?: number;
}

export interface IStorageService {
get(projectId: string, key: string): string | null;
set(projectId: string, key: string, value: string): void;
set(projectId: string, key: string, value: string, options?: StorageServiceOptions): void;
remove(projectId: string, key: string): void;
}
7 changes: 7 additions & 0 deletions packages/next/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# @tryabby/next

## 5.1.1

### Patch Changes

- Updated dependencies [31d14b7]
- @tryabby/react@5.2.0

## 5.1.0

### Minor Changes
Expand Down
2 changes: 1 addition & 1 deletion packages/next/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@tryabby/next",
"version": "5.1.0",
"version": "5.1.1",
"description": "",
"main": "dist/index.js",
"files": [
Expand Down
7 changes: 7 additions & 0 deletions packages/node/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# @tryabby/node

## 5.1.6

### Patch Changes

- Updated dependencies [31d14b7]
- @tryabby/core@5.3.0

## 5.1.5

### Patch Changes
Expand Down
2 changes: 1 addition & 1 deletion packages/node/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@tryabby/node",
"version": "5.1.5",
"version": "5.1.6",
"description": "",
"main": "dist/index.js",
"files": [
Expand Down
Loading

0 comments on commit 1e07e39

Please sign in to comment.