@naturalcycles/abba 1.20.0 → 1.21.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.
- package/package.json +1 -1
- package/readme.md +0 -326
package/package.json
CHANGED
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>
|