@voltro/plugin-progression 0.0.0-stage → 0.88.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 (97) hide show
  1. package/CHANGELOG.md +24492 -0
  2. package/LICENSE +61 -0
  3. package/README.md +478 -2
  4. package/SECURITY.md +56 -0
  5. package/THIRD-PARTY-NOTICES.md +9841 -0
  6. package/dist/achievementComponents.js +91 -0
  7. package/dist/achievementStore.js +602 -0
  8. package/dist/achievementTables.entity.js +97 -0
  9. package/dist/achievements.d.ts +188 -0
  10. package/dist/achievements.js +204 -0
  11. package/dist/capture.js +63 -0
  12. package/dist/cmsQuests.d.ts +91 -0
  13. package/dist/cmsQuests.js +82 -0
  14. package/dist/components.d.ts +172 -0
  15. package/dist/components.js +4 -0
  16. package/dist/curve.d.ts +27 -0
  17. package/dist/curve.js +37 -0
  18. package/dist/daily.d.ts +152 -0
  19. package/dist/daily.js +125 -0
  20. package/dist/dailyStore.js +420 -0
  21. package/dist/dailySystem.fixture.js +137 -0
  22. package/dist/dailyTables.entity.js +89 -0
  23. package/dist/declarationFixtures.js +142 -0
  24. package/dist/errors.d.ts +13 -0
  25. package/dist/errors.js +19 -0
  26. package/dist/index.d.ts +1833 -0
  27. package/dist/index.js +19 -0
  28. package/dist/pass.d.ts +186 -0
  29. package/dist/pass.js +121 -0
  30. package/dist/passRules.js +95 -0
  31. package/dist/passStore.js +484 -0
  32. package/dist/passTables.entity.js +95 -0
  33. package/dist/plugin.js +1085 -0
  34. package/dist/port.js +4 -0
  35. package/dist/progressionStore.js +705 -0
  36. package/dist/questComponents.js +162 -0
  37. package/dist/questPort.d.ts +126 -0
  38. package/dist/questPort.js +4 -0
  39. package/dist/questRefresh.js +55 -0
  40. package/dist/questRefresh.server.js +125 -0
  41. package/dist/questRerollJournal.js +76 -0
  42. package/dist/questStore.js +591 -0
  43. package/dist/questTables.entity.js +116 -0
  44. package/dist/quests.d.ts +142 -0
  45. package/dist/quests.js +152 -0
  46. package/dist/rank-app/schedules/progression.dispatchRankClosures.cron.tsx +19 -0
  47. package/dist/rank-app/workflows/progression.closeRankSeason.workflow.server.tsx +10 -0
  48. package/dist/rank-app/workflows/progression.closeRankSeason.workflow.tsx +1 -0
  49. package/dist/rankClosure.d.ts +69 -0
  50. package/dist/rankClosure.js +34 -0
  51. package/dist/rankClosure.server.js +138 -0
  52. package/dist/rankClosureWorkflow.d.ts +34 -0
  53. package/dist/rankClosureWorkflow.js +15 -0
  54. package/dist/rankReader.server.js +56 -0
  55. package/dist/rankRewardParent.server.js +64 -0
  56. package/dist/rankSeasons.d.ts +144 -0
  57. package/dist/rankSeasons.js +90 -0
  58. package/dist/rankStore.js +520 -0
  59. package/dist/rankSystem.fixture.js +169 -0
  60. package/dist/rankTables.entity.js +100 -0
  61. package/dist/ranks.d.ts +167 -0
  62. package/dist/ranks.js +218 -0
  63. package/dist/resourceStore.js +463 -0
  64. package/dist/resourceTables.entity.js +88 -0
  65. package/dist/resources.d.ts +105 -0
  66. package/dist/resources.js +59 -0
  67. package/dist/reward-app/schedules/progression.dispatchRewards.cron.tsx +19 -0
  68. package/dist/reward-app/workflows/progression.deliverReward.workflow.server.tsx +10 -0
  69. package/dist/reward-app/workflows/progression.deliverReward.workflow.tsx +1 -0
  70. package/dist/reward.d.ts +27 -0
  71. package/dist/reward.js +38 -0
  72. package/dist/rewardDelivery.d.ts +163 -0
  73. package/dist/rewardDelivery.js +37 -0
  74. package/dist/rewardDelivery.server.js +429 -0
  75. package/dist/rewardDeliveryRecord.js +47 -0
  76. package/dist/rewardDeliveryWorkflow.d.ts +36 -0
  77. package/dist/rewardDeliveryWorkflow.js +15 -0
  78. package/dist/rpc.d.ts +880 -0
  79. package/dist/rpc.js +497 -0
  80. package/dist/server.d.ts +2812 -0
  81. package/dist/server.js +21 -0
  82. package/dist/stats.js +44 -0
  83. package/dist/strategies.d.ts +131 -0
  84. package/dist/strategies.js +4 -0
  85. package/dist/systemFixtures.js +473 -0
  86. package/dist/tables.entity.js +154 -0
  87. package/dist/testing.d.ts +1566 -0
  88. package/dist/testing.js +11 -0
  89. package/dist/track.js +71 -0
  90. package/dist/tutorial.d.ts +157 -0
  91. package/dist/tutorial.js +109 -0
  92. package/dist/tutorialStore.js +495 -0
  93. package/dist/tutorialSystem.fixture.js +99 -0
  94. package/dist/tutorialTables.entity.js +90 -0
  95. package/dist/web.d.ts +363 -0
  96. package/dist/web.js +6 -0
  97. package/package.json +167 -4
@@ -0,0 +1,1566 @@
1
+ import { Context } from 'effect';
2
+ import { Effect } from 'effect';
3
+ import { Layer } from 'effect';
4
+ import { PluginPrivacyTarget } from '@voltro/protocol';
5
+ import { Schema } from 'effect';
6
+ import { Subject } from '@voltro/protocol';
7
+ import { YieldableError } from 'effect/Cause';
8
+
9
+ declare type AchievementCondition = StatThreshold | CompositeCondition;
10
+
11
+ declare interface AchievementEvaluation {
12
+ readonly met: boolean;
13
+ readonly progress: readonly AchievementProgress[];
14
+ }
15
+
16
+ declare type AchievementEvaluator = (input: {
17
+ readonly condition: AchievementCondition;
18
+ readonly stats: readonly AchievementStat[];
19
+ }) => AchievementEvaluation;
20
+
21
+ export declare const achievementEvaluatorSystemFixture: Readonly<{
22
+ kind: "slot";
23
+ defaultImplementation: AchievementEvaluator;
24
+ defaultProbe: {
25
+ run: () => Effect.Effect< AchievementEvaluation, never, never>;
26
+ expected: {
27
+ met: boolean;
28
+ progress: {
29
+ stat: string;
30
+ period: string;
31
+ seasonId: null;
32
+ value: string;
33
+ target: string;
34
+ met: boolean;
35
+ }[];
36
+ };
37
+ };
38
+ overrideProbe: {
39
+ run: () => Effect.Effect< AchievementEvaluation, never, never>;
40
+ expected: {
41
+ met: boolean;
42
+ progress: {
43
+ stat: string;
44
+ period: string;
45
+ seasonId: null;
46
+ value: string;
47
+ target: string;
48
+ met: boolean;
49
+ }[];
50
+ };
51
+ };
52
+ }>;
53
+
54
+ export declare const achievementFakeLayer: Layer.Layer<FixturePorts, never, never>;
55
+
56
+ declare interface AchievementPlatform {
57
+ readonly steam?: string;
58
+ readonly gameCenter?: string;
59
+ readonly playGames?: string;
60
+ }
61
+
62
+ declare class AchievementPort extends AchievementPort_base {
63
+ }
64
+
65
+ declare const AchievementPort_base: Context.ServiceClass<AchievementPort, "@voltro/AchievementPort", AchievementService>;
66
+
67
+ export declare const achievementPortSystemFixture: Readonly<{
68
+ kind: "port";
69
+ tag: typeof AchievementPort;
70
+ fakeLayer: Layer.Layer<FixturePorts, never, never>;
71
+ probe: {
72
+ run: () => Effect.Effect<{
73
+ original: boolean;
74
+ achievements: {
75
+ id: string;
76
+ tier: string;
77
+ unlocked: boolean;
78
+ value: string | undefined;
79
+ }[];
80
+ }, ProgressionError, never>;
81
+ expected: {
82
+ original: boolean;
83
+ achievements: {
84
+ id: string;
85
+ tier: string;
86
+ unlocked: boolean;
87
+ value: string;
88
+ }[];
89
+ };
90
+ };
91
+ }>;
92
+
93
+ declare interface AchievementProgress extends AchievementStat {
94
+ readonly target: string;
95
+ readonly met: boolean;
96
+ }
97
+
98
+ declare interface AchievementReceipt {
99
+ readonly operationId: string;
100
+ readonly throughSequence: number;
101
+ readonly unlockedIds: readonly string[];
102
+ readonly rewardsQueued: number;
103
+ readonly at: number;
104
+ }
105
+
106
+ declare interface AchievementService {
107
+ readonly evaluate: (subject: Subject, input: EvaluateAchievementsInput) => Effect.Effect<AchievementReceipt, ProgressionError>;
108
+ readonly mine: (subject: Subject) => Effect.Effect<readonly PlayerAchievement[], ProgressionError>;
109
+ readonly exportSubject: (target: PluginPrivacyTarget) => Effect.Effect<unknown, ProgressionError>;
110
+ readonly eraseSubject: (target: PluginPrivacyTarget) => Effect.Effect<void, ProgressionError>;
111
+ }
112
+
113
+ declare interface AchievementStat {
114
+ readonly stat: string;
115
+ readonly period: 'lifetime' | 'season';
116
+ readonly seasonId: string | null;
117
+ readonly value: string;
118
+ }
119
+
120
+ declare interface AchievementStatEvent extends AchievementStat {
121
+ readonly operationId: string;
122
+ readonly sequence: number;
123
+ readonly at: number;
124
+ }
125
+
126
+ declare interface AchievementStatHistory {
127
+ readonly version: string;
128
+ readonly throughSequence: number;
129
+ readonly initial: readonly AchievementStat[];
130
+ readonly events: readonly AchievementStatEvent[];
131
+ }
132
+
133
+ declare class AchievementStatSource extends AchievementStatSource_base {
134
+ }
135
+
136
+ declare const AchievementStatSource_base: Context.ServiceClass<AchievementStatSource, "@voltro/AchievementStatSource", AchievementStatSourceService>;
137
+
138
+ export declare const achievementStatSourceFakeLayer: Layer.Layer<FixturePorts, never, never>;
139
+
140
+ declare interface AchievementStatSourceService {
141
+ readonly history: (subject: Subject, input: {
142
+ readonly tenantId: string;
143
+ readonly ownerId: string;
144
+ readonly limit: number;
145
+ }) => Effect.Effect<AchievementStatHistory, ProgressionError>;
146
+ }
147
+
148
+ export declare const achievementStatSourceSystemFixture: Readonly<{
149
+ kind: "port";
150
+ tag: typeof AchievementStatSource;
151
+ fakeLayer: Layer.Layer<FixturePorts, never, never>;
152
+ probe: {
153
+ run: () => Effect.Effect<{
154
+ stat: string;
155
+ value: string;
156
+ }[], ProgressionError, never>;
157
+ expected: {
158
+ stat: string;
159
+ value: string;
160
+ }[];
161
+ };
162
+ }>;
163
+
164
+ declare interface ApplyStatInput {
165
+ readonly tenantId: string;
166
+ readonly ownerId: string;
167
+ readonly stat: string;
168
+ readonly period: 'lifetime' | 'season';
169
+ readonly seasonId?: string | null;
170
+ readonly operator: StatOperator;
171
+ readonly operand: ProgressValue;
172
+ readonly requestId: string;
173
+ readonly source: string;
174
+ readonly origin: string;
175
+ }
176
+
177
+ declare interface ApplyXpInput {
178
+ readonly tenantId: string;
179
+ readonly ownerId: string;
180
+ readonly trackId: string;
181
+ readonly amount: ProgressValue;
182
+ readonly requestId: string;
183
+ readonly source: string;
184
+ readonly origin: string;
185
+ }
186
+
187
+ declare interface AssignQuestsInput {
188
+ readonly tenantId: string;
189
+ readonly ownerId: string;
190
+ readonly poolId: string;
191
+ readonly requestId: string;
192
+ readonly expectedPoolDigest?: string;
193
+ readonly windowId: string;
194
+ readonly from: number;
195
+ readonly until: number;
196
+ readonly timezone: string;
197
+ readonly seed: number;
198
+ }
199
+
200
+ declare interface CompositeCondition {
201
+ readonly kind: 'composite';
202
+ readonly mode: 'all' | 'any';
203
+ readonly conditions: readonly AchievementCondition[];
204
+ }
205
+
206
+ declare interface DailyClaimInput {
207
+ readonly calendarId: string;
208
+ readonly requestId: string;
209
+ }
210
+
211
+ declare interface DailyClaimPlan {
212
+ readonly dayIndex: number;
213
+ readonly streak: number;
214
+ readonly protectionRemaining: number;
215
+ readonly cycle: number;
216
+ }
217
+
218
+ declare type DailyClaimPolicy = (input: DailyClaimPolicyContext) => DailyClaimPlan;
219
+
220
+ declare interface DailyClaimPolicyContext {
221
+ readonly calendar: LoginCalendar;
222
+ readonly previous: DailyState | null;
223
+ readonly window: DailyWindow;
224
+ readonly at: number;
225
+ }
226
+
227
+ export declare const dailyClaimPolicySystemFixture: Readonly<{
228
+ kind: "slot";
229
+ defaultImplementation: DailyClaimPolicy;
230
+ defaultProbe: {
231
+ run: () => Effect.Effect<{
232
+ dayIndex: number;
233
+ streak: number;
234
+ }, never, never>;
235
+ expected: {
236
+ dayIndex: number;
237
+ streak: number;
238
+ };
239
+ };
240
+ overrideProbe: {
241
+ run: () => Effect.Effect<{
242
+ dayIndex: number;
243
+ streak: number;
244
+ }, never, never>;
245
+ expected: {
246
+ dayIndex: number;
247
+ streak: number;
248
+ };
249
+ };
250
+ }>;
251
+
252
+ declare interface DailyProfile {
253
+ readonly timezone: string;
254
+ readonly version: string;
255
+ }
256
+
257
+ declare class DailyProfileSource extends DailyProfileSource_base {
258
+ }
259
+
260
+ declare const DailyProfileSource_base: Context.ServiceClass<DailyProfileSource, "@voltro/DailyProfileSource", DailyProfileSourceService>;
261
+
262
+ export declare const dailyProfileSourceFakeLayer: Layer.Layer<DailyProfileSource, never, never>;
263
+
264
+ declare interface DailyProfileSourceService {
265
+ readonly read: (subject: Subject, scope: {
266
+ readonly tenantId: string;
267
+ readonly ownerId: string;
268
+ }) => Effect.Effect<DailyProfile, ProgressionError>;
269
+ }
270
+
271
+ export declare const dailyProfileSourceSystemFixture: Readonly<{
272
+ kind: "port";
273
+ tag: typeof DailyProfileSource;
274
+ fakeLayer: Layer.Layer<DailyProfileSource, never, never>;
275
+ probe: {
276
+ run: () => Effect.Effect< DailyProfile, ProgressionError, never>;
277
+ expected: {
278
+ timezone: string;
279
+ version: string;
280
+ };
281
+ };
282
+ }>;
283
+
284
+ declare interface DailyReceipt {
285
+ readonly operationId: string;
286
+ readonly claimId: string;
287
+ readonly calendarId: string;
288
+ readonly dayKey: string;
289
+ readonly after: DailyState;
290
+ readonly rewardsQueued: number;
291
+ readonly at: number;
292
+ }
293
+
294
+ declare interface DailyState extends DailyWindow {
295
+ readonly calendarId: string;
296
+ readonly version: number;
297
+ readonly dayIndex: number;
298
+ readonly streak: number;
299
+ readonly protectionRemaining: number;
300
+ readonly cycle: number;
301
+ readonly at: number;
302
+ }
303
+
304
+ declare interface DailyWindow {
305
+ readonly dayKey: string;
306
+ readonly dayOrdinal: number;
307
+ readonly from: number;
308
+ readonly until: number;
309
+ readonly timezone: string;
310
+ }
311
+
312
+ export declare const defaultPassCatchUp: PassCatchUp;
313
+
314
+ export declare const defaultQuestProgressResolver: QuestProgressResolver;
315
+
316
+ /** Deterministic weighted selection without replacement; a trusted seed is not a security RNG. */
317
+ export declare const defaultQuestSelector: QuestSelector;
318
+
319
+ /** A read-only displayed score; it never writes or claims to decay the Ratings SQL pool. */
320
+ export declare const defaultRankDecay: RankDecayResolver;
321
+
322
+ export declare const defaultRankGrade: RankGradeResolver;
323
+
324
+ export declare const defaultRankScore: RankScoreResolver;
325
+
326
+ export declare const defaultRankSeasonReset: RankSeasonReset;
327
+
328
+ export declare const defaultResourceRegen: ResourceRegenResolver;
329
+
330
+ export declare const defaultTutorialStepPolicy: TutorialStepPolicy;
331
+
332
+ export declare const defineQuestPool: (input: QuestPoolDefinition) => QuestPool;
333
+
334
+ export declare const defineRegenResource: (input: RegenResourceDefinition | RegenResource) => RegenResource;
335
+
336
+ declare interface EvaluateAchievementsInput {
337
+ readonly tenantId: string;
338
+ readonly ownerId: string;
339
+ readonly requestId: string;
340
+ }
341
+
342
+ declare type FixturePorts = ProgressionPort | QuestPort | QuestSource | RegenResourcePort | AchievementPort | AchievementStatSource | SeasonPassPort;
343
+
344
+ declare type InitializeResourceInput = Omit<ResourceChangeInput, 'amount'>;
345
+
346
+ declare interface LevelCurve {
347
+ readonly thresholds: readonly string[];
348
+ }
349
+
350
+ declare interface LevelReward {
351
+ readonly level: number;
352
+ readonly reward: ProgressionReward;
353
+ }
354
+
355
+ declare interface LoginCalendar {
356
+ readonly id: string;
357
+ readonly version: number;
358
+ readonly days: readonly (readonly ProgressionReward[])[];
359
+ readonly streakProtection: number;
360
+ }
361
+
362
+ /** Test-only actual installed login calendar on a private store; the profile
363
+ * source is an explicit fixture timezone, not a production profile provider. */
364
+ export declare const loginCalendarFakeLayer: Layer.Layer<LoginCalendarPort>;
365
+
366
+ declare class LoginCalendarPort extends LoginCalendarPort_base {
367
+ }
368
+
369
+ declare const LoginCalendarPort_base: Context.ServiceClass<LoginCalendarPort, "@voltro/LoginCalendarPort", LoginCalendarService>;
370
+
371
+ export declare const loginCalendarPortSystemFixture: Readonly<{
372
+ kind: "port";
373
+ tag: typeof LoginCalendarPort;
374
+ fakeLayer: Layer.Layer<LoginCalendarPort, never, never>;
375
+ probe: {
376
+ run: () => Effect.Effect<{
377
+ original: boolean;
378
+ rewardsQueued: number;
379
+ calendars: {
380
+ claimed: boolean;
381
+ streak: number;
382
+ dayIndex: number;
383
+ }[];
384
+ }, ProgressionError, never>;
385
+ expected: {
386
+ original: boolean;
387
+ rewardsQueued: number;
388
+ calendars: {
389
+ claimed: boolean;
390
+ streak: number;
391
+ dayIndex: number;
392
+ }[];
393
+ };
394
+ };
395
+ }>;
396
+
397
+ declare interface LoginCalendarService {
398
+ readonly claim: (subject: Subject, input: DailyClaimInput) => Effect.Effect<DailyReceipt, ProgressionError>;
399
+ readonly mine: (subject: Subject) => Effect.Effect<readonly PlayerDaily[], ProgressionError>;
400
+ readonly exportSubject: (target: PluginPrivacyTarget) => Effect.Effect<unknown, ProgressionError>;
401
+ readonly eraseSubject: (target: PluginPrivacyTarget) => Effect.Effect<void, ProgressionError>;
402
+ }
403
+
404
+ declare type PassCatchUp = (input: PassCatchUpContext) => ProgressValue;
405
+
406
+ declare interface PassCatchUpContext {
407
+ readonly pass: SeasonPass;
408
+ readonly amount: string;
409
+ readonly at: number;
410
+ }
411
+
412
+ export declare const passCatchUpSystemFixture: Readonly<{
413
+ kind: "slot";
414
+ defaultImplementation: PassCatchUp;
415
+ defaultProbe: {
416
+ run: () => Effect.Effect<string, never, never>;
417
+ expected: string;
418
+ };
419
+ overrideProbe: {
420
+ run: () => Effect.Effect<string, never, never>;
421
+ expected: string;
422
+ };
423
+ }>;
424
+
425
+ declare interface PassClaimInput {
426
+ readonly passId: string;
427
+ readonly tier: number;
428
+ readonly track: PassTrack;
429
+ readonly requestId: string;
430
+ }
431
+
432
+ declare interface PassCloseInput {
433
+ readonly tenantId: string;
434
+ readonly ownerId: string;
435
+ readonly passId: string;
436
+ readonly requestId: string;
437
+ }
438
+
439
+ export declare const passFakeLayer: Layer.Layer<FixturePorts, never, never>;
440
+
441
+ export declare const passFixture: () => Readonly<{
442
+ pass: SeasonPass;
443
+ state: PassState;
444
+ passCatchUp: Readonly<{
445
+ pass: SeasonPass;
446
+ amount: "100";
447
+ at: number;
448
+ }>;
449
+ }>;
450
+
451
+ export declare const passPortSystemFixture: Readonly<{
452
+ kind: "port";
453
+ tag: typeof SeasonPassPort;
454
+ fakeLayer: Layer.Layer<FixturePorts, never, never>;
455
+ probe: {
456
+ run: () => Effect.Effect<{
457
+ original: boolean;
458
+ claimedFree: string;
459
+ rewardsQueued: number;
460
+ passes: {
461
+ xp: string;
462
+ tier: number;
463
+ claimedFree: string;
464
+ }[];
465
+ }, ProgressionError, never>;
466
+ expected: {
467
+ original: boolean;
468
+ claimedFree: string;
469
+ rewardsQueued: number;
470
+ passes: {
471
+ xp: string;
472
+ tier: number;
473
+ claimedFree: string;
474
+ }[];
475
+ };
476
+ };
477
+ }>;
478
+
479
+ declare interface PassPremiumInput {
480
+ readonly tenantId: string;
481
+ readonly ownerId: string;
482
+ readonly passId: string;
483
+ readonly offerId: string;
484
+ readonly fulfillmentId: string;
485
+ readonly requestId: string;
486
+ }
487
+
488
+ declare interface PassReceipt {
489
+ readonly operationId: string;
490
+ readonly kind: 'xp' | 'premium' | 'claim' | 'close';
491
+ readonly after: PassState;
492
+ readonly claims: readonly PassTierClaim[];
493
+ readonly rewardsQueued: number;
494
+ readonly at: number;
495
+ }
496
+
497
+ declare interface PassState {
498
+ readonly passId: string;
499
+ readonly version: number;
500
+ readonly xp: string;
501
+ readonly claimedFree: string;
502
+ readonly claimedPremium: string;
503
+ readonly premium: boolean;
504
+ readonly purchasedAt: number | null;
505
+ readonly fulfillmentId: string | null;
506
+ readonly closed: boolean;
507
+ readonly updatedAt: number;
508
+ }
509
+
510
+ declare interface PassTierClaim {
511
+ readonly tier: number;
512
+ readonly track: PassTrack;
513
+ readonly rewards: readonly ProgressionReward[];
514
+ }
515
+
516
+ declare type PassTrack = 'free' | 'premium';
517
+
518
+ declare interface PassXpInput {
519
+ readonly tenantId: string;
520
+ readonly ownerId: string;
521
+ readonly passId: string;
522
+ readonly amount: ProgressValue;
523
+ readonly source: string;
524
+ readonly originId: string;
525
+ readonly requestId: string;
526
+ }
527
+
528
+ declare interface PlayerAchievement {
529
+ readonly achievementId: string;
530
+ readonly version: number;
531
+ readonly tierId: string;
532
+ readonly unlocked: boolean;
533
+ readonly unlockedAt: number | null;
534
+ readonly progress: readonly AchievementProgress[];
535
+ readonly platform: AchievementPlatform | null;
536
+ }
537
+
538
+ declare interface PlayerDaily {
539
+ readonly calendarId: string;
540
+ readonly version: number;
541
+ readonly dayKey: string;
542
+ readonly timezone: string;
543
+ readonly from: number;
544
+ readonly until: number;
545
+ readonly observedAt: number;
546
+ readonly claimed: boolean;
547
+ readonly dayIndex: number;
548
+ readonly streak: number;
549
+ readonly protectionRemaining: number;
550
+ readonly reward: readonly ProgressionReward[];
551
+ }
552
+
553
+ declare interface PlayerPass extends PassState {
554
+ readonly tier: number;
555
+ readonly from: number;
556
+ readonly until: number;
557
+ readonly observedAt: number;
558
+ readonly active: boolean;
559
+ readonly premiumOffer: string | null;
560
+ readonly claimable: readonly PassTierClaim[];
561
+ }
562
+
563
+ declare interface PlayerQuest {
564
+ readonly id: string;
565
+ readonly poolId: string;
566
+ readonly windowId: string;
567
+ readonly quest: QuestDefinition;
568
+ readonly progress: readonly number[];
569
+ readonly state: 'active' | 'completed';
570
+ readonly assignedAt: number;
571
+ readonly expiresAt: number;
572
+ readonly rerollsUsed: number;
573
+ readonly rerollsAllowed: number;
574
+ }
575
+
576
+ declare interface PlayerRank {
577
+ readonly ladderId: string;
578
+ readonly version: number;
579
+ readonly pool: string;
580
+ readonly games: number;
581
+ readonly placementsRemaining: number;
582
+ readonly rawScore: number;
583
+ readonly score: number;
584
+ readonly grade: RankGrade | null;
585
+ readonly ratingUpdatedAt: number | null;
586
+ readonly observedAt: number;
587
+ readonly rulesVersion: string;
588
+ }
589
+
590
+ declare interface PlayerResource {
591
+ readonly resourceId: string;
592
+ readonly value: string;
593
+ readonly max: string;
594
+ readonly initialized: boolean;
595
+ readonly observedAt: number;
596
+ readonly nextRegenAt: number | null;
597
+ readonly refillOffer?: string;
598
+ }
599
+
600
+ declare interface PlayerStat {
601
+ readonly stat: string;
602
+ readonly period: 'lifetime' | 'season';
603
+ readonly seasonId: string | null;
604
+ readonly value: string;
605
+ readonly updatedAt: number;
606
+ }
607
+
608
+ declare interface PlayerTrack {
609
+ readonly trackId: string;
610
+ readonly xp: string;
611
+ readonly level: number;
612
+ readonly prestige: number;
613
+ readonly updatedAt: number | null;
614
+ }
615
+
616
+ declare interface PlayerTutorial extends TutorialState {
617
+ readonly nextStep: string | null;
618
+ readonly skippable: boolean;
619
+ readonly hints: string | null;
620
+ }
621
+
622
+ declare type ProgressionChange = {
623
+ readonly kind: 'xp';
624
+ readonly trackId: string;
625
+ readonly xp: string;
626
+ readonly delta: string;
627
+ readonly fromLevel: number;
628
+ readonly toLevel: number;
629
+ } | {
630
+ readonly kind: 'stat';
631
+ readonly stat: string;
632
+ readonly period: 'lifetime' | 'season';
633
+ readonly seasonId: string | null;
634
+ readonly value: string;
635
+ readonly operator: StatOperator;
636
+ };
637
+
638
+ declare class ProgressionError extends ProgressionError_base {
639
+ }
640
+
641
+ declare const ProgressionError_base: Schema.Class<ProgressionError, Schema.TaggedStruct<"ProgressionError", {
642
+ readonly code: Schema.Literals<readonly ["invalid_input", "invalid_record", "invalid_curve", "invalid_reward", "invalid_track", "invalid_stat", "overflow", "insufficient_resource", "forbidden", "conflict", "erased", "not_found", "limit_exceeded", "unavailable"]>;
643
+ }>, YieldableError>;
644
+
645
+ export declare const progressionFakeLayer: Layer.Layer<FixturePorts, never, never>;
646
+
647
+ export declare const progressionFixture: () => Readonly<{
648
+ curve: LevelCurve;
649
+ track: ProgressionTrack;
650
+ xpCurve: Readonly<{
651
+ xp: "100";
652
+ curve: LevelCurve;
653
+ }>;
654
+ rewardResolver: Readonly<{
655
+ track: ProgressionTrack;
656
+ fromLevel: 1;
657
+ toLevel: 2;
658
+ }>;
659
+ }>;
660
+
661
+ declare class ProgressionPort extends ProgressionPort_base {
662
+ }
663
+
664
+ declare const ProgressionPort_base: Context.ServiceClass<ProgressionPort, "@voltro/ProgressionPort", ProgressionService>;
665
+
666
+ export declare const progressionPortSystemFixture: Readonly<{
667
+ kind: "port";
668
+ tag: typeof ProgressionPort;
669
+ fakeLayer: Layer.Layer<FixturePorts, never, never>;
670
+ probe: {
671
+ run: () => Effect.Effect<{
672
+ original: boolean;
673
+ tracks: {
674
+ xp: string;
675
+ level: number;
676
+ }[];
677
+ stats: string[];
678
+ rewardsQueued: number;
679
+ }, ProgressionError, never>;
680
+ expected: {
681
+ original: boolean;
682
+ tracks: {
683
+ xp: string;
684
+ level: number;
685
+ }[];
686
+ stats: string[];
687
+ rewardsQueued: number;
688
+ };
689
+ };
690
+ }>;
691
+
692
+ declare interface ProgressionReceipt {
693
+ readonly operationId: string;
694
+ readonly at: number;
695
+ readonly change: ProgressionChange;
696
+ readonly rewardsQueued: number;
697
+ }
698
+
699
+ declare type ProgressionReward = {
700
+ readonly kind: 'currency';
701
+ readonly currency: string;
702
+ readonly amount: string;
703
+ } | {
704
+ readonly kind: 'item';
705
+ readonly itemId: string;
706
+ readonly qty: number;
707
+ } | {
708
+ readonly kind: 'xp';
709
+ readonly trackId: string;
710
+ readonly amount: string;
711
+ };
712
+
713
+ declare interface ProgressionService {
714
+ readonly applyXp: (subject: Subject, input: ApplyXpInput) => Effect.Effect<ProgressionReceipt, ProgressionError>;
715
+ readonly applyStat: (subject: Subject, input: ApplyStatInput) => Effect.Effect<ProgressionReceipt, ProgressionError>;
716
+ readonly mine: (subject: Subject) => Effect.Effect<readonly PlayerTrack[], ProgressionError>;
717
+ readonly stats: (subject: Subject) => Effect.Effect<readonly PlayerStat[], ProgressionError>;
718
+ readonly exportSubject: (target: PluginPrivacyTarget) => Effect.Effect<unknown, ProgressionError>;
719
+ readonly eraseSubject: (target: PluginPrivacyTarget) => Effect.Effect<void, ProgressionError>;
720
+ }
721
+
722
+ declare interface ProgressionTrack {
723
+ readonly id: string;
724
+ readonly version: number;
725
+ readonly xpCurve: LevelCurve;
726
+ readonly sources: readonly string[];
727
+ readonly rewards: Readonly<Record<string, readonly ProgressionReward[]>>;
728
+ readonly every: Readonly<Record<string, readonly ProgressionReward[]>>;
729
+ }
730
+
731
+ declare type ProgressValue = string | number | bigint;
732
+
733
+ declare interface QuestDefinition {
734
+ readonly id: string;
735
+ readonly titleKey?: string;
736
+ readonly objectives: readonly QuestObjective[];
737
+ readonly reward: readonly ProgressionReward[];
738
+ }
739
+
740
+ export declare const questFakeLayer: Layer.Layer<FixturePorts, never, never>;
741
+
742
+ declare type QuestObjective = {
743
+ readonly stat: string;
744
+ readonly target: number;
745
+ } | {
746
+ readonly event: string;
747
+ readonly target: number;
748
+ readonly where?: Readonly<Record<string, QuestScalar>>;
749
+ };
750
+
751
+ declare interface QuestPool extends QuestPoolDefinition {
752
+ readonly version: number;
753
+ readonly rerolls: number;
754
+ readonly weights: Readonly<Record<string, number>>;
755
+ }
756
+
757
+ declare interface QuestPoolDefinition {
758
+ readonly id: string;
759
+ readonly version?: number;
760
+ readonly slots: number;
761
+ readonly rerolls?: number;
762
+ readonly refresh: {
763
+ readonly cron: string;
764
+ readonly timezone: string;
765
+ };
766
+ readonly quests: readonly QuestDefinition[];
767
+ readonly weights?: Readonly<Record<string, number>>;
768
+ }
769
+
770
+ declare class QuestPort extends QuestPort_base {
771
+ }
772
+
773
+ declare const QuestPort_base: Context.ServiceClass<QuestPort, "@voltro/QuestPort", QuestService>;
774
+
775
+ export declare const questPortSystemFixture: Readonly<{
776
+ kind: "port";
777
+ tag: typeof QuestPort;
778
+ fakeLayer: Layer.Layer<FixturePorts, never, never>;
779
+ probe: {
780
+ run: () => Effect.Effect<{
781
+ original: boolean;
782
+ quests: {
783
+ progress: readonly number[];
784
+ state: "completed" | "active";
785
+ }[];
786
+ }, ProgressionError, never>;
787
+ expected: {
788
+ original: boolean;
789
+ quests: {
790
+ progress: number[];
791
+ state: string;
792
+ }[];
793
+ };
794
+ };
795
+ }>;
796
+
797
+ declare interface QuestProgressContext {
798
+ readonly quest: QuestDefinition;
799
+ readonly progress: readonly number[];
800
+ readonly signal: QuestSignal;
801
+ }
802
+
803
+ declare type QuestProgressResolver = (context: QuestProgressContext) => readonly number[];
804
+
805
+ export declare const questProgressResolverSystemFixture: Readonly<{
806
+ kind: "slot";
807
+ defaultImplementation: QuestProgressResolver;
808
+ defaultProbe: {
809
+ run: () => Effect.Effect<readonly number[], never, never>;
810
+ expected: number[];
811
+ };
812
+ overrideProbe: {
813
+ run: () => Effect.Effect<readonly number[], never, never>;
814
+ expected: number[];
815
+ };
816
+ }>;
817
+
818
+ declare interface QuestReceipt {
819
+ readonly operationId: string;
820
+ readonly kind: 'assign' | 'record' | 'reroll';
821
+ readonly assignmentIds: readonly string[];
822
+ readonly completedIds: readonly string[];
823
+ readonly rewardsQueued: number;
824
+ readonly at: number;
825
+ }
826
+
827
+ declare type QuestScalar = string | number | boolean | null;
828
+
829
+ declare type QuestSelector = (context: QuestSelectorContext) => readonly string[];
830
+
831
+ declare interface QuestSelectorContext {
832
+ readonly pool: QuestPool;
833
+ readonly count: number;
834
+ readonly seed: number;
835
+ readonly excluded: readonly string[];
836
+ }
837
+
838
+ export declare const questSelectorSystemFixture: Readonly<{
839
+ kind: "slot";
840
+ defaultImplementation: QuestSelector;
841
+ defaultProbe: {
842
+ run: () => Effect.Effect<readonly string[], never, never>;
843
+ expected: string[];
844
+ };
845
+ overrideProbe: {
846
+ run: () => Effect.Effect<readonly string[], never, never>;
847
+ expected: string[];
848
+ };
849
+ }>;
850
+
851
+ declare interface QuestService {
852
+ readonly assign: (subject: Subject, input: AssignQuestsInput) => Effect.Effect<QuestReceipt, ProgressionError>;
853
+ readonly record: (subject: Subject, input: RecordQuestInput) => Effect.Effect<QuestReceipt, ProgressionError>;
854
+ readonly reroll: (subject: Subject, input: RerollQuestInput) => Effect.Effect<QuestReceipt, ProgressionError>;
855
+ readonly mine: (subject: Subject) => Effect.Effect<readonly PlayerQuest[], ProgressionError>;
856
+ readonly exportSubject: (target: PluginPrivacyTarget) => Effect.Effect<unknown, ProgressionError>;
857
+ readonly eraseSubject: (target: PluginPrivacyTarget) => Effect.Effect<void, ProgressionError>;
858
+ }
859
+
860
+ declare type QuestSignal = {
861
+ readonly kind: 'stat';
862
+ readonly stat: string;
863
+ readonly delta: string;
864
+ } | {
865
+ readonly kind: 'event';
866
+ readonly event: string;
867
+ readonly data: Readonly<Record<string, QuestScalar>>;
868
+ };
869
+
870
+ declare type QuestSignalInput = {
871
+ readonly kind: 'stat';
872
+ readonly stat: string;
873
+ readonly delta: ProgressValue;
874
+ } | {
875
+ readonly kind: 'event';
876
+ readonly event: string;
877
+ readonly data?: Readonly<Record<string, QuestScalar>>;
878
+ };
879
+
880
+ declare class QuestSource extends QuestSource_base {
881
+ }
882
+
883
+ declare const QuestSource_base: Context.ServiceClass<QuestSource, "@voltro/QuestSource", QuestSourceService>;
884
+
885
+ export declare const questSourceFakeLayer: Layer.Layer<FixturePorts, never, never>;
886
+
887
+ declare interface QuestSourceScope {
888
+ readonly tenantId: string;
889
+ readonly channel: string;
890
+ readonly locale: string;
891
+ }
892
+
893
+ declare interface QuestSourceService {
894
+ readonly read: (scope: QuestSourceScope) => Effect.Effect<{
895
+ readonly revision: string;
896
+ readonly pools: readonly QuestPool[];
897
+ }, ProgressionError>;
898
+ }
899
+
900
+ export declare const questSourceSystemFixture: Readonly<{
901
+ kind: "port";
902
+ tag: typeof QuestSource;
903
+ fakeLayer: Layer.Layer<FixturePorts, never, never>;
904
+ probe: {
905
+ run: () => Effect.Effect<{
906
+ revision: string;
907
+ pools: string[];
908
+ }, ProgressionError, never>;
909
+ expected: {
910
+ revision: string;
911
+ pools: string[];
912
+ };
913
+ };
914
+ }>;
915
+
916
+ declare interface RankCloseInput extends RankObserveInput {
917
+ readonly tenantId: string;
918
+ readonly ownerId: string;
919
+ }
920
+
921
+ declare interface RankContext {
922
+ readonly ladder: RankLadder;
923
+ readonly rating: RankRating;
924
+ readonly at: number;
925
+ }
926
+
927
+ declare interface RankDecayDefinition {
928
+ readonly afterDays: number;
929
+ readonly perDay: number;
930
+ readonly floor: number;
931
+ }
932
+
933
+ declare type RankDecayResolver = (input: RankGradeContext) => number;
934
+
935
+ export declare const rankDecaySystemFixture: Readonly<{
936
+ kind: "slot";
937
+ defaultImplementation: RankDecayResolver;
938
+ defaultProbe: {
939
+ run: () => Effect.Effect<number, never, never>;
940
+ expected: number;
941
+ };
942
+ overrideProbe: {
943
+ run: () => Effect.Effect<number, never, never>;
944
+ expected: number;
945
+ };
946
+ }>;
947
+
948
+ /** Test-only actual installed rank seasons on a private store; the rating source
949
+ * is an explicit fixture rating, not the Ratings SQL pool. */
950
+ export declare const rankFakeLayer: Layer.Layer<RankPort>;
951
+
952
+ export declare const rankFixture: () => Readonly<{
953
+ ladder: RankLadder;
954
+ rating: Readonly<{
955
+ pool: "test.ranked";
956
+ state: Readonly<{
957
+ algorithm: "elo";
958
+ rating: 250;
959
+ }>;
960
+ games: 10;
961
+ updatedAt: 1000;
962
+ }>;
963
+ at: 1000;
964
+ }>;
965
+
966
+ declare interface RankGrade {
967
+ readonly index: number;
968
+ readonly tier: string;
969
+ readonly tierIndex: number;
970
+ readonly division: number;
971
+ }
972
+
973
+ declare interface RankGradeContext extends RankContext {
974
+ readonly score: number;
975
+ }
976
+
977
+ declare type RankGradeResolver = (input: RankGradeContext) => RankGrade | null;
978
+
979
+ export declare const rankGradeSystemFixture: Readonly<{
980
+ kind: "slot";
981
+ defaultImplementation: RankGradeResolver;
982
+ defaultProbe: {
983
+ run: () => Effect.Effect<{
984
+ tier: string;
985
+ division: number;
986
+ } | null, never, never>;
987
+ expected: {
988
+ tier: string;
989
+ division: number;
990
+ };
991
+ };
992
+ overrideProbe: {
993
+ run: () => Effect.Effect<{
994
+ tier: string;
995
+ division: number;
996
+ } | null, never, never>;
997
+ expected: {
998
+ tier: string;
999
+ division: number;
1000
+ };
1001
+ };
1002
+ }>;
1003
+
1004
+ declare interface RankLadder {
1005
+ readonly id: string;
1006
+ readonly version: number;
1007
+ readonly rating: string;
1008
+ readonly tiers: readonly string[];
1009
+ readonly divisions: number;
1010
+ readonly thresholds: readonly number[];
1011
+ readonly placements: number;
1012
+ readonly confidence: number;
1013
+ readonly decay: RankDecayDefinition | null;
1014
+ readonly softReset: RankResetDefinition | null;
1015
+ }
1016
+
1017
+ declare interface RankObserveInput {
1018
+ readonly seasonId: string;
1019
+ readonly requestId: string;
1020
+ }
1021
+
1022
+ declare class RankPort extends RankPort_base {
1023
+ }
1024
+
1025
+ declare const RankPort_base: Context.ServiceClass<RankPort, "@voltro/RankPort", RankSeasonService>;
1026
+
1027
+ export declare const rankPortSystemFixture: Readonly<{
1028
+ kind: "port";
1029
+ tag: typeof RankPort;
1030
+ fakeLayer: Layer.Layer<RankPort, never, never>;
1031
+ probe: {
1032
+ run: () => Effect.Effect<{
1033
+ original: boolean;
1034
+ highest: string | null;
1035
+ seasons: number;
1036
+ }, ProgressionError, never>;
1037
+ expected: {
1038
+ original: boolean;
1039
+ highest: string;
1040
+ seasons: number;
1041
+ };
1042
+ };
1043
+ }>;
1044
+
1045
+ declare interface RankRating {
1046
+ readonly pool: string;
1047
+ readonly state: RankRatingState;
1048
+ readonly games: number;
1049
+ readonly updatedAt: number | null;
1050
+ }
1051
+
1052
+ declare class RankRatingSource extends RankRatingSource_base {
1053
+ }
1054
+
1055
+ declare const RankRatingSource_base: Context.ServiceClass<RankRatingSource, "@voltro/RankRatingSource", RankRatingSourceService>;
1056
+
1057
+ export declare const rankRatingSourceFakeLayer: Layer.Layer<RankRatingSource, never, never>;
1058
+
1059
+ declare interface RankRatingSourceService {
1060
+ readonly read: (subject: Subject, pool: string) => Effect.Effect<RankRating, ProgressionError>;
1061
+ }
1062
+
1063
+ export declare const rankRatingSourceSystemFixture: Readonly<{
1064
+ kind: "port";
1065
+ tag: typeof RankRatingSource;
1066
+ fakeLayer: Layer.Layer<RankRatingSource, never, never>;
1067
+ probe: {
1068
+ run: () => Effect.Effect<{
1069
+ games: number;
1070
+ updatedAt: number | null;
1071
+ }, ProgressionError, never>;
1072
+ expected: {
1073
+ games: number;
1074
+ updatedAt: number;
1075
+ };
1076
+ };
1077
+ }>;
1078
+
1079
+ /** SQL Ratings remain the authority; this detached shape matches Ratings.myRating. */
1080
+ declare type RankRatingState = {
1081
+ readonly algorithm: 'elo';
1082
+ readonly rating: number;
1083
+ } | {
1084
+ readonly algorithm: 'openskill';
1085
+ readonly mu: number;
1086
+ readonly sigma: number;
1087
+ } | {
1088
+ readonly algorithm: 'glicko2';
1089
+ readonly rating: number;
1090
+ readonly deviation: number;
1091
+ readonly volatility: number;
1092
+ };
1093
+
1094
+ declare interface RankResetContext {
1095
+ readonly ladder: RankLadder;
1096
+ readonly score: number;
1097
+ }
1098
+
1099
+ declare interface RankResetDefinition {
1100
+ readonly target: number;
1101
+ readonly retain: number;
1102
+ }
1103
+
1104
+ declare type RankScoreResolver = (input: RankContext) => number;
1105
+
1106
+ export declare const rankScoreSystemFixture: Readonly<{
1107
+ kind: "slot";
1108
+ defaultImplementation: RankScoreResolver;
1109
+ defaultProbe: {
1110
+ run: () => Effect.Effect<number, never, never>;
1111
+ expected: number;
1112
+ };
1113
+ overrideProbe: {
1114
+ run: () => Effect.Effect<number, never, never>;
1115
+ expected: number;
1116
+ };
1117
+ }>;
1118
+
1119
+ declare interface RankSeason {
1120
+ readonly id: string;
1121
+ readonly version: number;
1122
+ readonly ladderId: string;
1123
+ readonly from: number;
1124
+ readonly until: number;
1125
+ readonly rewards: readonly (readonly ProgressionReward[])[];
1126
+ }
1127
+
1128
+ export declare const rankSeasonPolicyFixture: () => Readonly<{
1129
+ ladder: RankLadder;
1130
+ rating: Readonly<{
1131
+ pool: "test.ranked";
1132
+ state: Readonly<{
1133
+ algorithm: "elo";
1134
+ rating: 250;
1135
+ }>;
1136
+ games: 10;
1137
+ updatedAt: 1000;
1138
+ }>;
1139
+ at: 1000;
1140
+ season: RankSeason;
1141
+ state: RankSeasonState;
1142
+ }>;
1143
+
1144
+ declare interface RankSeasonReceipt {
1145
+ readonly operationId: string;
1146
+ readonly kind: 'observe' | 'close';
1147
+ readonly after: RankSeasonState;
1148
+ readonly rewardsQueued: number;
1149
+ readonly at: number;
1150
+ }
1151
+
1152
+ declare type RankSeasonReset = (input: RankResetContext) => number;
1153
+
1154
+ export declare const rankSeasonResetSystemFixture: Readonly<{
1155
+ kind: "slot";
1156
+ defaultImplementation: RankSeasonReset;
1157
+ defaultProbe: {
1158
+ run: () => Effect.Effect<number, never, never>;
1159
+ expected: number;
1160
+ };
1161
+ overrideProbe: {
1162
+ run: () => Effect.Effect<number, never, never>;
1163
+ expected: number;
1164
+ };
1165
+ }>;
1166
+
1167
+ declare interface RankSeasonService {
1168
+ readonly observe: (subject: Subject, input: RankObserveInput) => Effect.Effect<RankSeasonReceipt, ProgressionError>;
1169
+ readonly close: (subject: Subject, input: RankCloseInput) => Effect.Effect<RankSeasonReceipt, ProgressionError>;
1170
+ readonly mine: (subject: Subject) => Effect.Effect<readonly RankSeasonState[], ProgressionError>;
1171
+ readonly exportSubject: (target: PluginPrivacyTarget) => Effect.Effect<unknown, ProgressionError>;
1172
+ readonly eraseSubject: (target: PluginPrivacyTarget) => Effect.Effect<void, ProgressionError>;
1173
+ }
1174
+
1175
+ declare interface RankSeasonState {
1176
+ readonly seasonId: string;
1177
+ readonly version: number;
1178
+ readonly ladderId: string;
1179
+ readonly observations: number;
1180
+ readonly last: PlayerRank | null;
1181
+ readonly highest: RankGrade | null;
1182
+ readonly closedAt: number | null;
1183
+ readonly resetScore: number | null;
1184
+ }
1185
+
1186
+ declare interface RecordQuestInput {
1187
+ readonly tenantId: string;
1188
+ readonly ownerId: string;
1189
+ readonly poolId: string;
1190
+ readonly windowId: string;
1191
+ readonly requestId: string;
1192
+ readonly source: string;
1193
+ readonly origin: string;
1194
+ readonly signal: QuestSignalInput;
1195
+ }
1196
+
1197
+ declare interface RegenResource {
1198
+ readonly id: string;
1199
+ readonly version: number;
1200
+ readonly max: string;
1201
+ readonly initial: string;
1202
+ readonly regenPer: string;
1203
+ readonly regenAmount: string;
1204
+ readonly regenEveryMs: number;
1205
+ readonly refillOffer?: string;
1206
+ }
1207
+
1208
+ declare interface RegenResourceDefinition {
1209
+ readonly id: string;
1210
+ readonly version?: number;
1211
+ readonly max: ProgressValue;
1212
+ readonly initial?: ProgressValue;
1213
+ readonly regenPer: string;
1214
+ readonly regenAmount?: ProgressValue;
1215
+ readonly refillOffer?: string;
1216
+ }
1217
+
1218
+ declare class RegenResourcePort extends RegenResourcePort_base {
1219
+ }
1220
+
1221
+ declare const RegenResourcePort_base: Context.ServiceClass<RegenResourcePort, "@voltro/RegenResourcePort", RegenResourceService>;
1222
+
1223
+ declare interface RegenResourceService {
1224
+ readonly initialize: (subject: Subject, input: InitializeResourceInput) => Effect.Effect<ResourceReceipt, ProgressionError>;
1225
+ readonly consume: (subject: Subject, input: ResourceChangeInput) => Effect.Effect<ResourceReceipt, ProgressionError>;
1226
+ readonly grant: (subject: Subject, input: ResourceChangeInput) => Effect.Effect<ResourceReceipt, ProgressionError>;
1227
+ readonly mine: (subject: Subject) => Effect.Effect<readonly PlayerResource[], ProgressionError>;
1228
+ readonly exportSubject: (target: PluginPrivacyTarget) => Effect.Effect<unknown, ProgressionError>;
1229
+ readonly eraseSubject: (target: PluginPrivacyTarget) => Effect.Effect<void, ProgressionError>;
1230
+ }
1231
+
1232
+ declare interface RerollQuestInput {
1233
+ readonly poolId: string;
1234
+ readonly windowId: string;
1235
+ readonly assignmentId: string;
1236
+ readonly requestId: string;
1237
+ }
1238
+
1239
+ export declare const resolvePassCatchUp: (input: PassCatchUpContext, slot?: PassCatchUp) => string;
1240
+
1241
+ export declare const resolveQuestProgress: (input: QuestProgressContext, slot?: QuestProgressResolver) => readonly number[];
1242
+
1243
+ export declare const resolveResourceRegen: (input: ResourceRegenContext, slot?: ResourceRegenResolver) => ResourceState;
1244
+
1245
+ export declare const resolveTutorialStep: (input: TutorialStepPolicyContext, policy?: TutorialStepPolicy) => TutorialState;
1246
+
1247
+ declare interface ResourceChangeInput {
1248
+ readonly tenantId: string;
1249
+ readonly ownerId: string;
1250
+ readonly resourceId: string;
1251
+ readonly requestId: string;
1252
+ readonly source: string;
1253
+ readonly origin: string;
1254
+ readonly amount: ProgressValue;
1255
+ }
1256
+
1257
+ export declare const resourceFakeLayer: Layer.Layer<FixturePorts, never, never>;
1258
+
1259
+ export declare const resourceFixture: () => Readonly<{
1260
+ resource: RegenResource;
1261
+ state: Readonly<{
1262
+ value: "5";
1263
+ anchorAt: 1000;
1264
+ }>;
1265
+ at: 3000;
1266
+ }>;
1267
+
1268
+ export declare const resourcePortSystemFixture: Readonly<{
1269
+ kind: "port";
1270
+ tag: typeof RegenResourcePort;
1271
+ fakeLayer: Layer.Layer<FixturePorts, never, never>;
1272
+ probe: {
1273
+ run: () => Effect.Effect<{
1274
+ original: boolean;
1275
+ values: string[];
1276
+ }, ProgressionError, never>;
1277
+ expected: {
1278
+ original: boolean;
1279
+ values: string[];
1280
+ };
1281
+ };
1282
+ }>;
1283
+
1284
+ declare interface ResourceReceipt {
1285
+ readonly operationId: string;
1286
+ readonly kind: 'initialize' | 'consume' | 'grant';
1287
+ readonly resourceId: string;
1288
+ readonly amount: string;
1289
+ readonly regenerated: string;
1290
+ readonly after: ResourceState;
1291
+ readonly at: number;
1292
+ }
1293
+
1294
+ declare interface ResourceRegenContext {
1295
+ readonly resource: RegenResource;
1296
+ readonly state: ResourceState;
1297
+ readonly at: number;
1298
+ }
1299
+
1300
+ declare type ResourceRegenResolver = (input: ResourceRegenContext) => ResourceState;
1301
+
1302
+ export declare const resourceRegenSystemFixture: Readonly<{
1303
+ kind: "slot";
1304
+ defaultImplementation: ResourceRegenResolver;
1305
+ defaultProbe: {
1306
+ run: () => Effect.Effect< ResourceState, never, never>;
1307
+ expected: {
1308
+ value: string;
1309
+ anchorAt: number;
1310
+ };
1311
+ };
1312
+ overrideProbe: {
1313
+ run: () => Effect.Effect< ResourceState, never, never>;
1314
+ expected: {
1315
+ value: string;
1316
+ anchorAt: number;
1317
+ };
1318
+ };
1319
+ }>;
1320
+
1321
+ declare interface ResourceState {
1322
+ readonly value: string;
1323
+ readonly anchorAt: number;
1324
+ }
1325
+
1326
+ declare type RewardResolver = (context: RewardResolverContext) => readonly LevelReward[];
1327
+
1328
+ declare interface RewardResolverContext {
1329
+ readonly track: ProgressionTrack;
1330
+ readonly fromLevel: number;
1331
+ readonly toLevel: number;
1332
+ }
1333
+
1334
+ export declare const rewardResolverSystemFixture: Readonly<{
1335
+ kind: "slot";
1336
+ defaultImplementation: RewardResolver;
1337
+ defaultProbe: {
1338
+ run: () => Effect.Effect<readonly LevelReward[], never, never>;
1339
+ expected: {
1340
+ level: number;
1341
+ reward: {
1342
+ kind: string;
1343
+ currency: string;
1344
+ amount: string;
1345
+ };
1346
+ }[];
1347
+ };
1348
+ overrideProbe: {
1349
+ run: () => Effect.Effect<readonly LevelReward[], never, never>;
1350
+ expected: never[];
1351
+ };
1352
+ }>;
1353
+
1354
+ declare interface SeasonPass {
1355
+ readonly id: string;
1356
+ readonly version: number;
1357
+ readonly from: number;
1358
+ readonly until: number;
1359
+ readonly tiers: number;
1360
+ readonly xpPerTier: string;
1361
+ readonly tracks: {
1362
+ readonly free: readonly (readonly ProgressionReward[])[];
1363
+ readonly premium: readonly (readonly ProgressionReward[])[];
1364
+ };
1365
+ readonly premiumOffer: string | null;
1366
+ readonly sources: readonly string[];
1367
+ readonly catchUp: {
1368
+ readonly xpBoostAfterDay: number;
1369
+ readonly multiplier: number;
1370
+ } | null;
1371
+ readonly autoClaim: boolean;
1372
+ readonly expireUnclaimed: 'mail' | 'forfeit';
1373
+ }
1374
+
1375
+ declare class SeasonPassPort extends SeasonPassPort_base {
1376
+ }
1377
+
1378
+ declare const SeasonPassPort_base: Context.ServiceClass<SeasonPassPort, "@voltro/SeasonPassPort", SeasonPassService>;
1379
+
1380
+ declare interface SeasonPassService {
1381
+ readonly applyXp: (subject: Subject, input: PassXpInput) => Effect.Effect<PassReceipt, ProgressionError>;
1382
+ readonly grantPremium: (subject: Subject, input: PassPremiumInput) => Effect.Effect<PassReceipt, ProgressionError>;
1383
+ readonly claim: (subject: Subject, input: PassClaimInput) => Effect.Effect<PassReceipt, ProgressionError>;
1384
+ readonly close: (subject: Subject, input: PassCloseInput) => Effect.Effect<PassReceipt, ProgressionError>;
1385
+ readonly mine: (subject: Subject) => Effect.Effect<readonly PlayerPass[], ProgressionError>;
1386
+ readonly exportSubject: (target: PluginPrivacyTarget) => Effect.Effect<unknown, ProgressionError>;
1387
+ readonly eraseSubject: (target: PluginPrivacyTarget) => Effect.Effect<void, ProgressionError>;
1388
+ }
1389
+
1390
+ export declare const selectQuests: (input: QuestSelectorContext, slot?: QuestSelector) => readonly string[];
1391
+
1392
+ declare const STAT_OPERATORS: readonly ["increment", "max", "min", "set"];
1393
+
1394
+ export declare const staticQuestSource: (input: readonly QuestPoolDefinition[], revision?: string) => QuestSourceService;
1395
+
1396
+ declare type StatOperator = typeof STAT_OPERATORS[number];
1397
+
1398
+ declare interface StatThreshold {
1399
+ readonly kind: 'statAtLeast';
1400
+ readonly stat: string;
1401
+ readonly target: string;
1402
+ readonly period: 'lifetime' | 'season';
1403
+ readonly seasonId: string | null;
1404
+ }
1405
+
1406
+ declare interface Tutorial {
1407
+ readonly id: string;
1408
+ readonly version: number;
1409
+ readonly steps: readonly string[];
1410
+ readonly skippable: boolean;
1411
+ readonly reward: readonly ProgressionReward[];
1412
+ readonly rewardOnSkip: boolean;
1413
+ readonly hints: string | null;
1414
+ }
1415
+
1416
+ declare interface TutorialEvidence {
1417
+ readonly source: string;
1418
+ readonly originId: string;
1419
+ readonly version: string;
1420
+ readonly from: number;
1421
+ readonly until: number;
1422
+ }
1423
+
1424
+ /** Test-only actual installed tutorial adapter on a private store; no client
1425
+ * verifier, reward destination or production backend. */
1426
+ export declare const tutorialFakeLayer: Layer.Layer<TutorialPort>;
1427
+
1428
+ export declare const tutorialFixture: () => Readonly<{
1429
+ tutorial: Tutorial;
1430
+ state: TutorialState;
1431
+ stepPolicy: Readonly<{
1432
+ tutorial: Tutorial;
1433
+ before: TutorialState;
1434
+ step: "move";
1435
+ evidence: Readonly<{
1436
+ source: "test.room";
1437
+ originId: "test.move";
1438
+ version: "v1";
1439
+ from: 0;
1440
+ until: 1000;
1441
+ }>;
1442
+ at: 1;
1443
+ }>;
1444
+ }>;
1445
+
1446
+ declare class TutorialPort extends TutorialPort_base {
1447
+ }
1448
+
1449
+ declare const TutorialPort_base: Context.ServiceClass<TutorialPort, "@voltro/TutorialPort", TutorialService>;
1450
+
1451
+ export declare const tutorialPortSystemFixture: Readonly<{
1452
+ kind: "port";
1453
+ tag: typeof TutorialPort;
1454
+ fakeLayer: Layer.Layer<TutorialPort, never, never>;
1455
+ probe: {
1456
+ run: () => Effect.Effect<{
1457
+ original: boolean;
1458
+ completed: boolean;
1459
+ rewardsQueued: number;
1460
+ tutorials: {
1461
+ completedSteps: readonly string[];
1462
+ nextStep: string | null;
1463
+ }[];
1464
+ }, ProgressionError, never>;
1465
+ expected: {
1466
+ original: boolean;
1467
+ completed: boolean;
1468
+ rewardsQueued: number;
1469
+ tutorials: {
1470
+ completedSteps: string[];
1471
+ nextStep: null;
1472
+ }[];
1473
+ };
1474
+ };
1475
+ }>;
1476
+
1477
+ declare interface TutorialReceipt {
1478
+ readonly operationId: string;
1479
+ readonly kind: 'step' | 'skip';
1480
+ readonly step: string | null;
1481
+ readonly after: TutorialState;
1482
+ readonly rewardsQueued: number;
1483
+ readonly at: number;
1484
+ }
1485
+
1486
+ declare interface TutorialRecordInput extends TutorialStepInput {
1487
+ readonly tenantId: string;
1488
+ readonly ownerId: string;
1489
+ readonly source: string;
1490
+ readonly originId: string;
1491
+ }
1492
+
1493
+ declare interface TutorialService {
1494
+ readonly completeStep: (subject: Subject, input: TutorialStepInput) => Effect.Effect<TutorialReceipt, ProgressionError>;
1495
+ readonly record: (subject: Subject, input: TutorialRecordInput) => Effect.Effect<TutorialReceipt, ProgressionError>;
1496
+ readonly skip: (subject: Subject, input: TutorialSkipInput) => Effect.Effect<TutorialReceipt, ProgressionError>;
1497
+ readonly mine: (subject: Subject) => Effect.Effect<readonly PlayerTutorial[], ProgressionError>;
1498
+ readonly exportSubject: (target: PluginPrivacyTarget) => Effect.Effect<unknown, ProgressionError>;
1499
+ readonly eraseSubject: (target: PluginPrivacyTarget) => Effect.Effect<void, ProgressionError>;
1500
+ }
1501
+
1502
+ declare interface TutorialSkipInput {
1503
+ readonly tutorialId: string;
1504
+ readonly requestId: string;
1505
+ }
1506
+
1507
+ declare interface TutorialState {
1508
+ readonly tutorialId: string;
1509
+ readonly version: number;
1510
+ readonly completedSteps: readonly string[];
1511
+ readonly completed: boolean;
1512
+ readonly skipped: boolean;
1513
+ readonly completedAt: number | null;
1514
+ readonly updatedAt: number | null;
1515
+ }
1516
+
1517
+ declare interface TutorialStepInput {
1518
+ readonly tutorialId: string;
1519
+ readonly step: string;
1520
+ readonly requestId: string;
1521
+ }
1522
+
1523
+ declare type TutorialStepPolicy = (input: TutorialStepPolicyContext) => boolean;
1524
+
1525
+ declare interface TutorialStepPolicyContext {
1526
+ readonly tutorial: Tutorial;
1527
+ readonly before: TutorialState;
1528
+ readonly step: string;
1529
+ readonly evidence: TutorialEvidence;
1530
+ readonly at: number;
1531
+ }
1532
+
1533
+ export declare const tutorialStepPolicySystemFixture: Readonly<{
1534
+ kind: "slot";
1535
+ defaultImplementation: TutorialStepPolicy;
1536
+ defaultProbe: {
1537
+ run: () => Effect.Effect<readonly string[], never, never>;
1538
+ expected: string[];
1539
+ };
1540
+ overrideProbe: {
1541
+ run: () => Effect.Effect<string, never, never>;
1542
+ expected: string;
1543
+ };
1544
+ }>;
1545
+
1546
+ declare type XpCurve = (context: XpCurveContext) => number;
1547
+
1548
+ declare interface XpCurveContext {
1549
+ readonly xp: string;
1550
+ readonly curve: LevelCurve;
1551
+ }
1552
+
1553
+ export declare const xpCurveSystemFixture: Readonly<{
1554
+ kind: "slot";
1555
+ defaultImplementation: XpCurve;
1556
+ defaultProbe: {
1557
+ run: () => Effect.Effect<number, never, never>;
1558
+ expected: number;
1559
+ };
1560
+ overrideProbe: {
1561
+ run: () => Effect.Effect<number, never, never>;
1562
+ expected: number;
1563
+ };
1564
+ }>;
1565
+
1566
+ export { }