@naturalcycles/abba 2.7.2 → 2.8.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/abba.d.ts CHANGED
@@ -31,7 +31,7 @@ export declare class Abba {
31
31
  * Update experiment information, will also validate the buckets' ratio if experiment.active is true
32
32
  * Cold method.
33
33
  */
34
- saveExperiment(experiment: Experiment, buckets: Unsaved<Bucket>[]): Promise<ExperimentWithBuckets>;
34
+ saveExperiment(experiment: Experiment, buckets: (Unsaved<Bucket> | BucketInput)[]): Promise<ExperimentWithBuckets>;
35
35
  private updateExclusions;
36
36
  softDeleteExperiment(experimentId: string): Promise<void>;
37
37
  /**
package/dist/abba.js CHANGED
@@ -15,10 +15,6 @@ import { canGenerateNewAssignments, generateUserAssignmentData, getUserExclusion
15
15
  */
16
16
  const CACHE_TTL = 600_000;
17
17
  export class Abba {
18
- cfg;
19
- experimentDao;
20
- bucketDao;
21
- userAssignmentDao;
22
18
  constructor(cfg) {
23
19
  this.cfg = cfg;
24
20
  this.experimentDao = experimentDao(cfg.db);
@@ -72,7 +68,7 @@ export class Abba {
72
68
  async mergeAssignmentsForUserIds(fromUserId, intoUserId) {
73
69
  const fromAssignments = await this.userAssignmentDao.getBy('userId', fromUserId);
74
70
  const existingIntoAssignments = await this.userAssignmentDao.getBy('userId', intoUserId);
75
- await pMap(fromAssignments, async from => {
71
+ await pMap(fromAssignments, async (from) => {
76
72
  if (!existingIntoAssignments.some(into => into.experimentId === from.experimentId)) {
77
73
  await this.userAssignmentDao.patch(from, { userId: intoUserId });
78
74
  }
@@ -109,7 +105,7 @@ export class Abba {
109
105
  validateTotalBucketRatio(buckets);
110
106
  }
111
107
  const updatedExperiment = await this.experimentDao.save(experiment, { saveMethod: 'update' });
112
- const updatedBuckets = await pMap(buckets, async bucket => {
108
+ const updatedBuckets = await pMap(buckets, async (bucket) => {
113
109
  return await this.bucketDao.save({ ...bucket, experimentId: updatedExperiment.id }, { saveMethod: bucket.id ? 'update' : undefined });
114
110
  });
115
111
  await this.updateExclusions(updatedExperiment.id, updatedExperiment.exclusions);
@@ -221,7 +217,7 @@ export class Abba {
221
217
  */
222
218
  async getAllExistingUserAssignments(userId) {
223
219
  const assignments = await this.userAssignmentDao.getBy('userId', userId);
224
- return await pMap(assignments, async assignment => {
220
+ return await pMap(assignments, async (assignment) => {
225
221
  const experiment = await this.experimentDao.requireById(assignment.experimentId);
226
222
  const bucket = await this.bucketDao.getById(assignment.bucketId);
227
223
  return {
@@ -288,7 +284,7 @@ export class Abba {
288
284
  async getExperimentAssignmentStatistics(experimentId) {
289
285
  const totalAssignments = await this.userAssignmentDao.getCountByExperimentId(experimentId);
290
286
  const buckets = await this.bucketDao.getByExperimentId(experimentId);
291
- const bucketAssignments = await pMap(buckets, async bucket => {
287
+ const bucketAssignments = await pMap(buckets, async (bucket) => {
292
288
  const totalAssignments = await this.userAssignmentDao.getCountByBucketId(bucket.id);
293
289
  return {
294
290
  bucketId: bucket.id,
@@ -19,11 +19,7 @@ export function experimentDao(db) {
19
19
  beforeBMToDBM: bm => ({
20
20
  ...bm,
21
21
  rules: bm.rules.length ? JSON.stringify(bm.rules) : null,
22
- // We add the map here to account for backwards compatibility where exclusion experimentIds were stored as a number
23
- // TODO: Remove after some time when we are certain only strings are stored
24
- exclusions: bm.exclusions.length
25
- ? JSON.stringify(bm.exclusions.map(exclusion => exclusion.toString()))
26
- : null,
22
+ exclusions: bm.exclusions.length ? JSON.stringify(bm.exclusions) : null,
27
23
  data: bm.data ? JSON.stringify(bm.data) : null,
28
24
  }),
29
25
  beforeDBMToBM: dbm => ({
@@ -31,11 +27,7 @@ export function experimentDao(db) {
31
27
  startDateIncl: parseMySQLDate(dbm.startDateIncl),
32
28
  endDateExcl: parseMySQLDate(dbm.endDateExcl),
33
29
  rules: (dbm.rules && JSON.parse(dbm.rules)) || [],
34
- // We add the map here to account for backwards compatibility where exclusion experimentIds were stored as a number
35
- // TODO: Remove after some time when we are certain only strings are stored
36
- exclusions: (dbm.exclusions &&
37
- JSON.parse(dbm.exclusions).map((exclusion) => exclusion.toString())) ||
38
- [],
30
+ exclusions: (dbm.exclusions && JSON.parse(dbm.exclusions)) || [],
39
31
  data: dbm.data ? JSON.parse(dbm.data) : null,
40
32
  }),
41
33
  },
package/dist/types.js CHANGED
@@ -1,5 +1,4 @@
1
- export { AssignmentStatus };
2
- var AssignmentStatus;
1
+ export var AssignmentStatus;
3
2
  (function (AssignmentStatus) {
4
3
  /**
5
4
  * Will return existing assignments and generate new assignments
@@ -14,8 +13,7 @@ var AssignmentStatus;
14
13
  */
15
14
  AssignmentStatus[AssignmentStatus["Inactive"] = 3] = "Inactive";
16
15
  })(AssignmentStatus || (AssignmentStatus = {}));
17
- export { SegmentationRuleOperator };
18
- var SegmentationRuleOperator;
16
+ export var SegmentationRuleOperator;
19
17
  (function (SegmentationRuleOperator) {
20
18
  SegmentationRuleOperator["IsSet"] = "isSet";
21
19
  SegmentationRuleOperator["IsNotSet"] = "isNotSet";
package/dist/util.js CHANGED
@@ -93,12 +93,15 @@ export const segmentationRuleMap = {
93
93
  return !keyValue;
94
94
  },
95
95
  [SegmentationRuleOperator.EqualsText](keyValue, ruleValue) {
96
+ // oxlint-disable-next-line typescript/no-unnecessary-type-conversion
96
97
  return keyValue?.toString() === ruleValue.toString();
97
98
  },
98
99
  [SegmentationRuleOperator.NotEqualsText](keyValue, ruleValue) {
100
+ // oxlint-disable-next-line typescript/no-unnecessary-type-conversion
99
101
  return keyValue?.toString() !== ruleValue.toString();
100
102
  },
101
103
  [SegmentationRuleOperator.Semver](keyValue, ruleValue) {
104
+ // oxlint-disable-next-line typescript/no-unnecessary-type-conversion
102
105
  return satisfies(keyValue?.toString() || '', ruleValue.toString());
103
106
  },
104
107
  [SegmentationRuleOperator.Regex](keyValue, ruleValue) {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@naturalcycles/abba",
3
3
  "type": "module",
4
- "version": "2.7.2",
4
+ "version": "2.8.0",
5
5
  "dependencies": {
6
6
  "@naturalcycles/db-lib": "^10",
7
7
  "@naturalcycles/js-lib": "^15",
@@ -11,8 +11,8 @@
11
11
  },
12
12
  "devDependencies": {
13
13
  "@types/semver": "^7",
14
- "@typescript/native-preview": "7.0.0-dev.20260301.1",
15
- "@naturalcycles/dev-lib": "18.4.2"
14
+ "@typescript/native-preview": "7.0.0-dev.20260401.1",
15
+ "@naturalcycles/dev-lib": "20.42.0"
16
16
  },
17
17
  "exports": {
18
18
  ".": "./dist/index.js"
package/src/abba.ts CHANGED
@@ -157,7 +157,7 @@ export class Abba {
157
157
  */
158
158
  async saveExperiment(
159
159
  experiment: Experiment,
160
- buckets: Unsaved<Bucket>[],
160
+ buckets: (Unsaved<Bucket> | BucketInput)[],
161
161
  ): Promise<ExperimentWithBuckets> {
162
162
  if (experiment.status === AssignmentStatus.Active) {
163
163
  validateTotalBucketRatio(buckets)
@@ -26,11 +26,7 @@ export function experimentDao(db: CommonDB): ExperimentDao {
26
26
  beforeBMToDBM: bm => ({
27
27
  ...bm,
28
28
  rules: bm.rules.length ? JSON.stringify(bm.rules) : null,
29
- // We add the map here to account for backwards compatibility where exclusion experimentIds were stored as a number
30
- // TODO: Remove after some time when we are certain only strings are stored
31
- exclusions: bm.exclusions.length
32
- ? JSON.stringify(bm.exclusions.map(exclusion => exclusion.toString()))
33
- : null,
29
+ exclusions: bm.exclusions.length ? JSON.stringify(bm.exclusions) : null,
34
30
  data: bm.data ? JSON.stringify(bm.data) : null,
35
31
  }),
36
32
  beforeDBMToBM: dbm => ({
@@ -38,12 +34,7 @@ export function experimentDao(db: CommonDB): ExperimentDao {
38
34
  startDateIncl: parseMySQLDate(dbm.startDateIncl),
39
35
  endDateExcl: parseMySQLDate(dbm.endDateExcl),
40
36
  rules: (dbm.rules && JSON.parse(dbm.rules)) || [],
41
- // We add the map here to account for backwards compatibility where exclusion experimentIds were stored as a number
42
- // TODO: Remove after some time when we are certain only strings are stored
43
- exclusions:
44
- (dbm.exclusions &&
45
- JSON.parse(dbm.exclusions).map((exclusion: string | number) => exclusion.toString())) ||
46
- [],
37
+ exclusions: (dbm.exclusions && JSON.parse(dbm.exclusions)) || [],
47
38
  data: dbm.data ? JSON.parse(dbm.data) : null,
48
39
  }),
49
40
  },
package/src/util.ts CHANGED
@@ -124,12 +124,15 @@ export const segmentationRuleMap: Record<SegmentationRuleOperator, SegmentationR
124
124
  return !keyValue
125
125
  },
126
126
  [SegmentationRuleOperator.EqualsText](keyValue, ruleValue) {
127
+ // oxlint-disable-next-line typescript/no-unnecessary-type-conversion
127
128
  return keyValue?.toString() === ruleValue.toString()
128
129
  },
129
130
  [SegmentationRuleOperator.NotEqualsText](keyValue, ruleValue) {
131
+ // oxlint-disable-next-line typescript/no-unnecessary-type-conversion
130
132
  return keyValue?.toString() !== ruleValue.toString()
131
133
  },
132
134
  [SegmentationRuleOperator.Semver](keyValue, ruleValue) {
135
+ // oxlint-disable-next-line typescript/no-unnecessary-type-conversion
133
136
  return satisfies(keyValue?.toString() || '', ruleValue.toString())
134
137
  },
135
138
  [SegmentationRuleOperator.Regex](keyValue, ruleValue) {