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.
- package/cli.js +13 -0
- package/index.js +48 -28
- package/package.json +1 -1
- 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
|
|
36
|
-
|
|
36
|
+
const NOW = dayjs().unix();
|
|
37
|
+
|
|
37
38
|
const PEAK_DAYS = [
|
|
38
|
-
dayjs().subtract(
|
|
39
|
+
dayjs().subtract(2, "day").unix(),
|
|
40
|
+
dayjs().subtract(3, "day").unix(),
|
|
39
41
|
dayjs().subtract(5, "day").unix(),
|
|
40
|
-
dayjs().subtract(
|
|
41
|
-
dayjs().subtract(
|
|
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
|
-
|
|
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
|
-
|
|
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 =
|
|
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
|
-
*
|
|
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
|
|
401
|
+
function AKsTimeSoup(earliestTime, latestTime = NOW, peakDays = PEAK_DAYS) {
|
|
385
402
|
// Define business hours
|
|
386
|
-
const peakStartHour =
|
|
387
|
-
const peakEndHour =
|
|
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:
|
|
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) /
|
|
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
|
-
|
|
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
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
|
};
|