Proposal: frint-experiments for A/B testing and more...
- Dominant language
- JavaScript
- Stars
- 756
- Forks
- 33
- PR merge metrics
- No merged PRs in 30d
Description
(Intended to be done in a separate repositiory)
## What
Guidelines and API spec on how we can run experiments in the UI with FrintJS.
Extracted our usage out of the internal PoC we did recently.
/cc @AlexDudar, @juliamaksimchik, @discosultan, @viacheslaff
## Proposed packages
### `frint-experiments`
Will export:
* `ExperimentsService`
* will be set as a [provider](https://frint.js.org/docs/packages/frint/#understanding-providers) in Apps
* will provide access to the [collection](https://frint.js.org/docs/packages/frint-data/#collections)
* `ExperimentsCollection`: will contain the experiments data
* `Experiment`: Individual experiment item as a [model](https://frint.js.org/docs/packages/frint-data/#models)
* `createExperiments`: Generates a new configured `ExperimentsService` class
Example usage:
```js
import { createApp } from 'frint';
import { createExperiments } from 'frint-experiments';
const App = createApp({
name: 'MyApp',
providers: [
{
name: 'experiments',
useFactory() {
const ExperimentsService = createExperiments({
activate(model, attributes = {}) {
// implement activation logic
},
track(model, eventTags = {}) {
// implement tracking logic
},
});
return new ExperimentsService([]); // feed it with Experiments collection
}
}
]
});
```
The model can have this schema:
```js
// Experiment.js
import { createModel, Types } from 'frint-data';
export default createModel({
schema: {
name: Types.string,
variant: Types.string,
},
});
```
The service:
```js
class ExperimentsService {
constructor(experimentsArray) {
this.experiments = new ExperimentsCollection(experimentsArray);
}
findByName(name) {
return Experiment;
}
findByName$(name) {
return Observable;
}
activate(model, attributes = {}) {
}
track(model, eventTags = {}) {
}
}
```
### `frint-experiments-react`
This package will be exporting React components, for implementing our experiments at UI-level.
```js
import React from 'react';
import { Experiment, Variant } from 'frint-experiments-react';
export default function MyComponent(props) {
return (
'foo'} />
'bar'} />
'default'} />
);
}
```
`Experiment` component will receive either a `name` (`String`) or `model` (`Experiment`) as prop.
## Benefits
* Declarative experiments
* Always defined at code-level
* No external manipulation with JS code
* Can go for aggressive code-splitting at Component-level, so that users only download the code they need for their own experiments only
Contributor guide
Assessment
This issue has not been assessed yet.