make-mp-data 1.4.1 → 1.4.2

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/utils.js CHANGED
@@ -1,7 +1,7 @@
1
1
  const fs = require('fs');
2
2
  const Chance = require('chance');
3
3
  const readline = require('readline');
4
- const { comma, uid } = require('ak-tools');
4
+ const { comma, uid, clone } = require('ak-tools');
5
5
  const { spawn } = require('child_process');
6
6
  const dayjs = require('dayjs');
7
7
  const utc = require('dayjs/plugin/utc');
@@ -225,6 +225,7 @@ function integer(min = 1, max = 100) {
225
225
 
226
226
  function pickAWinner(items, mostChosenIndex) {
227
227
  const chance = getChance();
228
+ if (!mostChosenIndex) mostChosenIndex = integer(0, items.length);
228
229
  if (mostChosenIndex > items.length) mostChosenIndex = items.length;
229
230
  return function () {
230
231
  const weighted = [];
@@ -252,6 +253,48 @@ function pickAWinner(items, mostChosenIndex) {
252
253
  }
253
254
 
254
255
 
256
+ function inferFunnels(events) {
257
+ const createdFunnels = [];
258
+ const firstEvents = events.filter((e) => e.isFirstEvent).map((e) => e.event);
259
+ const usageEvents = events.filter((e) => !e.isFirstEvent).map((e) => e.event);
260
+ const numFunnelsToCreate = Math.ceil(usageEvents.length);
261
+ /** @type {Funnel} */
262
+ const funnelTemplate = {
263
+ sequence: [],
264
+ conversionRate: 50,
265
+ order: 'sequential',
266
+ requireRepeats: false,
267
+ props: {},
268
+ timeToConvert: 1,
269
+ isFirstFunnel: false,
270
+ weight: 1
271
+ };
272
+ if (firstEvents.length) {
273
+ for (const event of firstEvents) {
274
+ createdFunnels.push({ ...clone(funnelTemplate), sequence: [event], isFirstFunnel: true, conversionRate: 100 });
275
+ }
276
+ }
277
+
278
+ //at least one funnel with all usage events
279
+ createdFunnels.push({ ...clone(funnelTemplate), sequence: usageEvents });
280
+
281
+ //for the rest, make random funnels
282
+ followUpFunnels: for (let i = 1; i < numFunnelsToCreate; i++) {
283
+ /** @type {Funnel} */
284
+ const funnel = { ...clone(funnelTemplate) };
285
+ funnel.conversionRate = integer(25, 75);
286
+ funnel.timeToConvert = integer(1, 10);
287
+ funnel.weight = integer(1, 10);
288
+ const sequence = shuffleArray(usageEvents).slice(0, integer(2, usageEvents.length));
289
+ funnel.sequence = sequence;
290
+ funnel.order = 'random';
291
+ createdFunnels.push(funnel);
292
+ }
293
+
294
+ return createdFunnels;
295
+
296
+ }
297
+
255
298
  /*
256
299
  ----
257
300
  GENERATORS
@@ -274,7 +317,10 @@ function optimizedBoxMuller() {
274
317
  const chance = getChance();
275
318
  const u = Math.max(Math.min(chance.normal({ mean: .5, dev: .25 }), 1), 0);
276
319
  const v = Math.max(Math.min(chance.normal({ mean: .5, dev: .25 }), 1), 0);
277
- return Math.sqrt(-2.0 * Math.log(u)) * Math.cos(2.0 * Math.PI * v);
320
+ const result = Math.sqrt(-2.0 * Math.log(u)) * Math.cos(2.0 * Math.PI * v);
321
+ //ensure we didn't get infinity
322
+ if (result === Infinity || result === -Infinity) return chance.floating({ min: 0, max: 1 });
323
+ return result;
278
324
 
279
325
  }
280
326
 
@@ -769,31 +815,36 @@ function TimeSoup(earliestTime, latestTime, peaks = 5, deviation = 2, mean = 0)
769
815
 
770
816
 
771
817
  /**
818
+ * @param {string} userId
772
819
  * @param {number} bornDaysAgo=30
820
+ * @param {boolean} isAnonymous
773
821
  * @return {Person}
774
822
  */
775
- function person(bornDaysAgo = 30) {
823
+ function person(userId, bornDaysAgo = 30, isAnonymous = false) {
776
824
  const chance = getChance();
777
825
  //names and photos
826
+ const l = chance.letter;
778
827
  let gender = chance.pickone(['male', 'female']);
779
828
  if (!gender) gender = "female";
780
829
  // @ts-ignore
781
- const first = chance.first({ gender });
782
- const last = chance.last();
783
- const name = `${first} ${last}`;
784
- const email = `${first[0]}.${last}@${chance.domain()}.com`;
785
- const avatarPrefix = `https://randomuser.me/api/portraits`;
786
- const randomAvatarNumber = chance.integer({
830
+ let first = chance.first({ gender });
831
+ let last = chance.last();
832
+ let name = `${first} ${last}`;
833
+ let email = `${first[0]}.${last}@${chance.domain()}.com`;
834
+ let avatarPrefix = `https://randomuser.me/api/portraits`;
835
+ let randomAvatarNumber = chance.integer({
787
836
  min: 1,
788
837
  max: 99
789
838
  });
790
- const avPath = gender === 'male' ? `/men/${randomAvatarNumber}.jpg` : `/women/${randomAvatarNumber}.jpg`;
791
- const avatar = avatarPrefix + avPath;
792
- const created = dayjs.unix(global.NOW).subtract(bornDaysAgo, 'day').format('YYYY-MM-DD');
839
+ let avPath = gender === 'male' ? `/men/${randomAvatarNumber}.jpg` : `/women/${randomAvatarNumber}.jpg`;
840
+ let avatar = avatarPrefix + avPath;
841
+ let created = dayjs.unix(global.NOW).subtract(bornDaysAgo, 'day').format('YYYY-MM-DD');
793
842
  // const created = date(bornDaysAgo, true)();
794
843
 
844
+
795
845
  /** @type {Person} */
796
846
  const user = {
847
+ distinct_id: userId,
797
848
  name,
798
849
  email,
799
850
  avatar,
@@ -802,6 +853,13 @@ function person(bornDaysAgo = 30) {
802
853
  sessionIds: []
803
854
  };
804
855
 
856
+ if (isAnonymous) {
857
+ user.name = "Anonymous User";
858
+ user.email = `${l()}${l()}****${l()}${l()}@${l()}**${l()}*.com`;
859
+ delete user.avatar;
860
+
861
+ }
862
+
805
863
  //anon Ids
806
864
  if (global.MP_SIMULATION_CONFIG?.anonIds) {
807
865
  const clusterSize = integer(2, 10);
@@ -921,5 +979,6 @@ module.exports = {
921
979
  optimizedBoxMuller,
922
980
  buildFileNames,
923
981
  streamJSON,
924
- streamCSV
982
+ streamCSV,
983
+ inferFunnels
925
984
  };