@naturalcycles/abba 1.14.0 → 1.15.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/dist/dao/experiment.dao.js +14 -0
- package/dist/types.d.ts +3 -3
- package/dist/util.js +5 -1
- package/package.json +1 -1
- package/src/dao/experiment.dao.ts +14 -1
- package/src/types.ts +3 -3
- package/src/util.ts +5 -5
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.experimentDao = exports.ExperimentDao = void 0;
|
|
4
4
|
const db_lib_1 = require("@naturalcycles/db-lib");
|
|
5
|
+
const js_lib_1 = require("@naturalcycles/js-lib");
|
|
5
6
|
class ExperimentDao extends db_lib_1.CommonDao {
|
|
6
7
|
}
|
|
7
8
|
exports.ExperimentDao = ExperimentDao;
|
|
@@ -19,9 +20,22 @@ const experimentDao = (db) => new ExperimentDao({
|
|
|
19
20
|
}),
|
|
20
21
|
beforeDBMToBM: dbm => ({
|
|
21
22
|
...dbm,
|
|
23
|
+
startDateIncl: parseMySQLDate(dbm.startDateIncl),
|
|
24
|
+
endDateExcl: parseMySQLDate(dbm.endDateExcl),
|
|
22
25
|
rules: (dbm.rules && JSON.parse(dbm.rules)) || [],
|
|
23
26
|
exclusions: (dbm.exclusions && JSON.parse(dbm.exclusions)) || [],
|
|
24
27
|
}),
|
|
25
28
|
},
|
|
26
29
|
});
|
|
27
30
|
exports.experimentDao = experimentDao;
|
|
31
|
+
/**
|
|
32
|
+
* https://nc1.slack.com/archives/CCNTHJT7V/p1682514277002739
|
|
33
|
+
* MySQL Automatically parses Date fields as Date objects
|
|
34
|
+
* For simplicity let's not do that by having this function...
|
|
35
|
+
*/
|
|
36
|
+
function parseMySQLDate(date) {
|
|
37
|
+
// @ts-expect-error
|
|
38
|
+
if (date instanceof Date)
|
|
39
|
+
return (0, js_lib_1.localDate)(date).toISODate();
|
|
40
|
+
return date;
|
|
41
|
+
}
|
package/dist/types.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { CommonDB } from '@naturalcycles/db-lib';
|
|
2
|
-
import { AnyObject, BaseDBEntity, Saved } from '@naturalcycles/js-lib';
|
|
2
|
+
import { AnyObject, BaseDBEntity, IsoDateString, Saved } from '@naturalcycles/js-lib';
|
|
3
3
|
export interface AbbaConfig {
|
|
4
4
|
db: CommonDB;
|
|
5
5
|
}
|
|
@@ -8,8 +8,8 @@ export type BaseExperiment = BaseDBEntity<number> & {
|
|
|
8
8
|
status: number;
|
|
9
9
|
sampling: number;
|
|
10
10
|
description: string | null;
|
|
11
|
-
startDateIncl:
|
|
12
|
-
endDateExcl:
|
|
11
|
+
startDateIncl: IsoDateString;
|
|
12
|
+
endDateExcl: IsoDateString;
|
|
13
13
|
};
|
|
14
14
|
export type Experiment = BaseExperiment & {
|
|
15
15
|
rules: SegmentationRule[];
|
package/dist/util.js
CHANGED
|
@@ -116,7 +116,7 @@ exports.validateSegmentationRule = validateSegmentationRule;
|
|
|
116
116
|
const canGenerateNewAssignments = (experiment, exclusionSet) => {
|
|
117
117
|
return (!exclusionSet.has(experiment.id) &&
|
|
118
118
|
experiment.status === types_1.AssignmentStatus.Active &&
|
|
119
|
-
(0, js_lib_1.localDate)().isBetween(
|
|
119
|
+
(0, js_lib_1.localDate)().isBetween(experiment.startDateIncl, experiment.endDateExcl, '[)'));
|
|
120
120
|
};
|
|
121
121
|
exports.canGenerateNewAssignments = canGenerateNewAssignments;
|
|
122
122
|
/**
|
|
@@ -126,6 +126,10 @@ exports.canGenerateNewAssignments = canGenerateNewAssignments;
|
|
|
126
126
|
const getUserExclusionSet = (experiments, existingAssignments) => {
|
|
127
127
|
const exclusionSet = new Set();
|
|
128
128
|
existingAssignments.forEach(assignment => {
|
|
129
|
+
// Users who are excluded from an experiment due to sampling
|
|
130
|
+
// should not prevent potential assignment to other mutually exclusive experiments
|
|
131
|
+
if (assignment.bucketId === null)
|
|
132
|
+
return;
|
|
129
133
|
const experiment = experiments.find(e => e.id === assignment.experimentId);
|
|
130
134
|
experiment?.exclusions.forEach(experimentId => exclusionSet.add(experimentId));
|
|
131
135
|
});
|
package/package.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { CommonDao, CommonDB } from '@naturalcycles/db-lib'
|
|
2
|
-
import { Saved } from '@naturalcycles/js-lib'
|
|
2
|
+
import { IsoDateString, localDate, Saved } from '@naturalcycles/js-lib'
|
|
3
3
|
import { BaseExperiment, Experiment } from '../types'
|
|
4
4
|
|
|
5
5
|
type ExperimentDBM = Saved<BaseExperiment> & {
|
|
@@ -24,8 +24,21 @@ export const experimentDao = (db: CommonDB): ExperimentDao =>
|
|
|
24
24
|
}),
|
|
25
25
|
beforeDBMToBM: dbm => ({
|
|
26
26
|
...dbm,
|
|
27
|
+
startDateIncl: parseMySQLDate(dbm.startDateIncl),
|
|
28
|
+
endDateExcl: parseMySQLDate(dbm.endDateExcl),
|
|
27
29
|
rules: (dbm.rules && JSON.parse(dbm.rules)) || [],
|
|
28
30
|
exclusions: (dbm.exclusions && JSON.parse(dbm.exclusions)) || [],
|
|
29
31
|
}),
|
|
30
32
|
},
|
|
31
33
|
})
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* https://nc1.slack.com/archives/CCNTHJT7V/p1682514277002739
|
|
37
|
+
* MySQL Automatically parses Date fields as Date objects
|
|
38
|
+
* For simplicity let's not do that by having this function...
|
|
39
|
+
*/
|
|
40
|
+
function parseMySQLDate(date: string): IsoDateString {
|
|
41
|
+
// @ts-expect-error
|
|
42
|
+
if (date instanceof Date) return localDate(date).toISODate()
|
|
43
|
+
return date
|
|
44
|
+
}
|
package/src/types.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { CommonDB } from '@naturalcycles/db-lib'
|
|
2
|
-
import { AnyObject, BaseDBEntity, Saved } from '@naturalcycles/js-lib'
|
|
2
|
+
import { AnyObject, BaseDBEntity, IsoDateString, Saved } from '@naturalcycles/js-lib'
|
|
3
3
|
|
|
4
4
|
export interface AbbaConfig {
|
|
5
5
|
db: CommonDB
|
|
@@ -10,8 +10,8 @@ export type BaseExperiment = BaseDBEntity<number> & {
|
|
|
10
10
|
status: number
|
|
11
11
|
sampling: number
|
|
12
12
|
description: string | null
|
|
13
|
-
startDateIncl:
|
|
14
|
-
endDateExcl:
|
|
13
|
+
startDateIncl: IsoDateString
|
|
14
|
+
endDateExcl: IsoDateString
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
export type Experiment = BaseExperiment & {
|
package/src/util.ts
CHANGED
|
@@ -136,11 +136,7 @@ export const canGenerateNewAssignments = (
|
|
|
136
136
|
return (
|
|
137
137
|
!exclusionSet.has(experiment.id) &&
|
|
138
138
|
experiment.status === AssignmentStatus.Active &&
|
|
139
|
-
localDate().isBetween(
|
|
140
|
-
localDate(experiment.startDateIncl.toISOString()),
|
|
141
|
-
localDate(experiment.endDateExcl.toISOString()),
|
|
142
|
-
'[)',
|
|
143
|
-
)
|
|
139
|
+
localDate().isBetween(experiment.startDateIncl, experiment.endDateExcl, '[)')
|
|
144
140
|
)
|
|
145
141
|
}
|
|
146
142
|
|
|
@@ -154,6 +150,10 @@ export const getUserExclusionSet = (
|
|
|
154
150
|
): ExclusionSet => {
|
|
155
151
|
const exclusionSet: ExclusionSet = new Set()
|
|
156
152
|
existingAssignments.forEach(assignment => {
|
|
153
|
+
// Users who are excluded from an experiment due to sampling
|
|
154
|
+
// should not prevent potential assignment to other mutually exclusive experiments
|
|
155
|
+
if (assignment.bucketId === null) return
|
|
156
|
+
|
|
157
157
|
const experiment = experiments.find(e => e.id === assignment.experimentId)
|
|
158
158
|
experiment?.exclusions.forEach(experimentId => exclusionSet.add(experimentId))
|
|
159
159
|
})
|