@ak--47/dungeon-master 1.1.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.
- package/dungeons/technical/ad-spend-schema.json +2 -2
- package/dungeons/technical/ad-spend.js +1 -1
- package/dungeons/technical/anonymous-users-schema.json +4 -3
- package/dungeons/technical/anonymous-users.js +1 -1
- package/dungeons/technical/array-of-object-lookup-schema.json +1 -1
- package/dungeons/technical/array-of-object-lookup.js +1 -1
- package/dungeons/technical/experiments-schema.json +25 -19
- package/dungeons/technical/experiments.js +1 -1
- package/dungeons/technical/foobar.js +1 -1
- package/dungeons/technical/group-analytics-schema.json +92 -0
- package/dungeons/technical/group-analytics.js +1 -1
- package/dungeons/technical/mirror-strategies-schema.json +4 -4
- package/dungeons/technical/mirror-strategies.js +1 -1
- package/dungeons/technical/nested-objects.js +1 -1
- package/dungeons/technical/retention-cadence.js +1 -2
- package/dungeons/technical/sanity-schema.json +22 -22
- package/dungeons/technical/sanity.js +1 -0
- package/dungeons/technical/scale-test.js +1 -1
- package/dungeons/technical/scd-schema.json +230 -33
- package/dungeons/technical/scd.js +1 -0
- package/dungeons/technical/simple-schema.json +132 -48
- package/dungeons/technical/simple.js +1 -1
- package/dungeons/technical/simplest-schema.json +168 -79
- package/dungeons/technical/simplest.js +1 -1
- package/dungeons/technical/text-generation-schema.json +7 -4
- package/dungeons/technical/text-generation.js +1 -2
- package/dungeons/vertical/community-schema.json +71 -49
- package/dungeons/vertical/community.js +8 -2
- package/dungeons/vertical/devtools-schema.json +69 -48
- package/dungeons/vertical/devtools.js +8 -2
- package/dungeons/vertical/ecommerce-schema.json +126 -108
- package/dungeons/vertical/ecommerce.js +9 -2
- package/dungeons/vertical/education-schema.json +5261 -272
- package/dungeons/vertical/education.js +16 -3
- package/dungeons/vertical/fintech-schema.json +165 -98
- package/dungeons/vertical/fintech.js +16 -3
- package/dungeons/vertical/fitness-schema.json +69 -47
- package/dungeons/vertical/fitness.js +8 -2
- package/dungeons/vertical/food-delivery-schema.json +36237 -187
- package/dungeons/vertical/food-delivery.js +16 -3
- package/dungeons/vertical/gaming-schema.json +103 -59
- package/dungeons/vertical/gaming.js +20 -9
- package/dungeons/vertical/healthcare-schema.json +70 -48
- package/dungeons/vertical/healthcare.js +8 -2
- package/dungeons/vertical/insurance-application-schema.json +66 -47
- package/dungeons/vertical/insurance-application.js +8 -2
- package/dungeons/vertical/logistics-schema.json +60 -38
- package/dungeons/vertical/logistics.js +8 -2
- package/dungeons/vertical/marketplace-schema.json +65 -43
- package/dungeons/vertical/marketplace.js +8 -2
- package/dungeons/vertical/media-schema.json +4085 -123
- package/dungeons/vertical/media.js +9 -3
- package/dungeons/vertical/rpg-schema.json +1984 -147
- package/dungeons/vertical/rpg.js +9 -3
- package/dungeons/vertical/sass-schema.json +2622 -147
- package/dungeons/vertical/sass.js +16 -3
- package/dungeons/vertical/social-schema.json +146 -78
- package/dungeons/vertical/social.js +16 -3
- package/dungeons/vertical/travel-schema.json +57 -35
- package/dungeons/vertical/travel.js +8 -2
- package/index.js +1 -1
- package/lib/core/context.js +9 -0
- package/lib/core/storage.js +2 -0
- package/lib/orchestrators/user-loop.js +4 -1
- package/package.json +1 -1
- package/scripts/extract-dungeon-schema.mjs +64 -18
- package/types.d.ts +3 -0
|
@@ -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("
|
|
13
|
+
/** @typedef {import("../../types").Dungeon} Config */
|
|
14
14
|
|
|
15
15
|
/*
|
|
16
16
|
* ═══════════════════════════════════════════════════════════════════════════════
|
|
@@ -268,10 +268,23 @@ const config = {
|
|
|
268
268
|
hasAdSpend: false,
|
|
269
269
|
percentUsersBornInDataset: 50,
|
|
270
270
|
hasAvatar: true,
|
|
271
|
-
batchSize: 2_500_000,
|
|
272
271
|
concurrency: 1,
|
|
273
272
|
writeToDisk: false,
|
|
274
|
-
scdProps: {
|
|
273
|
+
scdProps: {
|
|
274
|
+
primary_role: {
|
|
275
|
+
values: ["viewer", "editor", "admin", "owner"],
|
|
276
|
+
frequency: "month",
|
|
277
|
+
timing: "fuzzy",
|
|
278
|
+
max: 6
|
|
279
|
+
},
|
|
280
|
+
plan_tier: {
|
|
281
|
+
values: ["starter", "growth", "enterprise", "scale"],
|
|
282
|
+
frequency: "month",
|
|
283
|
+
timing: "fixed",
|
|
284
|
+
max: 6,
|
|
285
|
+
type: "company_id"
|
|
286
|
+
}
|
|
287
|
+
},
|
|
275
288
|
|
|
276
289
|
funnels: [
|
|
277
290
|
{
|
|
@@ -38,9 +38,10 @@
|
|
|
38
38
|
241
|
|
39
39
|
]
|
|
40
40
|
},
|
|
41
|
-
"has_media":
|
|
42
|
-
|
|
43
|
-
|
|
41
|
+
"has_media": [
|
|
42
|
+
false,
|
|
43
|
+
true
|
|
44
|
+
],
|
|
44
45
|
"hashtag_count": {
|
|
45
46
|
"$range": [
|
|
46
47
|
1,
|
|
@@ -206,14 +207,15 @@
|
|
|
206
207
|
"text"
|
|
207
208
|
],
|
|
208
209
|
"view_duration_sec": [
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
210
|
+
14,
|
|
211
|
+
9,
|
|
212
|
+
25,
|
|
213
|
+
20
|
|
214
|
+
],
|
|
215
|
+
"completed": [
|
|
216
|
+
false,
|
|
217
|
+
true
|
|
213
218
|
],
|
|
214
|
-
"completed": {
|
|
215
|
-
"$type": "array"
|
|
216
|
-
},
|
|
217
219
|
"toxic_user": [
|
|
218
220
|
false
|
|
219
221
|
]
|
|
@@ -228,12 +230,14 @@
|
|
|
228
230
|
"video",
|
|
229
231
|
"text"
|
|
230
232
|
],
|
|
231
|
-
"has_filter":
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
233
|
+
"has_filter": [
|
|
234
|
+
true,
|
|
235
|
+
false
|
|
236
|
+
],
|
|
237
|
+
"has_sticker": [
|
|
238
|
+
false,
|
|
239
|
+
true
|
|
240
|
+
],
|
|
237
241
|
"weekend_surge": [
|
|
238
242
|
false
|
|
239
243
|
],
|
|
@@ -258,16 +262,15 @@
|
|
|
258
262
|
"posts"
|
|
259
263
|
],
|
|
260
264
|
"results_count": [
|
|
261
|
-
33,
|
|
262
|
-
40,
|
|
263
|
-
35,
|
|
264
|
-
28,
|
|
265
|
-
17,
|
|
266
|
-
36,
|
|
267
265
|
37,
|
|
268
|
-
|
|
266
|
+
14,
|
|
267
|
+
11,
|
|
268
|
+
23,
|
|
269
|
+
9,
|
|
270
|
+
8,
|
|
269
271
|
15,
|
|
270
|
-
|
|
272
|
+
36,
|
|
273
|
+
17
|
|
271
274
|
],
|
|
272
275
|
"toxic_user": [
|
|
273
276
|
false
|
|
@@ -285,9 +288,10 @@
|
|
|
285
288
|
"mention",
|
|
286
289
|
"trending"
|
|
287
290
|
],
|
|
288
|
-
"clicked":
|
|
289
|
-
|
|
290
|
-
|
|
291
|
+
"clicked": [
|
|
292
|
+
false,
|
|
293
|
+
true
|
|
294
|
+
],
|
|
291
295
|
"toxic_user": [
|
|
292
296
|
false
|
|
293
297
|
]
|
|
@@ -305,8 +309,8 @@
|
|
|
305
309
|
],
|
|
306
310
|
"conversation_length": {
|
|
307
311
|
"$range": [
|
|
308
|
-
|
|
309
|
-
|
|
312
|
+
4,
|
|
313
|
+
93
|
|
310
314
|
]
|
|
311
315
|
},
|
|
312
316
|
"toxic_user": [
|
|
@@ -411,8 +415,8 @@
|
|
|
411
415
|
"vip"
|
|
412
416
|
],
|
|
413
417
|
"price_usd": [
|
|
414
|
-
9.99,
|
|
415
418
|
4.99,
|
|
419
|
+
9.99,
|
|
416
420
|
19.99
|
|
417
421
|
],
|
|
418
422
|
"toxic_user": [
|
|
@@ -421,53 +425,6 @@
|
|
|
421
425
|
}
|
|
422
426
|
}
|
|
423
427
|
],
|
|
424
|
-
"superProps": {
|
|
425
|
-
"app_version": [
|
|
426
|
-
"4.0",
|
|
427
|
-
"4.1",
|
|
428
|
-
"4.2",
|
|
429
|
-
"4.3",
|
|
430
|
-
"5.0"
|
|
431
|
-
],
|
|
432
|
-
"account_type": [
|
|
433
|
-
"personal",
|
|
434
|
-
"creator",
|
|
435
|
-
"business"
|
|
436
|
-
]
|
|
437
|
-
},
|
|
438
|
-
"userProps": {
|
|
439
|
-
"follower_count": {
|
|
440
|
-
"$range": [
|
|
441
|
-
2283,
|
|
442
|
-
7639
|
|
443
|
-
]
|
|
444
|
-
},
|
|
445
|
-
"following_count": {
|
|
446
|
-
"$range": [
|
|
447
|
-
869,
|
|
448
|
-
3942
|
|
449
|
-
]
|
|
450
|
-
},
|
|
451
|
-
"bio_length": {
|
|
452
|
-
"$range": [
|
|
453
|
-
2,
|
|
454
|
-
132
|
|
455
|
-
]
|
|
456
|
-
},
|
|
457
|
-
"verified": {
|
|
458
|
-
"$type": "array"
|
|
459
|
-
},
|
|
460
|
-
"content_niche": [
|
|
461
|
-
"lifestyle",
|
|
462
|
-
"tech",
|
|
463
|
-
"food",
|
|
464
|
-
"fitness",
|
|
465
|
-
"travel",
|
|
466
|
-
"comedy",
|
|
467
|
-
"news",
|
|
468
|
-
"art"
|
|
469
|
-
]
|
|
470
|
-
},
|
|
471
428
|
"funnels": [
|
|
472
429
|
{
|
|
473
430
|
"sequence": [
|
|
@@ -548,5 +505,116 @@
|
|
|
548
505
|
"conversionRate": 20,
|
|
549
506
|
"timeToConvert": 2
|
|
550
507
|
}
|
|
551
|
-
]
|
|
508
|
+
],
|
|
509
|
+
"superProps": {
|
|
510
|
+
"app_version": [
|
|
511
|
+
"4.0",
|
|
512
|
+
"4.1",
|
|
513
|
+
"4.2",
|
|
514
|
+
"4.3",
|
|
515
|
+
"5.0"
|
|
516
|
+
],
|
|
517
|
+
"account_type": [
|
|
518
|
+
"personal",
|
|
519
|
+
"creator",
|
|
520
|
+
"business"
|
|
521
|
+
]
|
|
522
|
+
},
|
|
523
|
+
"userProps": {
|
|
524
|
+
"follower_count": {
|
|
525
|
+
"$range": [
|
|
526
|
+
2075,
|
|
527
|
+
7782
|
|
528
|
+
]
|
|
529
|
+
},
|
|
530
|
+
"following_count": {
|
|
531
|
+
"$range": [
|
|
532
|
+
967,
|
|
533
|
+
4229
|
|
534
|
+
]
|
|
535
|
+
},
|
|
536
|
+
"bio_length": {
|
|
537
|
+
"$range": [
|
|
538
|
+
10,
|
|
539
|
+
149
|
|
540
|
+
]
|
|
541
|
+
},
|
|
542
|
+
"verified": [
|
|
543
|
+
false,
|
|
544
|
+
true
|
|
545
|
+
],
|
|
546
|
+
"content_niche": [
|
|
547
|
+
"lifestyle",
|
|
548
|
+
"tech",
|
|
549
|
+
"food",
|
|
550
|
+
"fitness",
|
|
551
|
+
"travel",
|
|
552
|
+
"comedy",
|
|
553
|
+
"news",
|
|
554
|
+
"art"
|
|
555
|
+
]
|
|
556
|
+
},
|
|
557
|
+
"groupKeys": [
|
|
558
|
+
{
|
|
559
|
+
"key": "community_id",
|
|
560
|
+
"count": 100,
|
|
561
|
+
"affectsEvents": [
|
|
562
|
+
"post created",
|
|
563
|
+
"comment posted",
|
|
564
|
+
"post liked",
|
|
565
|
+
"post shared"
|
|
566
|
+
]
|
|
567
|
+
}
|
|
568
|
+
],
|
|
569
|
+
"groupProps": {
|
|
570
|
+
"community_id": {
|
|
571
|
+
"name": {
|
|
572
|
+
"$type": "string"
|
|
573
|
+
},
|
|
574
|
+
"member_count": {
|
|
575
|
+
"$range": [
|
|
576
|
+
850,
|
|
577
|
+
4126
|
|
578
|
+
]
|
|
579
|
+
},
|
|
580
|
+
"category": [
|
|
581
|
+
"technology",
|
|
582
|
+
"entertainment",
|
|
583
|
+
"sports",
|
|
584
|
+
"politics",
|
|
585
|
+
"art",
|
|
586
|
+
"science"
|
|
587
|
+
],
|
|
588
|
+
"is_moderated": [
|
|
589
|
+
false,
|
|
590
|
+
true
|
|
591
|
+
]
|
|
592
|
+
}
|
|
593
|
+
},
|
|
594
|
+
"scdProps": {
|
|
595
|
+
"account_type": {
|
|
596
|
+
"type": "user",
|
|
597
|
+
"frequency": "month",
|
|
598
|
+
"timing": "fuzzy",
|
|
599
|
+
"max": 6,
|
|
600
|
+
"values": [
|
|
601
|
+
"personal",
|
|
602
|
+
"creator",
|
|
603
|
+
"business",
|
|
604
|
+
"verified"
|
|
605
|
+
]
|
|
606
|
+
},
|
|
607
|
+
"community_status": {
|
|
608
|
+
"type": "community_id",
|
|
609
|
+
"frequency": "month",
|
|
610
|
+
"timing": "fixed",
|
|
611
|
+
"max": 6,
|
|
612
|
+
"values": [
|
|
613
|
+
"new",
|
|
614
|
+
"growing",
|
|
615
|
+
"established",
|
|
616
|
+
"featured"
|
|
617
|
+
]
|
|
618
|
+
}
|
|
619
|
+
}
|
|
552
620
|
}
|
|
@@ -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("
|
|
13
|
+
/** @typedef {import("../../types").Dungeon} Config */
|
|
14
14
|
|
|
15
15
|
/*
|
|
16
16
|
* =====================================================================================
|
|
@@ -182,10 +182,23 @@ const config = {
|
|
|
182
182
|
hasAdSpend: false,
|
|
183
183
|
percentUsersBornInDataset: 50,
|
|
184
184
|
hasAvatar: true,
|
|
185
|
-
batchSize: 2_500_000,
|
|
186
185
|
concurrency: 1,
|
|
187
186
|
writeToDisk: false,
|
|
188
|
-
scdProps: {
|
|
187
|
+
scdProps: {
|
|
188
|
+
account_type: {
|
|
189
|
+
values: ["personal", "creator", "business", "verified"],
|
|
190
|
+
frequency: "month",
|
|
191
|
+
timing: "fuzzy",
|
|
192
|
+
max: 6
|
|
193
|
+
},
|
|
194
|
+
community_status: {
|
|
195
|
+
values: ["new", "growing", "established", "featured"],
|
|
196
|
+
frequency: "month",
|
|
197
|
+
timing: "fixed",
|
|
198
|
+
max: 6,
|
|
199
|
+
type: "community_id"
|
|
200
|
+
}
|
|
201
|
+
},
|
|
189
202
|
|
|
190
203
|
funnels: [
|
|
191
204
|
{
|
|
@@ -454,6 +454,9 @@
|
|
|
454
454
|
},
|
|
455
455
|
{
|
|
456
456
|
"event": "account deactivated",
|
|
457
|
+
"isChurnEvent": true,
|
|
458
|
+
"returnLikelihood": 0.2,
|
|
459
|
+
"isStrictEvent": true,
|
|
457
460
|
"properties": {
|
|
458
461
|
"reason": [
|
|
459
462
|
"found_alternative",
|
|
@@ -465,40 +468,6 @@
|
|
|
465
468
|
}
|
|
466
469
|
}
|
|
467
470
|
],
|
|
468
|
-
"superProps": {
|
|
469
|
-
"platform": [
|
|
470
|
-
"ios",
|
|
471
|
-
"android",
|
|
472
|
-
"web"
|
|
473
|
-
],
|
|
474
|
-
"membership_tier": [
|
|
475
|
-
"standard",
|
|
476
|
-
"gold",
|
|
477
|
-
"platinum"
|
|
478
|
-
]
|
|
479
|
-
},
|
|
480
|
-
"userProps": {
|
|
481
|
-
"customer_segment": [
|
|
482
|
-
"leisure_family"
|
|
483
|
-
],
|
|
484
|
-
"travel_frequency": [
|
|
485
|
-
"occasional",
|
|
486
|
-
"monthly",
|
|
487
|
-
"weekly"
|
|
488
|
-
],
|
|
489
|
-
"company_name": [
|
|
490
|
-
"none"
|
|
491
|
-
],
|
|
492
|
-
"preferred_destination": {
|
|
493
|
-
"$type": "string"
|
|
494
|
-
},
|
|
495
|
-
"avg_budget_per_night": {
|
|
496
|
-
"$range": [
|
|
497
|
-
98,
|
|
498
|
-
339
|
|
499
|
-
]
|
|
500
|
-
}
|
|
501
|
-
},
|
|
502
471
|
"funnels": [
|
|
503
472
|
{
|
|
504
473
|
"sequence": [
|
|
@@ -507,6 +476,7 @@
|
|
|
507
476
|
"hotel viewed",
|
|
508
477
|
"booking completed"
|
|
509
478
|
],
|
|
479
|
+
"name": "Onboarding to First Booking",
|
|
510
480
|
"isFirstFunnel": true,
|
|
511
481
|
"conversionRate": 35,
|
|
512
482
|
"timeToConvert": 72,
|
|
@@ -519,6 +489,7 @@
|
|
|
519
489
|
"price compared",
|
|
520
490
|
"booking completed"
|
|
521
491
|
],
|
|
492
|
+
"name": "Search to Book",
|
|
522
493
|
"conversionRate": 25,
|
|
523
494
|
"timeToConvert": 48,
|
|
524
495
|
"weight": 5
|
|
@@ -530,6 +501,7 @@
|
|
|
530
501
|
"amenity used",
|
|
531
502
|
"review submitted"
|
|
532
503
|
],
|
|
504
|
+
"name": "Full Stay Journey",
|
|
533
505
|
"conversionRate": 30,
|
|
534
506
|
"timeToConvert": 336,
|
|
535
507
|
"weight": 3
|
|
@@ -540,6 +512,7 @@
|
|
|
540
512
|
"loyalty points redeemed",
|
|
541
513
|
"review submitted"
|
|
542
514
|
],
|
|
515
|
+
"name": "Loyalty Engagement",
|
|
543
516
|
"conversionRate": 15,
|
|
544
517
|
"timeToConvert": 720,
|
|
545
518
|
"weight": 2
|
|
@@ -550,9 +523,58 @@
|
|
|
550
523
|
"booking completed",
|
|
551
524
|
"room upgrade selected"
|
|
552
525
|
],
|
|
526
|
+
"name": "Upsell Path",
|
|
553
527
|
"conversionRate": 20,
|
|
554
528
|
"timeToConvert": 24,
|
|
555
529
|
"weight": 2
|
|
556
530
|
}
|
|
557
|
-
]
|
|
531
|
+
],
|
|
532
|
+
"superProps": {
|
|
533
|
+
"platform": [
|
|
534
|
+
"ios",
|
|
535
|
+
"android",
|
|
536
|
+
"web"
|
|
537
|
+
],
|
|
538
|
+
"membership_tier": [
|
|
539
|
+
"standard",
|
|
540
|
+
"gold",
|
|
541
|
+
"platinum"
|
|
542
|
+
]
|
|
543
|
+
},
|
|
544
|
+
"userProps": {
|
|
545
|
+
"customer_segment": [
|
|
546
|
+
"leisure_family"
|
|
547
|
+
],
|
|
548
|
+
"travel_frequency": [
|
|
549
|
+
"occasional",
|
|
550
|
+
"monthly",
|
|
551
|
+
"weekly"
|
|
552
|
+
],
|
|
553
|
+
"company_name": [
|
|
554
|
+
"none"
|
|
555
|
+
],
|
|
556
|
+
"preferred_destination": {
|
|
557
|
+
"$type": "string"
|
|
558
|
+
},
|
|
559
|
+
"avg_budget_per_night": {
|
|
560
|
+
"$range": [
|
|
561
|
+
98,
|
|
562
|
+
339
|
|
563
|
+
]
|
|
564
|
+
}
|
|
565
|
+
},
|
|
566
|
+
"scdProps": {
|
|
567
|
+
"membership_tier": {
|
|
568
|
+
"type": "user",
|
|
569
|
+
"frequency": "month",
|
|
570
|
+
"timing": "fuzzy",
|
|
571
|
+
"max": 8,
|
|
572
|
+
"values": [
|
|
573
|
+
"member",
|
|
574
|
+
"silver",
|
|
575
|
+
"gold",
|
|
576
|
+
"platinum"
|
|
577
|
+
]
|
|
578
|
+
}
|
|
579
|
+
}
|
|
558
580
|
}
|
|
@@ -217,10 +217,16 @@ const config = {
|
|
|
217
217
|
hasAdSpend: false,
|
|
218
218
|
percentUsersBornInDataset: 35,
|
|
219
219
|
hasAvatar: true,
|
|
220
|
-
batchSize: 2_500_000,
|
|
221
220
|
concurrency: 1,
|
|
222
221
|
writeToDisk: false,
|
|
223
|
-
scdProps: {
|
|
222
|
+
scdProps: {
|
|
223
|
+
membership_tier: {
|
|
224
|
+
values: ["member", "silver", "gold", "platinum"],
|
|
225
|
+
frequency: "month",
|
|
226
|
+
timing: "fuzzy",
|
|
227
|
+
max: 8
|
|
228
|
+
}
|
|
229
|
+
},
|
|
224
230
|
mirrorProps: {},
|
|
225
231
|
lookupTables: [],
|
|
226
232
|
|
package/index.js
CHANGED
|
@@ -216,7 +216,7 @@ async function runDungeon(config) {
|
|
|
216
216
|
files: await extractFileInfo(storage, validatedConfig),
|
|
217
217
|
time: { start, end, delta, human },
|
|
218
218
|
operations: context.getOperations(),
|
|
219
|
-
eventCount: context.
|
|
219
|
+
eventCount: context.getStoredEventCount(),
|
|
220
220
|
userCount: context.getUserCount()
|
|
221
221
|
};
|
|
222
222
|
|
package/lib/core/context.js
CHANGED
|
@@ -71,6 +71,7 @@ function createRuntimeState() {
|
|
|
71
71
|
return {
|
|
72
72
|
operations: 0,
|
|
73
73
|
eventCount: 0,
|
|
74
|
+
storedEventCount: 0,
|
|
74
75
|
userCount: 0,
|
|
75
76
|
isBatchMode: false,
|
|
76
77
|
verbose: false
|
|
@@ -143,6 +144,14 @@ export function createContext(config, storage = null, timeConstants = {}) {
|
|
|
143
144
|
runtime.eventCount++;
|
|
144
145
|
},
|
|
145
146
|
|
|
147
|
+
incrementStoredEvents(count = 1) {
|
|
148
|
+
runtime.storedEventCount += count;
|
|
149
|
+
},
|
|
150
|
+
|
|
151
|
+
getStoredEventCount() {
|
|
152
|
+
return runtime.storedEventCount;
|
|
153
|
+
},
|
|
154
|
+
|
|
146
155
|
isBatchMode() {
|
|
147
156
|
return runtime.isBatchMode;
|
|
148
157
|
},
|
package/lib/core/storage.js
CHANGED
|
@@ -99,8 +99,10 @@ export async function createHookArray(arr = [], opts) {
|
|
|
99
99
|
// Fast path for passthrough hooks - no transformation needed
|
|
100
100
|
if (Array.isArray(item)) {
|
|
101
101
|
arr.push(...item);
|
|
102
|
+
if (type === "event" && context.incrementStoredEvents) context.incrementStoredEvents(item.length);
|
|
102
103
|
} else {
|
|
103
104
|
arr.push(item);
|
|
105
|
+
if (type === "event" && context.incrementStoredEvents) context.incrementStoredEvents(1);
|
|
104
106
|
}
|
|
105
107
|
} else {
|
|
106
108
|
// Slow path for actual transformation hooks
|
|
@@ -397,7 +397,10 @@ export async function userLoop(context) {
|
|
|
397
397
|
// Subscription events (trial, upgrade, cancel) must not be randomly dropped by decay
|
|
398
398
|
const userDecay = persona?.engagementDecay || globalEngagementDecay;
|
|
399
399
|
if (userDecay && userDecay.model !== 'none' && usersEvents.length > 0) {
|
|
400
|
-
|
|
400
|
+
// adjustedCreated is in FIXED time space, but ev.time is in PRESENT time (shifted).
|
|
401
|
+
// Shift adjustedCreated to present so daysSinceBirth reflects within-dataset age.
|
|
402
|
+
const adjustedCreatedPresent = adjustedCreated.add(context.TIME_SHIFT_SECONDS, 'seconds');
|
|
403
|
+
usersEvents = applyEngagementDecay(usersEvents, userDecay, adjustedCreatedPresent, context, chance);
|
|
401
404
|
}
|
|
402
405
|
|
|
403
406
|
// Feature 5: Subscription lifecycle — inject after decay (exempt from decay filtering)
|