@naturalcycles/abba 1.20.0 → 1.22.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -4,6 +4,7 @@ CREATE TABLE IF NOT EXISTS `Bucket` (
4
4
  `experimentId` VARCHAR(50) NOT NULL,
5
5
  `key` VARCHAR(10) NOT NULL,
6
6
  `ratio` INTEGER NOT NULL,
7
+ 'data' JSON NULL,
7
8
  `created` INT NOT NULL,
8
9
  `updated` INT NOT NULL,
9
10
 
package/dist/types.d.ts CHANGED
@@ -41,6 +41,7 @@ export type Bucket = BaseDBEntity & {
41
41
  experimentId: string;
42
42
  key: string;
43
43
  ratio: number;
44
+ data: AnyObject | null;
44
45
  };
45
46
  export type UserAssignment = BaseDBEntity & {
46
47
  userId: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@naturalcycles/abba",
3
- "version": "1.20.0",
3
+ "version": "1.22.0",
4
4
  "scripts": {
5
5
  "prepare": "husky"
6
6
  },
@@ -4,6 +4,7 @@ CREATE TABLE IF NOT EXISTS `Bucket` (
4
4
  `experimentId` VARCHAR(50) NOT NULL,
5
5
  `key` VARCHAR(10) NOT NULL,
6
6
  `ratio` INTEGER NOT NULL,
7
+ 'data' JSON NULL,
7
8
  `created` INT NOT NULL,
8
9
  `updated` INT NOT NULL,
9
10
 
package/src/types.ts CHANGED
@@ -46,6 +46,7 @@ export type Bucket = BaseDBEntity & {
46
46
  experimentId: string
47
47
  key: string
48
48
  ratio: number
49
+ data: AnyObject | null
49
50
  }
50
51
 
51
52
  export type UserAssignment = BaseDBEntity & {
package/readme.md DELETED
@@ -1,326 +0,0 @@
1
- <div id="top"></div>
2
-
3
- <!-- PROJECT LOGO -->
4
- <br />
5
- <div align="center">
6
- <h3 align="center">ABBA</h3>
7
-
8
- <p align="center">
9
- A tool for generating and persisting AB test assignments
10
- <br />
11
- </p>
12
- </div>
13
-
14
- <!-- TABLE OF CONTENTS -->
15
- <details>
16
- <summary>Table of Contents</summary>
17
- <ol>
18
- <li>
19
- <a href="#concepts">Concepts</a>
20
- </li>
21
- <li>
22
- <a href="#getting-started">Getting Started</a>
23
- <ul>
24
- <li><a href="#prerequisites">Prerequisites</a></li>
25
- <li><a href="#installation">Installation</a></li>
26
- </ul>
27
- </li>
28
- <li><a href="#usage">Usage</a></li>
29
- <li><a href="#segmentation">Segmentation</a></li>
30
- <li><a href="#experiment-status">Experiment / Assignment statuses</a></li>
31
- <li><a href="#exclusion">Mutual Exclusion</a></li>
32
- </ol>
33
- </details>
34
-
35
- <!-- CONCEPTS -->
36
-
37
- ## Concepts
38
-
39
- - **Experiment:** An individual experiment that will test a hypothesis
40
- - **Segmentation:** The target audience for the experiment
41
- - **Sampling:** Restrictions on what proportion of the target audience will be involved in the
42
- experiment
43
- - **Bucket:** An allocation that defines what variant of a particular experience the user will have
44
- - **Start/End dates:** The timeframe that assignments will be generated for this experiment when
45
- active
46
- - **Mutual Exclusion:**
47
- [See here](https://docs.developers.optimizely.com/full-stack-experimentation/docs/mutually-exclusive-experiments)
48
-
49
- <!-- BUILTWITH -->
50
-
51
- ### Built With
52
-
53
- - [@naturalcycles/db-lib](https://github.com/NaturalCycles/db-lib)
54
-
55
- <p align="right">(<a href="#top">back to top</a>)</p>
56
-
57
- <!-- GETTING STARTED -->
58
-
59
- ## Getting Started
60
-
61
- <div id="getting-started"></div>
62
-
63
- ### Prerequisites
64
-
65
- <div id="prerequisites"></div>
66
-
67
- - A running MYSQL instance
68
-
69
- ### Installation
70
-
71
- <div id="installation"></div>
72
-
73
- _Below is an example of how you can instruct your audience on installing and setting up your app.
74
- This template doesn't rely on any external dependencies or services._
75
-
76
- 1. Install NPM packages<br/>
77
-
78
- ```sh
79
- yarn add @naturalcyles/abba
80
-
81
- or
82
-
83
- npm install @naturalcyles/abba
84
- ```
85
-
86
- 2. Install the schema into your MySQL db instance using the migration script found
87
- [here](https://github.com/NaturalCycles/abba/blob/master/src/migrations/init.sql).
88
-
89
- <p align="right">(<a href="#top">back to top</a>)</p>
90
-
91
- <!-- USAGE EXAMPLES -->
92
-
93
- ## Usage
94
-
95
- <div id="usage"></div>
96
-
97
- ### Create an instance of Abba
98
-
99
- (Currently supports MySQL, probably all DocumentDBs but not verified.)
100
-
101
- ```js
102
- type AbbaConfig = {
103
- db: CommonDB // from @naturalcycles/db-lib
104
- }
105
-
106
- const abba = new Abba(config: AbbaConfig)
107
- ```
108
-
109
- ### Create a new experiment
110
-
111
- Creates a new experiment
112
-
113
- ```js
114
- async createExperiment(
115
- input: ExperimentInput,
116
- buckets: BucketInput[]
117
- ): Promise<Saved<Experiment>>
118
- ```
119
-
120
- ### Update an experiment
121
-
122
- Updates an existing experiment.
123
-
124
- ```js
125
- async updateExperiment(
126
- id: number,
127
- input: ExperimentInput,
128
- buckets: BucketInput[]
129
- ): Promise<Saved<Experiment>>
130
- ```
131
-
132
- ### Delete an experiment
133
-
134
- Delete an experiment. Removes all users assignments and buckets
135
-
136
- ```js
137
- async deleteExperiment(
138
- id: number
139
- ): Promise<void>
140
- ```
141
-
142
- ### Get all existing user assignments
143
-
144
- Gets all existing user assignments
145
-
146
- ```js
147
- async getAllExistingUserAssignments(
148
- userId: string
149
- ): Promise<Saved<UserAssignment>[]>
150
- ```
151
-
152
- ### Get a users assignment
153
-
154
- Get an assignment for a given user. If `existingOnly` is false, it will attempt generate a new
155
- assignment. `segmentationData` becomse required when `existingOnly` is false
156
-
157
- ```js
158
- async getUserAssignment(
159
- experimentId: number,
160
- userId: string,
161
- existingOnly: boolean,
162
- segmentationData?: SegmentationData,
163
- ): Promise<GeneratedUserAssignment | null>
164
- ```
165
-
166
- ### Generate user assignments
167
-
168
- Generate user assignments for all active experiments. Will return any existing assignments and
169
- attempt to generate new assignments.
170
-
171
- ```js
172
- async generateUserAssignments(
173
- userId: string,
174
- segmentationData: SegmentationData,
175
- ): Promise<GeneratedUserAssignment[]>
176
- ```
177
-
178
- ### Getting assignment statistics
179
-
180
- Get assignment statistics for an experiment.
181
-
182
- ```js
183
- async getExperimentAssignmentStatistics(
184
- experimentId: number
185
- ): Promise<AssignmentStatistics>
186
- ```
187
-
188
- <p align="right">(<a href="#top">back to top</a>)</p>
189
-
190
- ## Segmentation
191
-
192
- <div id="segmentation"></div>
193
-
194
- Experiments can be configured to target specific audiences using segmentation rules. When generating
195
- assignments it is possible to test these rules using user segmentation data which is an object
196
- containing key/value pairs unique to each user. (Allowed value types: `string`, `number`,
197
- `boolean`). A segmentation rule consist of the following properties:
198
-
199
- ```js
200
- key: string, // the key of the corresponding segmentationData property.
201
- operator: '==' | '!=' | 'semver' | 'regex' | 'boolean', // the operator that will be used to execute the rule
202
- value: string | number | boolean, // the value the operator will be executed against
203
- ```
204
-
205
- ## Segmentation rule operators
206
-
207
- ### Equals (==)
208
-
209
- Rule:
210
-
211
- ```js
212
- { key: 'country', operator: '==', value: 'SE }
213
- ```
214
-
215
- Example segmentation data:
216
-
217
- ```js
218
- {
219
- country: 'SE', // valid
220
- country: 'NO' // not valid
221
- }
222
- ```
223
-
224
- ### Not equals (!=)
225
-
226
- Rule:
227
-
228
- ```js
229
- { key: 'country', operator: '!=', value: 'SE' }
230
- ```
231
-
232
- Example segmentation data:
233
-
234
- ```js
235
- {
236
- country: 'NO', // valid
237
- country: 'SE' // not valid
238
- }
239
- ```
240
-
241
- ### Boolean (boolean)
242
-
243
- Rule:
244
-
245
- ```js
246
- { key: 'isEligible', operator: 'boolean', value: true }
247
- ```
248
-
249
- Example segmentation data:
250
-
251
- ```js
252
- {
253
- isEligible: true, // valid
254
- isEligible: false // not valid
255
- }
256
- ```
257
-
258
- ### Semver (semver)
259
-
260
- Rule:
261
-
262
- ```js
263
- { key: 'appVersion', operator: 'semver', value: '>1.1.0' }
264
- ```
265
-
266
- Example segmentation data:
267
-
268
- ```js
269
- {
270
- appVersion: '1.2.0', // valid
271
- appVersion: '1' // not valid
272
- }
273
- ```
274
-
275
- ### Regex (regex)
276
-
277
- Rule:
278
-
279
- ```js
280
- { key: 'country', operator: 'regex', value: 'SE|NO' }
281
- ```
282
-
283
- Example segmentation data:
284
-
285
- ```js
286
- {
287
- country: 'SE', // valid
288
- country: 'NO', // valid
289
- country: 'GB' // not valid
290
- }
291
- ```
292
-
293
- <p align="right">(<a href="#top">back to top</a>)</p>
294
-
295
- <div id="exclusion"></div>
296
-
297
- ## Experiment Status
298
-
299
- <div id="experiment-status"></div>
300
-
301
- ```js
302
- export enum AssignmentStatus {
303
- /**
304
- * Will return existing assignments and generate new assignments
305
- */
306
- Active = 1,
307
- /**
308
- * Will return existing assignments but not generate new assignments
309
- */
310
- Paused = 2,
311
- /**
312
- * Will not return any assignments
313
- */
314
- Inactive = 3,
315
- }
316
- ```
317
-
318
- <p align="right">(<a href="#top">back to top</a>)</p>
319
-
320
- ## Mutual Exclusion
321
-
322
- Mutual exclusion is configured per-experiment. If an experiment is listed as mutually exclusive with
323
- another experiment(s) then new assignments will only be generated with one of the experiments and
324
- will never be created for the other(s)
325
-
326
- <p align="right">(<a href="#top">back to top</a>)</p>