make-mp-data 1.0.14 → 1.0.15

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.
Files changed (4) hide show
  1. package/cli.js +13 -0
  2. package/index.js +48 -28
  3. package/package.json +1 -1
  4. package/utils.js +4 -2
package/cli.js CHANGED
@@ -60,6 +60,19 @@ DOCS: https://github.com/ak--47/make-mp-data`)
60
60
  describe: 'either US or EU',
61
61
  type: 'string'
62
62
  })
63
+ .option("writeToDisk", {
64
+ demandOption: false,
65
+ default: true,
66
+ describe: 'write data to disk',
67
+ alias: 'w',
68
+ type: 'boolean',
69
+ coerce: (value) => {
70
+ if (typeof value === 'string') {
71
+ return value.toLowerCase() === 'true';
72
+ }
73
+ return value;
74
+ }
75
+ })
63
76
  .help()
64
77
  .wrap(null)
65
78
  .argv;
package/index.js CHANGED
@@ -25,20 +25,27 @@ const {
25
25
  range,
26
26
  exhaust,
27
27
  openFinder,
28
+ applySkew,
29
+ boxMullerRandom,
28
30
  } = require("./utils.js");
29
31
  const dayjs = require("dayjs");
30
32
  const utc = require("dayjs/plugin/utc");
31
- const cliParams = require("./cli.js");
32
-
33
33
  dayjs.extend(utc);
34
+ const cliParams = require("./cli.js");
34
35
  Array.prototype.pickOne = pick;
35
- const now = dayjs().unix();
36
- const dayInSec = 86400;
36
+ const NOW = dayjs().unix();
37
+
37
38
  const PEAK_DAYS = [
38
- dayjs().subtract(1, "day").unix(),
39
+ dayjs().subtract(2, "day").unix(),
40
+ dayjs().subtract(3, "day").unix(),
39
41
  dayjs().subtract(5, "day").unix(),
40
- dayjs().subtract(10, "day").unix(),
41
- dayjs().subtract(15, "day").unix(),
42
+ dayjs().subtract(7, "day").unix(),
43
+ dayjs().subtract(11, "day").unix(),
44
+ dayjs().subtract(13, "day").unix(),
45
+ dayjs().subtract(17, "day").unix(),
46
+ dayjs().subtract(19, "day").unix(),
47
+ dayjs().subtract(23, "day").unix(),
48
+ dayjs().subtract(29, "day").unix(),
42
49
  ];
43
50
 
44
51
  //our main program
@@ -63,13 +70,30 @@ async function main(config) {
63
70
  region = "US",
64
71
  writeToDisk = false,
65
72
  } = config;
66
- if (require.main === module) writeToDisk = true;
73
+
74
+ //ensure we have a token or are writing to disk
75
+ if (require.main === module) {
76
+ if (!token) {
77
+ if (!writeToDisk) {
78
+ writeToDisk = true;
79
+ }
80
+ }
81
+ }
82
+
67
83
  const uuidChance = new Chance(seed);
68
84
 
69
- //the function which generates $distinct_id
85
+ //the function which generates $distinct_id + $created
70
86
  function uuid() {
71
87
  const distinct_id = uuidChance.guid();
72
- const daysAgoBorn = chance.integer({ min: 1, max: numDays });
88
+ let z = boxMullerRandom();
89
+ const skew = chance.normal({ mean: 10, dev: 3 });
90
+ z = applySkew(z, skew);
91
+
92
+ // Scale and shift the normally distributed value to fit the range of days
93
+ const maxZ = integer(2, 4);
94
+ const scaledZ = (z / maxZ + 1) / 2; // Scale to a 0-1 range
95
+ const daysAgoBorn = Math.round(scaledZ * (numDays - 1)) + 1; // Scale to 1-numDays range
96
+
73
97
  return {
74
98
  distinct_id,
75
99
  ...person(daysAgoBorn),
@@ -300,14 +324,7 @@ function makeSCD(props, distinct_id, mutations, $created) {
300
324
  return scdEntries;
301
325
  }
302
326
 
303
- function makeEvent(
304
- distinct_id,
305
- earliestTime,
306
- events,
307
- superProps,
308
- groupKeys,
309
- isFirstEvent = false
310
- ) {
327
+ function makeEvent(distinct_id, earliestTime, events, superProps, groupKeys, isFirstEvent = false) {
311
328
  let chosenEvent = events.pickOne();
312
329
  if (typeof chosenEvent === "string")
313
330
  chosenEvent = { event: chosenEvent, properties: {} };
@@ -318,7 +335,7 @@ function makeEvent(
318
335
  };
319
336
 
320
337
  if (isFirstEvent) event.time = earliestTime;
321
- if (!isFirstEvent) event.time = customTimeDistribution(earliestTime, now, PEAK_DAYS);
338
+ if (!isFirstEvent) event.time = AKsTimeSoup(earliestTime, NOW, PEAK_DAYS);
322
339
 
323
340
  const props = { ...chosenEvent.properties, ...superProps };
324
341
 
@@ -375,16 +392,16 @@ function buildFileNames(config) {
375
392
  }
376
393
 
377
394
  /**
378
- * Generates a random timestamp with higher likelihood on peak days and typical business hours.
395
+ * timestamp generator with a twist
379
396
  * @param {number} earliestTime - The earliest timestamp in Unix format.
380
397
  * @param {number} latestTime - The latest timestamp in Unix format.
381
398
  * @param {Array} peakDays - Array of Unix timestamps representing the start of peak days.
382
399
  * @returns {number} - The generated event timestamp in Unix format.
383
400
  */
384
- function customTimeDistribution(earliestTime, latestTime, peakDays) {
401
+ function AKsTimeSoup(earliestTime, latestTime = NOW, peakDays = PEAK_DAYS) {
385
402
  // Define business hours
386
- const peakStartHour = 8; // 8 AM
387
- const peakEndHour = 18; // 6 PM
403
+ const peakStartHour = 4; // 4 AM
404
+ const peakEndHour = 23; // 11 PM
388
405
  const likelihoodOfPeakDay = chance.integer({ min: integer(5, 42), max: integer(43, 69) }); // Randomize likelihood with CHAOS!~~
389
406
 
390
407
  // Select a day, with a preference for peak days
@@ -393,7 +410,7 @@ function customTimeDistribution(earliestTime, latestTime, peakDays) {
393
410
  selectedDay = peakDays.length > 0 ? chance.pickone(peakDays) : integer(earliestTime, latestTime);
394
411
  } else {
395
412
  // Introduce minor peaks by allowing some events to still occur during business hours
396
- selectedDay = chance.bool({ likelihood: 20 }) // 20% chance to simulate a minor peak on a non-peak day
413
+ selectedDay = chance.bool({ likelihood: integer(1, 42) })
397
414
  ? chance.pickone(peakDays)
398
415
  : integer(earliestTime, latestTime);
399
416
  }
@@ -407,12 +424,14 @@ function customTimeDistribution(earliestTime, latestTime, peakDays) {
407
424
  let eventTime;
408
425
  if (selectedDay === peakDays[0]) {
409
426
  // Use a skewed distribution for peak days
410
- eventTime = chance.normal({ mean: (businessEnd + businessStart) / 2, dev: (businessEnd - businessStart) / 8 });
427
+ eventTime = chance.normal({ mean: (businessEnd + businessStart) / integer(1, 4), dev: (businessEnd - businessStart) / integer(2, 8) });
411
428
  } else {
412
429
  // For non-peak days, use a uniform distribution to add noise
413
- eventTime = integer(businessStart, businessEnd);
430
+ eventTime = integer(integer(businessStart, businessEnd), integer(businessStart, businessEnd));
414
431
  }
415
- eventTime = Math.min(Math.max(eventTime, businessStart), businessEnd); // Ensure time is within business hours
432
+
433
+ // usually, ensure the event time is within business hours
434
+ if (chance.bool({ likelihood: 42 })) eventTime = Math.min(Math.max(eventTime, businessStart), businessEnd);
416
435
 
417
436
  return eventTime;
418
437
  }
@@ -422,7 +441,7 @@ function customTimeDistribution(earliestTime, latestTime, peakDays) {
422
441
  // this is for CLI
423
442
  if (require.main === module) {
424
443
  const args = cliParams();
425
- const { token, seed, format, numDays, numUsers, numEvents, region } = args;
444
+ const { token, seed, format, numDays, numUsers, numEvents, region, writeToDisk } = args;
426
445
  const suppliedConfig = args._[0];
427
446
 
428
447
  //if the user specifics an separate config file
@@ -443,6 +462,7 @@ if (require.main === module) {
443
462
  if (numUsers) config.numUsers = numUsers;
444
463
  if (numEvents) config.numEvents = numEvents;
445
464
  if (region) config.region = region;
465
+ if (writeToDisk) config.writeToDisk = writeToDisk;
446
466
 
447
467
  main(config)
448
468
  .then((data) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "make-mp-data",
3
- "version": "1.0.14",
3
+ "version": "1.0.15",
4
4
  "description": "builds all mixpanel primitives for a given project",
5
5
  "main": "index.js",
6
6
  "scripts": {
package/utils.js CHANGED
@@ -20,7 +20,7 @@ function pick() {
20
20
  function date(inTheLast = 30, isPast = true, format = 'YYYY-MM-DD') {
21
21
  const now = dayjs.utc();
22
22
  return function () {
23
- const when = chance.integer({ min: 0, max: inTheLast });
23
+ const when = chance.integer({ min: 0, max: Math.abs(inTheLast) });
24
24
  let then;
25
25
  if (isPast) then = now.subtract(when, 'day');
26
26
  if (!isPast) then = now.add(when, 'day');
@@ -227,5 +227,7 @@ module.exports = {
227
227
  choose,
228
228
  range,
229
229
  exhaust,
230
- openFinder
230
+ openFinder,
231
+ applySkew,
232
+ boxMullerRandom,
231
233
  };