@ak--47/dungeon-master 1.0.0 → 1.2.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.
Files changed (104) hide show
  1. package/README.md +7 -7
  2. package/dungeons/technical/ad-spend-schema.json +128 -0
  3. package/dungeons/technical/ad-spend.js +116 -0
  4. package/dungeons/technical/anonymous-users-schema.json +92 -0
  5. package/dungeons/technical/anonymous-users.js +102 -0
  6. package/dungeons/technical/array-of-object-lookup-schema.json +191 -0
  7. package/dungeons/{array-of-object-lookup.js → technical/array-of-object-lookup.js} +12 -5
  8. package/dungeons/technical/experiments-schema.json +203 -0
  9. package/dungeons/technical/experiments.js +168 -0
  10. package/dungeons/technical/foobar-schema.json +362 -0
  11. package/dungeons/{foobar.js → technical/foobar.js} +3 -3
  12. package/dungeons/technical/group-analytics-schema.json +241 -0
  13. package/dungeons/technical/group-analytics.js +151 -0
  14. package/dungeons/technical/mirror-strategies-schema.json +84 -0
  15. package/dungeons/technical/mirror-strategies.js +126 -0
  16. package/dungeons/technical/nested-objects-schema.json +145 -0
  17. package/dungeons/technical/nested-objects.js +207 -0
  18. package/dungeons/technical/retention-cadence-schema.json +37 -0
  19. package/dungeons/{retention-cadence.js → technical/retention-cadence.js} +2 -3
  20. package/dungeons/technical/sanity-schema.json +185 -0
  21. package/dungeons/{sanity.js → technical/sanity.js} +4 -2
  22. package/dungeons/technical/scale-test-schema.json +70 -0
  23. package/dungeons/technical/scale-test.js +90 -0
  24. package/dungeons/technical/scd-schema.json +467 -0
  25. package/dungeons/{scd.js → technical/scd.js} +20 -10
  26. package/dungeons/technical/simple-schema.json +362 -0
  27. package/dungeons/{simple.js → technical/simple.js} +7 -7
  28. package/dungeons/technical/simplest-schema.json +724 -0
  29. package/dungeons/{simplest.js → technical/simplest.js} +7 -7
  30. package/dungeons/technical/text-generation-schema.json +1062 -0
  31. package/dungeons/{text-generation.js → technical/text-generation.js} +24 -11
  32. package/dungeons/vertical/community-schema.json +579 -0
  33. package/dungeons/vertical/community.js +794 -0
  34. package/dungeons/vertical/devtools-schema.json +601 -0
  35. package/dungeons/vertical/devtools.js +843 -0
  36. package/dungeons/vertical/ecommerce-schema.json +604 -0
  37. package/dungeons/{ecommerce.js → vertical/ecommerce.js} +43 -5
  38. package/dungeons/vertical/education-schema.json +5686 -0
  39. package/dungeons/{education.js → vertical/education.js} +70 -39
  40. package/dungeons/vertical/fintech-schema.json +630 -0
  41. package/dungeons/{fintech.js → vertical/fintech.js} +107 -56
  42. package/dungeons/vertical/fitness-schema.json +530 -0
  43. package/dungeons/vertical/fitness.js +808 -0
  44. package/dungeons/vertical/food-delivery-schema.json +36728 -0
  45. package/dungeons/{food.js → vertical/food-delivery.js} +67 -26
  46. package/dungeons/vertical/gaming-schema.json +438 -0
  47. package/dungeons/{gaming.js → vertical/gaming.js} +29 -16
  48. package/dungeons/vertical/healthcare-schema.json +549 -0
  49. package/dungeons/vertical/healthcare.js +775 -0
  50. package/dungeons/vertical/insurance-application-schema.json +485 -0
  51. package/dungeons/{insurance-application.js → vertical/insurance-application.js} +41 -31
  52. package/dungeons/vertical/logistics-schema.json +574 -0
  53. package/dungeons/vertical/logistics.js +799 -0
  54. package/dungeons/vertical/marketplace-schema.json +533 -0
  55. package/dungeons/vertical/marketplace.js +850 -0
  56. package/dungeons/vertical/media-schema.json +4749 -0
  57. package/dungeons/{media.js → vertical/media.js} +103 -19
  58. package/dungeons/vertical/rpg-schema.json +2491 -0
  59. package/dungeons/{rpg.js → vertical/rpg.js} +87 -60
  60. package/dungeons/vertical/sass-schema.json +3128 -0
  61. package/dungeons/{sass.js → vertical/sass.js} +65 -26
  62. package/dungeons/vertical/social-schema.json +620 -0
  63. package/dungeons/{social.js → vertical/social.js} +76 -17
  64. package/dungeons/vertical/travel-schema.json +580 -0
  65. package/dungeons/vertical/travel.js +742 -0
  66. package/index.js +20 -16
  67. package/lib/core/config-validator.js +286 -1
  68. package/lib/core/context.js +16 -5
  69. package/lib/core/storage.js +2 -0
  70. package/lib/generators/adspend.js +3 -3
  71. package/lib/generators/events.js +141 -14
  72. package/lib/generators/funnels.js +67 -7
  73. package/lib/generators/text.js +2 -2
  74. package/lib/orchestrators/user-loop.js +444 -22
  75. package/lib/templates/soup-presets.js +2 -2
  76. package/lib/utils/utils.js +4 -5
  77. package/package.json +4 -3
  78. package/scripts/dungeon-to-json.mjs +163 -0
  79. package/scripts/extract-dungeon-schema.mjs +343 -0
  80. package/scripts/json-to-dungeon.mjs +200 -0
  81. package/scripts/run-dungeon.mjs +76 -0
  82. package/scripts/run-many.mjs +118 -0
  83. package/scripts/verify-runner.mjs +42 -0
  84. package/types.d.ts +316 -1
  85. package/dungeons/array-of-object-lookup-schema.json +0 -327
  86. package/dungeons/ecommerce-schema.json +0 -462
  87. package/dungeons/education-schema.json +0 -2409
  88. package/dungeons/fintech-schema.json +0 -14034
  89. package/dungeons/foobar-schema.json +0 -403
  90. package/dungeons/food-delivery-schema.json +0 -192
  91. package/dungeons/food-delivery.js +0 -602
  92. package/dungeons/food-schema.json +0 -1152
  93. package/dungeons/gaming-schema.json +0 -1270
  94. package/dungeons/insurance-application-schema.json +0 -204
  95. package/dungeons/media-schema.json +0 -906
  96. package/dungeons/retention-cadence-schema.json +0 -78
  97. package/dungeons/rpg-schema.json +0 -4526
  98. package/dungeons/sanity-schema.json +0 -255
  99. package/dungeons/sass-schema.json +0 -1291
  100. package/dungeons/scd-schema.json +0 -919
  101. package/dungeons/simple-schema.json +0 -608
  102. package/dungeons/simplest-schema.json +0 -1418
  103. package/dungeons/social-schema.json +0 -1118
  104. package/dungeons/text-generation-schema.json +0 -3096
@@ -1,7 +1,7 @@
1
1
  import dayjs from "dayjs";
2
2
  import utc from "dayjs/plugin/utc.js";
3
3
  import "dotenv/config";
4
- import * as u from "../lib/utils/utils.js";
4
+ import * as u from "../../lib/utils/utils.js";
5
5
  import * as v from "ak-tools";
6
6
 
7
7
  const SEED = "harness-media";
@@ -10,7 +10,7 @@ const chance = u.initChance(SEED);
10
10
  const num_users = 5_000;
11
11
  const days = 100;
12
12
 
13
- /** @typedef {import("../types.js").Dungeon} Config */
13
+ /** @typedef {import("../../types").Dungeon} Config */
14
14
 
15
15
  /**
16
16
  * ═══════════════════════════════════════════════════════════════════════════════
@@ -238,7 +238,6 @@ const config = {
238
238
  hasAdSpend: false,
239
239
  percentUsersBornInDataset: 50,
240
240
  hasAvatar: true,
241
- batchSize: 2_500_000,
242
241
  concurrency: 1,
243
242
  writeToDisk: false,
244
243
 
@@ -318,6 +317,10 @@ const config = {
318
317
  properties: {
319
318
  "signup_source": ["organic", "referral", "trial_offer", "ad"],
320
319
  "plan_selected": ["free", "standard", "premium"],
320
+ "weekend_viewing": [false],
321
+ "prime_time": [false],
322
+ "kids_profile": [false],
323
+ "ad_fatigue": [false],
321
324
  }
322
325
  },
323
326
  {
@@ -326,6 +329,10 @@ const config = {
326
329
  properties: {
327
330
  "browse_section": ["home", "trending", "new_releases", "genre", "continue_watching"],
328
331
  "genre": ["action", "comedy", "drama", "documentary", "horror", "sci_fi", "animation", "thriller", "romance"],
332
+ "weekend_viewing": [false],
333
+ "prime_time": [false],
334
+ "kids_profile": [false],
335
+ "ad_fatigue": [false],
329
336
  }
330
337
  },
331
338
  {
@@ -334,62 +341,96 @@ const config = {
334
341
  properties: {
335
342
  "content_type": ["movie", "series", "documentary", "special"],
336
343
  "genre": ["action", "comedy", "drama", "documentary", "horror", "sci_fi", "animation", "thriller", "romance"],
337
- "content_id": u.pickAWinner(contentIds),
344
+ "content_id": contentIds,
345
+ "blockbuster_release": [false],
346
+ "kids_profile": [false],
347
+ "weekend_viewing": [false],
348
+ "prime_time": [false],
349
+ "ad_fatigue": [false],
338
350
  }
339
351
  },
340
352
  {
341
353
  event: "playback started",
342
354
  weight: 18,
343
355
  properties: {
344
- "content_id": u.pickAWinner(contentIds),
356
+ "content_id": contentIds,
345
357
  "content_type": ["movie", "series", "documentary", "special"],
346
358
  "playback_quality": ["480p", "720p", "1080p", "4k"],
347
359
  "subtitle_language": ["none", "english", "spanish", "french", "japanese", "korean"],
348
- "playback_speed": u.pickAWinner(["0.5x", "1x", "1x", "1x", "1.25x", "1.5x", "2x"]),
360
+ "playback_speed": ["0.5x", "1x", "1x", "1x", "1.25x", "1.5x", "2x"],
361
+ "blockbuster_release": [false],
362
+ "kids_profile": [false],
363
+ "binge_session": [false],
364
+ "weekend_viewing": [false],
365
+ "prime_time": [false],
366
+ "ad_fatigue": [false],
349
367
  }
350
368
  },
351
369
  {
352
370
  event: "playback completed",
353
371
  weight: 12,
354
372
  properties: {
355
- "content_id": u.pickAWinner(contentIds),
373
+ "content_id": contentIds,
356
374
  "content_type": ["movie", "series", "documentary", "special"],
357
375
  "watch_duration_min": u.weighNumRange(5, 180, 0.5, 45),
358
376
  "completion_percent": u.weighNumRange(10, 100, 1.5, 85),
377
+ "binge_session": [false],
378
+ "subtitle_user": [false],
379
+ "weekend_viewing": [false],
380
+ "prime_time": [false],
381
+ "kids_profile": [false],
382
+ "ad_fatigue": [false],
359
383
  }
360
384
  },
361
385
  {
362
386
  event: "playback paused",
363
387
  weight: 10,
364
388
  properties: {
365
- "content_id": u.pickAWinner(contentIds),
389
+ "content_id": contentIds,
366
390
  "pause_reason": ["manual", "ad_break", "buffering", "notification"],
391
+ "weekend_viewing": [false],
392
+ "prime_time": [false],
393
+ "kids_profile": [false],
394
+ "ad_fatigue": [false],
367
395
  }
368
396
  },
369
397
  {
370
398
  event: "content rated",
371
399
  weight: 6,
372
400
  properties: {
373
- "content_id": u.pickAWinner(contentIds),
401
+ "content_id": contentIds,
374
402
  "rating": u.weighNumRange(1, 5, 2, 4),
375
403
  "review_text_length": u.weighNumRange(0, 500, 0.2, 0),
404
+ "blockbuster_release": [false],
405
+ "weekend_viewing": [false],
406
+ "prime_time": [false],
407
+ "kids_profile": [false],
408
+ "ad_fatigue": [false],
376
409
  }
377
410
  },
378
411
  {
379
412
  event: "watchlist added",
380
413
  weight: 8,
381
414
  properties: {
382
- "content_id": u.pickAWinner(contentIds),
415
+ "content_id": contentIds,
383
416
  "content_type": ["movie", "series", "documentary", "special"],
384
417
  "genre": ["action", "comedy", "drama", "documentary", "horror", "sci_fi", "animation", "thriller", "romance"],
418
+ "weekend_viewing": [false],
419
+ "prime_time": [false],
420
+ "kids_profile": [false],
421
+ "ad_fatigue": [false],
385
422
  }
386
423
  },
387
424
  {
388
425
  event: "watchlist removed",
389
426
  weight: 3,
390
427
  properties: {
391
- "content_id": u.pickAWinner(contentIds),
428
+ "content_id": contentIds,
392
429
  "reason": ["watched", "not_interested", "expired"],
430
+ "weekend_viewing": [false],
431
+ "prime_time": [false],
432
+ "kids_profile": [false],
433
+ "ad_fatigue": [false],
393
434
  }
394
435
  },
395
436
  {
@@ -399,6 +440,10 @@ const config = {
399
440
  "search_term": () => chance.word(),
400
441
  "results_count": u.weighNumRange(0, 50, 0.5, 15),
401
442
  "search_type": ["title", "actor", "director", "genre"],
443
+ "weekend_viewing": [false],
444
+ "prime_time": [false],
445
+ "kids_profile": [false],
446
+ "ad_fatigue": [false],
402
447
  }
403
448
  },
404
449
  {
@@ -407,6 +452,10 @@ const config = {
407
452
  properties: {
408
453
  "algorithm": ["collaborative_filtering", "content_based", "trending", "editorial"],
409
454
  "position": u.weighNumRange(1, 20),
455
+ "weekend_viewing": [false],
456
+ "prime_time": [false],
457
+ "kids_profile": [false],
458
+ "ad_fatigue": [false],
410
459
  }
411
460
  },
412
461
  {
@@ -414,6 +463,10 @@ const config = {
414
463
  weight: 4,
415
464
  properties: {
416
465
  "profile_type": ["main", "kids", "partner", "guest"],
466
+ "weekend_viewing": [false],
467
+ "prime_time": [false],
468
+ "kids_profile": [false],
469
+ "ad_fatigue": [false],
417
470
  }
418
471
  },
419
472
  {
@@ -422,7 +475,12 @@ const config = {
422
475
  properties: {
423
476
  "ad_type": ["pre_roll", "mid_roll", "banner", "interstitial"],
424
477
  "ad_duration_sec": u.weighNumRange(5, 30),
425
- "skipped": u.pickAWinner([true, false], 0.4),
478
+ "skipped": [false, false, false, true, true],
479
+ "ad_blocked": [false],
480
+ "kids_profile": [false],
481
+ "weekend_viewing": [false],
482
+ "prime_time": [false],
483
+ "ad_fatigue": [false],
426
484
  }
427
485
  },
428
486
  {
@@ -432,15 +490,23 @@ const config = {
432
490
  "old_plan": ["free", "standard", "premium"],
433
491
  "new_plan": ["free", "standard", "premium"],
434
492
  "change_reason": ["upgrade", "downgrade", "cancel", "resubscribe"],
493
+ "weekend_viewing": [false],
494
+ "prime_time": [false],
495
+ "kids_profile": [false],
496
+ "ad_fatigue": [false],
435
497
  }
436
498
  },
437
499
  {
438
500
  event: "download started",
439
501
  weight: 5,
440
502
  properties: {
441
- "content_id": u.pickAWinner(contentIds),
503
+ "content_id": contentIds,
442
504
  "content_type": ["movie", "series", "documentary", "special"],
443
505
  "download_quality": ["720p", "1080p", "4k"],
506
+ "weekend_viewing": [false],
507
+ "prime_time": [false],
508
+ "kids_profile": [false],
509
+ "ad_fatigue": [false],
444
510
  }
445
511
  },
446
512
  {
@@ -449,6 +515,10 @@ const config = {
449
515
  properties: {
450
516
  "share_method": ["link", "social", "dm", "email"],
451
517
  "content_type": ["movie", "series", "documentary", "special"],
518
+ "weekend_viewing": [false],
519
+ "prime_time": [false],
520
+ "kids_profile": [false],
521
+ "ad_fatigue": [false],
452
522
  }
453
523
  },
454
524
  {
@@ -457,23 +527,34 @@ const config = {
457
527
  properties: {
458
528
  "subtitle_language": ["none", "english", "spanish", "french", "japanese", "korean"],
459
529
  "action": ["enabled", "disabled", "changed"],
530
+ "weekend_viewing": [false],
531
+ "prime_time": [false],
532
+ "kids_profile": [false],
533
+ "ad_fatigue": [false],
460
534
  }
461
535
  },
462
536
  ],
463
537
 
464
538
  superProps: {
465
- subscription_plan: u.pickAWinner(["free", "free", "standard", "standard", "standard", "premium"]),
539
+ subscription_plan: ["free", "free", "standard", "standard", "standard", "premium"],
466
540
  device_type: ["smart_tv", "mobile", "tablet", "laptop", "desktop"],
467
541
  },
468
542
 
469
- scdProps: {},
543
+ scdProps: {
544
+ subscription_plan: {
545
+ values: ["free", "basic", "standard", "premium"],
546
+ frequency: "month",
547
+ timing: "fuzzy",
548
+ max: 6
549
+ }
550
+ },
470
551
 
471
552
  userProps: {
472
553
  "preferred_genre": ["action", "comedy", "drama", "documentary", "horror", "sci_fi", "animation"],
473
554
  "avg_session_duration_min": u.weighNumRange(10, 180, 0.5, 45),
474
555
  "total_watch_hours": u.weighNumRange(0, 500, 0.8, 50),
475
556
  "profiles_count": u.weighNumRange(1, 5),
476
- "downloads_enabled": u.pickAWinner([true, false], 0.4),
557
+ "downloads_enabled": [false, false, false, true, true],
477
558
  },
478
559
 
479
560
  lookupTables: [],
@@ -497,7 +578,8 @@ const config = {
497
578
  const DATASET_START = NOW.subtract(days, 'days');
498
579
  // FIXED_START is the pre-shift time range start; needed because
499
580
  // meta.firstEventTime in funnel-pre is in the FIXED (pre-shift) timeframe
500
- const FIXED_START = dayjs.unix(global.FIXED_NOW).subtract(days, 'days');
581
+ const FIXED_NOW_UNIX = dayjs('2024-02-02').unix();
582
+ const FIXED_START = dayjs.unix(FIXED_NOW_UNIX).subtract(days, 'days');
501
583
 
502
584
  // ─────────────────────────────────────────────────────────────
503
585
  // Hook #1: GENRE FUNNEL CONVERSION (funnel-pre)
@@ -701,7 +783,9 @@ const config = {
701
783
  // Add extra viewing events after completions
702
784
  if (event.event === "playback completed" && chance.bool({ likelihood: 40 })) {
703
785
  const nextContentId = chance.pickone(contentIds);
786
+ const startTemplate = userEvents.find(e => e.event === "playback started");
704
787
  const extraStart = {
788
+ ...(startTemplate || event),
705
789
  event: "playback started",
706
790
  time: eventTime.add(chance.integer({ min: 1, max: 5 }), 'minutes').toISOString(),
707
791
  user_id: event.user_id,
@@ -711,7 +795,7 @@ const config = {
711
795
  binge_session: true,
712
796
  };
713
797
  const extraComplete = {
714
- event: "playback completed",
798
+ ...event,
715
799
  time: eventTime.add(chance.integer({ min: 25, max: 60 }), 'minutes').toISOString(),
716
800
  user_id: event.user_id,
717
801
  content_id: nextContentId,
@@ -767,7 +851,7 @@ const config = {
767
851
  const templateEvent = chance.pickone(completionEvents);
768
852
  const templateTime = dayjs(templateEvent.time);
769
853
  const extraCompletion = {
770
- event: "playback completed",
854
+ ...templateEvent,
771
855
  time: templateTime.add(chance.integer({ min: 30, max: 180 }), 'minutes').toISOString(),
772
856
  user_id: templateEvent.user_id,
773
857
  content_id: chance.pickone(contentIds),