make-mp-data 3.0.4 → 3.0.6

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 (66) hide show
  1. package/README.md +46 -0
  2. package/dungeons/array-of-object-lookup-schema.json +327 -0
  3. package/dungeons/array-of-object-lookup.js +28 -8
  4. package/dungeons/ecommerce-schema.json +462 -0
  5. package/dungeons/{copilot.js → ecommerce.js} +77 -15
  6. package/dungeons/education-schema.json +2409 -0
  7. package/dungeons/education.js +206 -442
  8. package/dungeons/fintech-schema.json +14034 -0
  9. package/dungeons/fintech.js +110 -389
  10. package/dungeons/foobar-schema.json +403 -0
  11. package/dungeons/foobar.js +27 -4
  12. package/dungeons/food-delivery-schema.json +192 -0
  13. package/dungeons/food-delivery.js +602 -0
  14. package/dungeons/food-schema.json +1152 -0
  15. package/dungeons/food.js +150 -383
  16. package/dungeons/gaming-schema.json +1270 -0
  17. package/dungeons/gaming.js +143 -3
  18. package/dungeons/insurance-application-schema.json +204 -0
  19. package/dungeons/insurance-application.js +605 -0
  20. package/dungeons/media-schema.json +906 -0
  21. package/dungeons/media.js +221 -391
  22. package/dungeons/retention-cadence-schema.json +78 -0
  23. package/dungeons/retention-cadence.js +35 -1
  24. package/dungeons/rpg-schema.json +4526 -0
  25. package/dungeons/rpg.js +130 -388
  26. package/dungeons/sanity-schema.json +255 -0
  27. package/dungeons/sanity.js +21 -10
  28. package/dungeons/sass-schema.json +1291 -0
  29. package/dungeons/sass.js +210 -337
  30. package/dungeons/scd-schema.json +919 -0
  31. package/dungeons/scd.js +38 -10
  32. package/dungeons/simple-schema.json +608 -0
  33. package/dungeons/simple.js +48 -11
  34. package/dungeons/simplest-schema.json +1418 -0
  35. package/dungeons/simplest.js +392 -0
  36. package/dungeons/social-schema.json +1118 -0
  37. package/dungeons/social.js +124 -365
  38. package/dungeons/text-generation-schema.json +3096 -0
  39. package/dungeons/text-generation.js +71 -0
  40. package/index.js +6 -3
  41. package/lib/core/config-validator.js +18 -0
  42. package/lib/core/storage.js +5 -5
  43. package/lib/generators/events.js +4 -4
  44. package/lib/orchestrators/mixpanel-sender.js +14 -8
  45. package/lib/orchestrators/user-loop.js +14 -6
  46. package/lib/templates/soup-presets.js +188 -0
  47. package/lib/utils/utils.js +52 -6
  48. package/package.json +2 -2
  49. package/types.d.ts +20 -3
  50. package/dungeons/adspend.js +0 -117
  51. package/dungeons/anon.js +0 -128
  52. package/dungeons/benchmark-heavy.js +0 -240
  53. package/dungeons/benchmark-light.js +0 -126
  54. package/dungeons/big.js +0 -226
  55. package/dungeons/business.js +0 -391
  56. package/dungeons/complex.js +0 -428
  57. package/dungeons/experiments.js +0 -137
  58. package/dungeons/funnels.js +0 -309
  59. package/dungeons/mil.js +0 -323
  60. package/dungeons/mirror.js +0 -160
  61. package/dungeons/soup-test.js +0 -52
  62. package/dungeons/streaming.js +0 -372
  63. package/dungeons/strict-event-test.js +0 -30
  64. package/dungeons/student-teacher.js +0 -438
  65. package/dungeons/too-big-events.js +0 -203
  66. package/dungeons/user-agent.js +0 -209
@@ -0,0 +1,78 @@
1
+ {
2
+ "schema": {
3
+ "token": "",
4
+ "seed": "lets go",
5
+ "numDays": 360,
6
+ "numEvents": 5000,
7
+ "numUsers": 100,
8
+ "hasAnonIds": false,
9
+ "hasSessionIds": false,
10
+ "format": "json",
11
+ "alsoInferFunnels": false,
12
+ "hasLocation": false,
13
+ "hasAndroidDevices": false,
14
+ "hasIOSDevices": false,
15
+ "hasDesktopDevices": false,
16
+ "hasBrowser": false,
17
+ "hasCampaigns": false,
18
+ "isAnonymous": false,
19
+ "hasAdSpend": false,
20
+ "hasAvatar": false,
21
+ "batchSize": 5500000,
22
+ "concurrency": 1,
23
+ "writeToDisk": false,
24
+ "percentUsersBornInDataset": 100,
25
+ "funnels": [],
26
+ "events": [
27
+ {
28
+ "event": "first behavior",
29
+ "weight": 1,
30
+ "isFirstEvent": true,
31
+ "properties": {}
32
+ },
33
+ {
34
+ "event": "hourly behavior",
35
+ "weight": 40,
36
+ "properties": {}
37
+ },
38
+ {
39
+ "event": "daily behavior",
40
+ "weight": 30,
41
+ "properties": {}
42
+ },
43
+ {
44
+ "event": "weekly behavior",
45
+ "weight": 15,
46
+ "properties": {}
47
+ },
48
+ {
49
+ "event": "monthly behavior",
50
+ "weight": 10,
51
+ "properties": {}
52
+ },
53
+ {
54
+ "event": "placeholder",
55
+ "weight": 50,
56
+ "properties": {}
57
+ }
58
+ ],
59
+ "superProps": {},
60
+ "userProps": {
61
+ "favorite color": [
62
+ "red",
63
+ "blue",
64
+ "green",
65
+ "yellow",
66
+ "purple"
67
+ ]
68
+ },
69
+ "scdProps": {},
70
+ "mirrorProps": {},
71
+ "groupKeys": [],
72
+ "groupProps": {},
73
+ "lookupTables": []
74
+ },
75
+ "hooks": "function (record, type, meta) {\n\t\tif (type === \"everything\") {\n\t\t\tif (!record.length) return record;\n\n\t\t\tconst userId = record[0].user_id || record[0].device_id;\n\t\t\tif (!userId) return record;\n\n\t\t\tconst favoriteColor = meta.profile?.[\"favorite color\"] || \"green\";\n\t\t\tconst colorChurnRates = CHURN_RATES[favoriteColor] || CHURN_RATES.green;\n\n\t\t\t// Find the time range from the raw events\n\t\t\tconst times = record.map(e => new Date(e.time).getTime()).filter(t => !isNaN(t));\n\t\t\tif (!times.length) return record;\n\t\t\tconst startTime = dayjs(Math.min(...times));\n\t\t\tconst endTime = dayjs(Math.max(...times));\n\t\t\tconst totalSpanHours = endTime.diff(startTime, 'hour');\n\n\t\t\tif (totalSpanHours < 1) return record;\n\n\t\t\t// Keep the \"first behavior\" event from the original stream\n\t\t\tconst firstBehavior = record.find(e => e.event === \"first behavior\");\n\t\t\tconst newEvents = [];\n\n\t\t\tif (firstBehavior) {\n\t\t\t\tnewEvents.push(firstBehavior);\n\t\t\t} else {\n\t\t\t\t// Create a first behavior event at the start\n\t\t\t\tnewEvents.push({\n\t\t\t\t\tevent: \"first behavior\",\n\t\t\t\t\ttime: startTime.toISOString(),\n\t\t\t\t\tuser_id: userId,\n\t\t\t\t\tinsert_id: v.uid(12),\n\t\t\t\t});\n\t\t\t}\n\n\t\t\t// For each behavior type, determine churn and generate cadenced events\n\t\t\tfor (const [behaviorKey, cadence] of Object.entries(BEHAVIORS)) {\n\t\t\t\tconst churnRate = colorChurnRates[behaviorKey];\n\t\t\t\tlet churnTime = null;\n\n\t\t\t\tif (chance.bool({ likelihood: churnRate })) {\n\t\t\t\t\t// Pick churn time between 20% and 80% into the active period\n\t\t\t\t\tconst churnOffsetHours = chance.integer({\n\t\t\t\t\t\tmin: Math.floor(totalSpanHours * 0.2),\n\t\t\t\t\t\tmax: Math.floor(totalSpanHours * 0.8),\n\t\t\t\t\t});\n\t\t\t\t\tchurnTime = startTime.add(churnOffsetHours, 'hour');\n\t\t\t\t}\n\n\t\t\t\tconst behaviorEvents = generateCadencedEvents(\n\t\t\t\t\tbehaviorKey,\n\t\t\t\t\tcadence,\n\t\t\t\t\tstartTime,\n\t\t\t\t\tendTime,\n\t\t\t\t\tchurnTime,\n\t\t\t\t\tuserId\n\t\t\t\t);\n\t\t\t\tnewEvents.push(...behaviorEvents);\n\t\t\t}\n\n\t\t\t// Sort all events by time\n\t\t\tnewEvents.sort((a, b) => new Date(a.time) - new Date(b.time));\n\t\t\treturn newEvents;\n\t\t}\n\n\t\treturn record;\n\t}",
76
+ "timestamp": "2026-04-10T01:39:07.299Z",
77
+ "version": "4.0"
78
+ }
@@ -1,4 +1,3 @@
1
-
2
1
  const SEED = "kurby-retention";
3
2
  import dayjs from 'dayjs';
4
3
  import utc from 'dayjs/plugin/utc.js';
@@ -12,6 +11,41 @@ const days = 360;
12
11
 
13
12
  /** @typedef {import("../types.js").Dungeon} Config */
14
13
 
14
+ /**
15
+ * ═══════════════════════════════════════════════════════════════
16
+ * DATASET OVERVIEW
17
+ * ═══════════════════════════════════════════════════════════════
18
+ *
19
+ * Retention Cadence — tests behavior frequency and color-based churn.
20
+ * - 100 users over 360 days, ~5K base events (replaced by cadenced events)
21
+ * - 4 behavior cadences: hourly, daily, weekly, monthly
22
+ * - Churn rates vary by user's "favorite color" (red, blue, green, yellow, purple)
23
+ * - The everything hook REPLACES all generated events with precisely
24
+ * cadenced behavior events, making this a pure retention analysis dataset
25
+ *
26
+ * ═══════════════════════════════════════════════════════════════
27
+ * ANALYTICS HOOKS (1 pattern — everything hook)
28
+ * ═══════════════════════════════════════════════════════════════
29
+ *
30
+ * 1. COLOR-BASED CADENCED CHURN (everything hook)
31
+ * All raw events are replaced with 4 cadenced behavior streams
32
+ * (hourly/daily/weekly/monthly). Each user's "favorite color"
33
+ * determines their churn likelihood per cadence:
34
+ * - red: high daily churn (40%)
35
+ * - blue: high weekly churn (40%)
36
+ * - green: low churn across all cadences (5%)
37
+ * - yellow: high monthly churn (40%)
38
+ * - purple: high hourly churn (40%)
39
+ * Churned behaviors get a "churn - X behavior" event at the churn point.
40
+ *
41
+ * Mixpanel Report:
42
+ * - Retention: Event A: "first behavior", Event B: "daily behavior",
43
+ * breakdown by "favorite color"
44
+ * Expected: red users show ~40% daily churn, green users retain well
45
+ * - Insights: "churn - *" events, breakdown by "favorite color"
46
+ * Expected: each color dominates its respective cadence's churn events
47
+ */
48
+
15
49
  // Churn rates by favorite color per behavior type (percentage likelihood)
16
50
  const CHURN_RATES = {
17
51
  red: { hourly: 15, daily: 40, weekly: 15, monthly: 10 },