@voltro/plugin-progression 0.0.0-stage → 0.87.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 +24329 -0
  2. package/LICENSE +61 -0
  3. package/README.md +478 -2
  4. package/SECURITY.md +56 -0
  5. package/THIRD-PARTY-NOTICES.md +9189 -0
  6. package/dist/achievementComponents.js +92 -0
  7. package/dist/achievementStore.js +603 -0
  8. package/dist/achievementTables.entity.js +98 -0
  9. package/dist/achievements.d.ts +188 -0
  10. package/dist/achievements.js +205 -0
  11. package/dist/capture.js +64 -0
  12. package/dist/cmsQuests.d.ts +91 -0
  13. package/dist/cmsQuests.js +83 -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 +38 -0
  18. package/dist/daily.d.ts +152 -0
  19. package/dist/daily.js +126 -0
  20. package/dist/dailyStore.js +421 -0
  21. package/dist/dailySystem.fixture.js +138 -0
  22. package/dist/dailyTables.entity.js +90 -0
  23. package/dist/declarationFixtures.js +143 -0
  24. package/dist/errors.d.ts +13 -0
  25. package/dist/errors.js +20 -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 +122 -0
  30. package/dist/passRules.js +96 -0
  31. package/dist/passStore.js +485 -0
  32. package/dist/passTables.entity.js +96 -0
  33. package/dist/plugin.js +1086 -0
  34. package/dist/port.js +5 -0
  35. package/dist/progressionStore.js +706 -0
  36. package/dist/questComponents.js +163 -0
  37. package/dist/questPort.d.ts +126 -0
  38. package/dist/questPort.js +5 -0
  39. package/dist/questRefresh.js +56 -0
  40. package/dist/questRefresh.server.js +126 -0
  41. package/dist/questRerollJournal.js +77 -0
  42. package/dist/questStore.js +592 -0
  43. package/dist/questTables.entity.js +117 -0
  44. package/dist/quests.d.ts +142 -0
  45. package/dist/quests.js +153 -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 +35 -0
  51. package/dist/rankClosure.server.js +139 -0
  52. package/dist/rankClosureWorkflow.d.ts +34 -0
  53. package/dist/rankClosureWorkflow.js +16 -0
  54. package/dist/rankReader.server.js +57 -0
  55. package/dist/rankRewardParent.server.js +65 -0
  56. package/dist/rankSeasons.d.ts +144 -0
  57. package/dist/rankSeasons.js +91 -0
  58. package/dist/rankStore.js +521 -0
  59. package/dist/rankSystem.fixture.js +170 -0
  60. package/dist/rankTables.entity.js +101 -0
  61. package/dist/ranks.d.ts +167 -0
  62. package/dist/ranks.js +219 -0
  63. package/dist/resourceStore.js +464 -0
  64. package/dist/resourceTables.entity.js +89 -0
  65. package/dist/resources.d.ts +105 -0
  66. package/dist/resources.js +60 -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 +39 -0
  72. package/dist/rewardDelivery.d.ts +163 -0
  73. package/dist/rewardDelivery.js +38 -0
  74. package/dist/rewardDelivery.server.js +430 -0
  75. package/dist/rewardDeliveryRecord.js +48 -0
  76. package/dist/rewardDeliveryWorkflow.d.ts +36 -0
  77. package/dist/rewardDeliveryWorkflow.js +16 -0
  78. package/dist/rpc.d.ts +880 -0
  79. package/dist/rpc.js +498 -0
  80. package/dist/server.d.ts +2812 -0
  81. package/dist/server.js +21 -0
  82. package/dist/stats.js +45 -0
  83. package/dist/strategies.d.ts +131 -0
  84. package/dist/strategies.js +4 -0
  85. package/dist/systemFixtures.js +474 -0
  86. package/dist/tables.entity.js +155 -0
  87. package/dist/testing.d.ts +1566 -0
  88. package/dist/testing.js +11 -0
  89. package/dist/track.js +72 -0
  90. package/dist/tutorial.d.ts +157 -0
  91. package/dist/tutorial.js +110 -0
  92. package/dist/tutorialStore.js +496 -0
  93. package/dist/tutorialSystem.fixture.js +100 -0
  94. package/dist/tutorialTables.entity.js +91 -0
  95. package/dist/web.d.ts +363 -0
  96. package/dist/web.js +7 -0
  97. package/package.json +167 -4
@@ -0,0 +1,98 @@
1
+ import { boolean as e, id as t, integer as n, json as r, table as i, text as a, timestamp as o } from "@voltro/database";
2
+ //#region src/achievementTables.entity.ts
3
+ var s = () => a().maxLength(120).externalId().sensitive("pii"), c = () => a().maxLength(120).externalId().sensitive("pii"), l = () => a().maxLength(64).nullable().serverOnly(), u = i("_voltro_prog_achievement_definitions", {
4
+ id: t({ prefix: "pad" }),
5
+ tenantId: s(),
6
+ achievementId: a().maxLength(120).safe(),
7
+ version: n().safe(),
8
+ config: r().serverOnly(),
9
+ rulesVersion: a().maxLength(120).safe(),
10
+ admission: n().serverOnly()
11
+ }).index("voltro_prog_achievement_definitions_version_idx", [
12
+ "tenantId",
13
+ "achievementId",
14
+ "version"
15
+ ]), d = i("_voltro_prog_achievement_subjects", {
16
+ id: t({ prefix: "pas" }),
17
+ tenantId: s(),
18
+ ownerId: c().nullable(),
19
+ erased: e().serverOnly(),
20
+ sequence: n().serverOnly(),
21
+ admission: n().serverOnly(),
22
+ throughSequence: n().serverOnly(),
23
+ sourceVersion: a().maxLength(120).nullable().serverOnly(),
24
+ sourceDigest: a().maxLength(64).nullable().serverOnly(),
25
+ configDigest: a().maxLength(64).nullable().serverOnly(),
26
+ view: r().nullable().serverOnly()
27
+ }).index(["tenantId", "ownerId"]), f = i("_voltro_prog_achievements", {
28
+ id: t({ prefix: "pau" }),
29
+ tenantId: s(),
30
+ ownerId: c(),
31
+ achievementId: a().maxLength(120).safe(),
32
+ version: n().safe(),
33
+ tierId: a().maxLength(120).safe(),
34
+ unlockedAt: o().safe(),
35
+ sourceSequence: n().safe(),
36
+ operationId: a().maxLength(64).safe()
37
+ }).index([
38
+ "tenantId",
39
+ "ownerId",
40
+ "achievementId"
41
+ ]), p = i("_voltro_prog_achievement_unlock_ledger", {
42
+ id: t({ prefix: "pal" }),
43
+ tenantId: s(),
44
+ ownerId: c().nullable(),
45
+ ownerKey: l(),
46
+ unlockId: a().maxLength(64).safe(),
47
+ achievementId: a().maxLength(120).safe(),
48
+ version: n().safe(),
49
+ tierId: a().maxLength(120).safe(),
50
+ unlockedAt: o().safe(),
51
+ sourceSequence: n().safe(),
52
+ operationId: a().maxLength(64).safe(),
53
+ proof: r().nullable().serverOnly()
54
+ }).index(["tenantId", "ownerKey"]), m = i("_voltro_prog_achievement_operations", {
55
+ id: t({ prefix: "pao" }),
56
+ tenantId: s(),
57
+ ownerKey: l(),
58
+ state: a().maxLength(16).oneOf(["committed", "erased"]).serverOnly(),
59
+ sequence: n().serverOnly(),
60
+ throughSequence: n().serverOnly(),
61
+ sourceVersion: a().maxLength(120).nullable().serverOnly(),
62
+ sourceDigest: a().maxLength(64).nullable().serverOnly(),
63
+ configDigest: a().maxLength(64).nullable().serverOnly(),
64
+ view: r().nullable().serverOnly(),
65
+ receipt: r().nullable().serverOnly(),
66
+ at: o().safe()
67
+ }).index(["tenantId", "ownerKey"]), h = i("_voltro_prog_achievement_rewards", {
68
+ id: t({ prefix: "par" }),
69
+ tenantId: s(),
70
+ ownerId: c().nullable(),
71
+ ownerKey: l(),
72
+ unlockId: a().maxLength(64).safe(),
73
+ operationId: a().maxLength(64).safe(),
74
+ reward: r().nullable().serverOnly(),
75
+ state: a().maxLength(16).oneOf([
76
+ "pending",
77
+ "delivered",
78
+ "erased"
79
+ ]).serverOnly(),
80
+ createdAt: o().safe(),
81
+ deliveredAt: o().nullable().safe(),
82
+ deliveryIntent: r().nullable().serverOnly(),
83
+ deliveryDigest: a().maxLength(64).nullable().serverOnly(),
84
+ deliveryReceipt: r().nullable().serverOnly()
85
+ }).index([
86
+ "tenantId",
87
+ "ownerKey",
88
+ "state"
89
+ ]), g = [
90
+ u,
91
+ d,
92
+ f,
93
+ p,
94
+ m,
95
+ h
96
+ ];
97
+ //#endregion
98
+ export { u as achievementDefinitionsTable, m as achievementOperationsTable, h as achievementRewardsTable, d as achievementSubjectsTable, g as achievementTables, p as achievementUnlockLedgerTable, f as achievementsTable };
@@ -0,0 +1,188 @@
1
+ import { Context } from 'effect';
2
+ import { Effect } from 'effect';
3
+ import { PluginPrivacyTarget } from '@voltro/protocol';
4
+ import { Schema } from 'effect';
5
+ import { Subject } from '@voltro/protocol';
6
+ import { YieldableError } from 'effect/Cause';
7
+
8
+ export declare interface Achievement {
9
+ readonly id: string;
10
+ readonly version: number;
11
+ readonly hidden: boolean;
12
+ readonly tiers: readonly AchievementTier[];
13
+ }
14
+
15
+ export declare type AchievementCondition = StatThreshold | CompositeCondition;
16
+
17
+ export declare interface AchievementDefinition {
18
+ readonly id: string;
19
+ readonly version?: number;
20
+ readonly condition: AchievementCondition;
21
+ readonly tiers?: readonly AchievementTierDefinition[];
22
+ readonly hidden?: boolean;
23
+ readonly reward?: readonly ProgressionReward[];
24
+ readonly platform?: AchievementPlatform;
25
+ }
26
+
27
+ export declare interface AchievementEvaluation {
28
+ readonly met: boolean;
29
+ readonly progress: readonly AchievementProgress[];
30
+ }
31
+
32
+ export declare type AchievementEvaluator = (input: {
33
+ readonly condition: AchievementCondition;
34
+ readonly stats: readonly AchievementStat[];
35
+ }) => AchievementEvaluation;
36
+
37
+ export declare interface AchievementPlatform {
38
+ readonly steam?: string;
39
+ readonly gameCenter?: string;
40
+ readonly playGames?: string;
41
+ }
42
+
43
+ export declare class AchievementPort extends AchievementPort_base {
44
+ }
45
+
46
+ declare const AchievementPort_base: Context.ServiceClass<AchievementPort, "@voltro/AchievementPort", AchievementService>;
47
+
48
+ export declare interface AchievementProgress extends AchievementStat {
49
+ readonly target: string;
50
+ readonly met: boolean;
51
+ }
52
+
53
+ export declare interface AchievementReceipt {
54
+ readonly operationId: string;
55
+ readonly throughSequence: number;
56
+ readonly unlockedIds: readonly string[];
57
+ readonly rewardsQueued: number;
58
+ readonly at: number;
59
+ }
60
+
61
+ export declare interface AchievementService {
62
+ readonly evaluate: (subject: Subject, input: EvaluateAchievementsInput) => Effect.Effect<AchievementReceipt, ProgressionError>;
63
+ readonly mine: (subject: Subject) => Effect.Effect<readonly PlayerAchievement[], ProgressionError>;
64
+ readonly exportSubject: (target: PluginPrivacyTarget) => Effect.Effect<unknown, ProgressionError>;
65
+ readonly eraseSubject: (target: PluginPrivacyTarget) => Effect.Effect<void, ProgressionError>;
66
+ }
67
+
68
+ export declare interface AchievementStat {
69
+ readonly stat: string;
70
+ readonly period: 'lifetime' | 'season';
71
+ readonly seasonId: string | null;
72
+ readonly value: string;
73
+ }
74
+
75
+ export declare interface AchievementStatEvent extends AchievementStat {
76
+ readonly operationId: string;
77
+ readonly sequence: number;
78
+ readonly at: number;
79
+ }
80
+
81
+ export declare interface AchievementStatHistory {
82
+ readonly version: string;
83
+ readonly throughSequence: number;
84
+ readonly initial: readonly AchievementStat[];
85
+ readonly events: readonly AchievementStatEvent[];
86
+ }
87
+
88
+ export declare class AchievementStatSource extends AchievementStatSource_base {
89
+ }
90
+
91
+ declare const AchievementStatSource_base: Context.ServiceClass<AchievementStatSource, "@voltro/AchievementStatSource", AchievementStatSourceService>;
92
+
93
+ export declare interface AchievementStatSourceService {
94
+ readonly history: (subject: Subject, input: {
95
+ readonly tenantId: string;
96
+ readonly ownerId: string;
97
+ readonly limit: number;
98
+ }) => Effect.Effect<AchievementStatHistory, ProgressionError>;
99
+ }
100
+
101
+ export declare interface AchievementTier {
102
+ readonly id: string;
103
+ readonly condition: AchievementCondition;
104
+ readonly reward: readonly ProgressionReward[];
105
+ readonly platform: AchievementPlatform;
106
+ }
107
+
108
+ export declare interface AchievementTierDefinition {
109
+ readonly id: string;
110
+ readonly condition: AchievementCondition;
111
+ readonly reward?: readonly ProgressionReward[];
112
+ readonly platform?: AchievementPlatform;
113
+ }
114
+
115
+ export declare const captureAchievementCondition: (input: unknown) => AchievementCondition;
116
+
117
+ export declare const captureAchievementPlatform: (input: unknown) => AchievementPlatform;
118
+
119
+ export declare const captureAchievementStats: (input: unknown) => readonly AchievementStat[];
120
+
121
+ export declare const composite: (conditions: readonly AchievementCondition[], mode?: "all" | "any") => AchievementCondition;
122
+
123
+ export declare interface CompositeCondition {
124
+ readonly kind: 'composite';
125
+ readonly mode: 'all' | 'any';
126
+ readonly conditions: readonly AchievementCondition[];
127
+ }
128
+
129
+ export declare const defaultAchievementEvaluator: AchievementEvaluator;
130
+
131
+ export declare const defineAchievement: (input: AchievementDefinition | Achievement) => Achievement;
132
+
133
+ export declare interface EvaluateAchievementsInput {
134
+ readonly tenantId: string;
135
+ readonly ownerId: string;
136
+ readonly requestId: string;
137
+ }
138
+
139
+ export declare interface PlayerAchievement {
140
+ readonly achievementId: string;
141
+ readonly version: number;
142
+ readonly tierId: string;
143
+ readonly unlocked: boolean;
144
+ readonly unlockedAt: number | null;
145
+ readonly progress: readonly AchievementProgress[];
146
+ readonly platform: AchievementPlatform | null;
147
+ }
148
+
149
+ declare class ProgressionError extends ProgressionError_base {
150
+ }
151
+
152
+ declare const ProgressionError_base: Schema.Class<ProgressionError, Schema.TaggedStruct<"ProgressionError", {
153
+ 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"]>;
154
+ }>, YieldableError>;
155
+
156
+ declare type ProgressionReward = {
157
+ readonly kind: 'currency';
158
+ readonly currency: string;
159
+ readonly amount: string;
160
+ } | {
161
+ readonly kind: 'item';
162
+ readonly itemId: string;
163
+ readonly qty: number;
164
+ } | {
165
+ readonly kind: 'xp';
166
+ readonly trackId: string;
167
+ readonly amount: string;
168
+ };
169
+
170
+ declare type ProgressValue = string | number | bigint;
171
+
172
+ /** A custom evaluator may change fulfillment; it must retain truthful threshold progress. */
173
+ export declare const resolveAchievementEvaluation: (condition: AchievementCondition, stats: readonly AchievementStat[], slot?: AchievementEvaluator) => AchievementEvaluation;
174
+
175
+ export declare const statAtLeast: (stat: string, target: ProgressValue, scope?: {
176
+ readonly period?: "lifetime" | "season";
177
+ readonly seasonId?: string | null;
178
+ }) => StatThreshold;
179
+
180
+ export declare interface StatThreshold {
181
+ readonly kind: 'statAtLeast';
182
+ readonly stat: string;
183
+ readonly target: string;
184
+ readonly period: 'lifetime' | 'season';
185
+ readonly seasonId: string | null;
186
+ }
187
+
188
+ export { }
@@ -0,0 +1,205 @@
1
+ import { progressionError as e } from "./errors.js";
2
+ import { identifier as t, integer as n, list as r, object as i, progressValue as a } from "./capture.js";
3
+ import { captureRewards as o } from "./reward.js";
4
+ import { Context as s } from "effect";
5
+ //#region src/achievements.ts
6
+ var c = (n, r, o = {}) => {
7
+ let s = i(o, ["period", "seasonId"]), c = s.period ?? "lifetime", l = a(r);
8
+ if (c !== "lifetime" && c !== "season" || l === 0n || c === "lifetime" && s.seasonId !== void 0 && s.seasonId !== null) throw e("invalid_input");
9
+ return Object.freeze({
10
+ kind: "statAtLeast",
11
+ stat: t(n),
12
+ target: String(l),
13
+ period: c,
14
+ seasonId: c === "season" ? t(s.seasonId) : null
15
+ });
16
+ }, l = (n) => {
17
+ let a = 0, o = (n, s) => {
18
+ if (s > 8) throw e("limit_exceeded");
19
+ let l = i(n, [
20
+ "kind",
21
+ "stat",
22
+ "target",
23
+ "period",
24
+ "seasonId",
25
+ "mode",
26
+ "conditions"
27
+ ]);
28
+ if (l.kind === "statAtLeast") {
29
+ if (++a > 64 || Object.keys(l).some((e) => ![
30
+ "kind",
31
+ "stat",
32
+ "target",
33
+ "period",
34
+ "seasonId"
35
+ ].includes(e))) throw e("invalid_input");
36
+ return c(t(l.stat), l.target, {
37
+ period: l.period,
38
+ seasonId: l.seasonId
39
+ });
40
+ }
41
+ if (l.kind !== "composite" || l.mode !== "all" && l.mode !== "any" || Object.keys(l).some((e) => ![
42
+ "kind",
43
+ "mode",
44
+ "conditions"
45
+ ].includes(e))) throw e("invalid_input");
46
+ let u = r(l.conditions, 64).map((e) => o(e, s + 1));
47
+ if (u.length === 0) throw e("invalid_input");
48
+ return Object.freeze({
49
+ kind: "composite",
50
+ mode: l.mode,
51
+ conditions: Object.freeze(u)
52
+ });
53
+ };
54
+ return o(n, 0);
55
+ }, u = (e, t = "all") => l({
56
+ kind: "composite",
57
+ mode: t,
58
+ conditions: e
59
+ }), d = (e) => {
60
+ let n = i(e, [
61
+ "steam",
62
+ "gameCenter",
63
+ "playGames"
64
+ ]);
65
+ return Object.freeze(Object.fromEntries(Object.entries(n).map(([e, n]) => [e, t(n)])));
66
+ }, f = (a) => {
67
+ let s = i(a, [
68
+ "id",
69
+ "version",
70
+ "condition",
71
+ "tiers",
72
+ "hidden",
73
+ "reward",
74
+ "platform"
75
+ ]);
76
+ if (s.condition === void 0) {
77
+ if (s.reward !== void 0 || s.platform !== void 0 || typeof s.hidden != "boolean") throw e("invalid_input");
78
+ let a = Object.freeze(r(s.tiers, 32).map((e) => {
79
+ let n = i(e, [
80
+ "id",
81
+ "condition",
82
+ "reward",
83
+ "platform"
84
+ ]);
85
+ return Object.freeze({
86
+ id: t(n.id),
87
+ condition: l(n.condition),
88
+ reward: o(n.reward, 64),
89
+ platform: d(n.platform)
90
+ });
91
+ }));
92
+ if (a[0]?.id !== "base" || new Set(a.map((e) => e.id)).size !== a.length) throw e("invalid_input");
93
+ return Object.freeze({
94
+ id: t(s.id),
95
+ version: n(s.version, 1, 1e6),
96
+ hidden: s.hidden,
97
+ tiers: a
98
+ });
99
+ }
100
+ let c = l(s.condition);
101
+ if (s.hidden !== void 0 && typeof s.hidden != "boolean") throw e("invalid_input");
102
+ let f = [Object.freeze({
103
+ id: "base",
104
+ condition: c,
105
+ reward: o(s.reward ?? [], 64),
106
+ platform: d(s.platform ?? {})
107
+ })];
108
+ for (let e of r(s.tiers ?? [], 31)) {
109
+ let n = i(e, [
110
+ "id",
111
+ "condition",
112
+ "reward",
113
+ "platform"
114
+ ]);
115
+ f.push(Object.freeze({
116
+ id: t(n.id),
117
+ condition: u([c, l(n.condition)]),
118
+ reward: o(n.reward ?? [], 64),
119
+ platform: d(n.platform ?? {})
120
+ }));
121
+ }
122
+ if (new Set(f.map((e) => e.id)).size !== f.length) throw e("invalid_input");
123
+ return Object.freeze({
124
+ id: t(s.id),
125
+ version: n(s.version ?? 1, 1, 1e6),
126
+ hidden: s.hidden ?? !1,
127
+ tiers: Object.freeze(f)
128
+ });
129
+ }, p = (n) => {
130
+ let o = r(n, 4096).map((n) => {
131
+ let r = i(n, [
132
+ "stat",
133
+ "period",
134
+ "seasonId",
135
+ "value"
136
+ ]), o = r.period;
137
+ if (o !== "lifetime" && o !== "season" || o === "lifetime" && r.seasonId !== null) throw e("invalid_input");
138
+ return Object.freeze({
139
+ stat: t(r.stat),
140
+ period: o,
141
+ seasonId: o === "season" ? t(r.seasonId) : null,
142
+ value: String(a(r.value))
143
+ });
144
+ });
145
+ if (new Set(o.map((e) => JSON.stringify([
146
+ e.stat,
147
+ e.period,
148
+ e.seasonId
149
+ ]))).size !== o.length) throw e("invalid_input");
150
+ return Object.freeze(o);
151
+ }, m = (e) => {
152
+ let t = l(e.condition), n = p(e.stats), r = [], i = (e) => {
153
+ if (e.kind === "composite") {
154
+ let t = e.conditions.map(i);
155
+ return e.mode === "all" ? t.every(Boolean) : t.some(Boolean);
156
+ }
157
+ let t = n.find((t) => t.stat === e.stat && t.period === e.period && t.seasonId === e.seasonId)?.value ?? "0", a = BigInt(t) >= BigInt(e.target);
158
+ return r.push(Object.freeze({
159
+ stat: e.stat,
160
+ period: e.period,
161
+ seasonId: e.seasonId,
162
+ value: t,
163
+ target: e.target,
164
+ met: a
165
+ })), a;
166
+ }, a = i(t);
167
+ return Object.freeze({
168
+ met: a,
169
+ progress: Object.freeze(r)
170
+ });
171
+ }, h = (t, n, o = m) => {
172
+ let s = Object.freeze({
173
+ condition: l(t),
174
+ stats: p(n)
175
+ }), c = m(s), u = i(o(s), ["met", "progress"]);
176
+ if (typeof u.met != "boolean") throw e("invalid_input");
177
+ let d = r(u.progress, 64).map((t) => {
178
+ let n = i(t, [
179
+ "stat",
180
+ "period",
181
+ "seasonId",
182
+ "value",
183
+ "target",
184
+ "met"
185
+ ]);
186
+ if (typeof n.met != "boolean") throw e("invalid_input");
187
+ return Object.freeze({
188
+ ...p([{
189
+ stat: n.stat,
190
+ period: n.period,
191
+ seasonId: n.seasonId,
192
+ value: n.value
193
+ }])[0],
194
+ target: String(a(n.target)),
195
+ met: n.met
196
+ });
197
+ });
198
+ if (JSON.stringify(d) !== JSON.stringify(c.progress)) throw e("invalid_input");
199
+ return Object.freeze({
200
+ met: u.met,
201
+ progress: Object.freeze(d)
202
+ });
203
+ }, g = class extends s.Service()("@voltro/AchievementStatSource") {}, _ = class extends s.Service()("@voltro/AchievementPort") {};
204
+ //#endregion
205
+ export { _ as AchievementPort, g as AchievementStatSource, l as captureAchievementCondition, d as captureAchievementPlatform, p as captureAchievementStats, u as composite, m as defaultAchievementEvaluator, f as defineAchievement, h as resolveAchievementEvaluation, c as statAtLeast };
@@ -0,0 +1,64 @@
1
+ import { progressionError as e } from "./errors.js";
2
+ //#region src/capture.ts
3
+ var t = (t, n) => {
4
+ if (!t || typeof t != "object" || Array.isArray(t)) throw e("invalid_input");
5
+ let r = Object.getPrototypeOf(t);
6
+ if (r !== Object.prototype && r !== null) throw e("invalid_input");
7
+ let i = Object.create(null), a = Object.getOwnPropertyDescriptors(t);
8
+ for (let t of Reflect.ownKeys(a)) {
9
+ let r = typeof t == "string" ? a[t] : void 0;
10
+ if (typeof t != "string" || n && !n.includes(t) || !r || !("value" in r) || !r.enumerable) throw e("invalid_input");
11
+ i[t] = r.value;
12
+ }
13
+ return Object.freeze(i);
14
+ }, n = (t) => {
15
+ if (typeof t != "string" || !/^[A-Za-z0-9][A-Za-z0-9._:-]{0,119}$/.test(t)) throw e("invalid_input");
16
+ return t;
17
+ }, r = (t, n, r) => {
18
+ if (typeof t != "number" || !Number.isSafeInteger(t) || Object.is(t, -0) || t < n || t > r) throw e("invalid_input");
19
+ return t;
20
+ }, i = (t, n) => {
21
+ if (!Array.isArray(t) || t.length > n) throw e("invalid_input");
22
+ let r = Object.getOwnPropertyDescriptors(t);
23
+ if (Reflect.ownKeys(r).length !== t.length + 1) throw e("invalid_input");
24
+ return Object.freeze(Array.from({ length: t.length }, (t, n) => {
25
+ let i = r[String(n)];
26
+ if (!i || !("value" in i) || !i.enumerable) throw e("invalid_input");
27
+ return i.value;
28
+ }));
29
+ }, a = 9223372036854775807n, o = (t) => {
30
+ let n;
31
+ if (typeof t == "bigint") n = t;
32
+ else if (typeof t == "number" && Number.isSafeInteger(t) && !Object.is(t, -0)) n = BigInt(t);
33
+ else if (typeof t == "string" && /^(0|[1-9][0-9]{0,18})$/.test(t)) n = BigInt(t);
34
+ else throw e("invalid_input");
35
+ if (n < 0n || n > 9223372036854775807n) throw e("overflow");
36
+ return n;
37
+ }, s = (n) => {
38
+ let r = 0, a = (n, o) => {
39
+ if (++r > 4096 || o > 16) throw e("invalid_input");
40
+ if (n == null || typeof n == "boolean" || typeof n == "bigint" || typeof n == "string" && n.length <= 4096 || typeof n == "number" && Number.isFinite(n)) return n;
41
+ if (Array.isArray(n)) return Object.freeze(i(n, 4096).map((e) => a(e, o + 1)));
42
+ let s = t(n);
43
+ return Object.freeze(Object.fromEntries(Object.entries(s).map(([e, t]) => [e, a(t, o + 1)])));
44
+ };
45
+ return a(n, 0);
46
+ }, c = (t, n) => {
47
+ if (typeof t != "object" || !t || Array.isArray(t)) throw e("invalid_input");
48
+ let r = Object.create(null);
49
+ for (let i of n) {
50
+ let n = t, a = !1;
51
+ for (let o = 0; n !== null && o < 8; o++, n = Object.getPrototypeOf(n)) {
52
+ let o = Object.getOwnPropertyDescriptor(n, i);
53
+ if (o !== void 0) {
54
+ if (!("value" in o) || typeof o.value != "function") throw e("invalid_input");
55
+ r[i] = o.value.bind(t), a = !0;
56
+ break;
57
+ }
58
+ }
59
+ if (!a) throw e("invalid_input");
60
+ }
61
+ return Object.freeze(r);
62
+ };
63
+ //#endregion
64
+ export { a as MAX_PROGRESS_VALUE, s as captureArguments, c as captureMethods, n as identifier, r as integer, i as list, t as object, o as progressValue };
@@ -0,0 +1,91 @@
1
+ import { ContentEntities } from '@voltro/cms';
2
+ import { ContentType } from '@voltro/cms';
3
+ import { DataStore } from '@voltro/database';
4
+ import { Effect } from 'effect';
5
+ import { Schema } from 'effect';
6
+ import { YieldableError } from 'effect/Cause';
7
+
8
+ export declare interface CmsQuestOptions {
9
+ readonly site: string;
10
+ readonly environments: Readonly<Record<string, string>>;
11
+ readonly maxPools?: number;
12
+ }
13
+
14
+ export declare const cmsQuestSource: (store: DataStore, input: CmsQuestOptions) => QuestSourceService;
15
+
16
+ declare class ProgressionError extends ProgressionError_base {
17
+ }
18
+
19
+ declare const ProgressionError_base: Schema.Class<ProgressionError, Schema.TaggedStruct<"ProgressionError", {
20
+ 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"]>;
21
+ }>, YieldableError>;
22
+
23
+ export declare const progressionQuestContentTables: ContentEntities;
24
+
25
+ export declare const progressionQuestContentType: ContentType;
26
+
27
+ declare type ProgressionReward = {
28
+ readonly kind: 'currency';
29
+ readonly currency: string;
30
+ readonly amount: string;
31
+ } | {
32
+ readonly kind: 'item';
33
+ readonly itemId: string;
34
+ readonly qty: number;
35
+ } | {
36
+ readonly kind: 'xp';
37
+ readonly trackId: string;
38
+ readonly amount: string;
39
+ };
40
+
41
+ declare interface QuestDefinition {
42
+ readonly id: string;
43
+ readonly titleKey?: string;
44
+ readonly objectives: readonly QuestObjective[];
45
+ readonly reward: readonly ProgressionReward[];
46
+ }
47
+
48
+ declare type QuestObjective = {
49
+ readonly stat: string;
50
+ readonly target: number;
51
+ } | {
52
+ readonly event: string;
53
+ readonly target: number;
54
+ readonly where?: Readonly<Record<string, QuestScalar>>;
55
+ };
56
+
57
+ declare interface QuestPool extends QuestPoolDefinition {
58
+ readonly version: number;
59
+ readonly rerolls: number;
60
+ readonly weights: Readonly<Record<string, number>>;
61
+ }
62
+
63
+ declare interface QuestPoolDefinition {
64
+ readonly id: string;
65
+ readonly version?: number;
66
+ readonly slots: number;
67
+ readonly rerolls?: number;
68
+ readonly refresh: {
69
+ readonly cron: string;
70
+ readonly timezone: string;
71
+ };
72
+ readonly quests: readonly QuestDefinition[];
73
+ readonly weights?: Readonly<Record<string, number>>;
74
+ }
75
+
76
+ declare type QuestScalar = string | number | boolean | null;
77
+
78
+ declare interface QuestSourceScope {
79
+ readonly tenantId: string;
80
+ readonly channel: string;
81
+ readonly locale: string;
82
+ }
83
+
84
+ declare interface QuestSourceService {
85
+ readonly read: (scope: QuestSourceScope) => Effect.Effect<{
86
+ readonly revision: string;
87
+ readonly pools: readonly QuestPool[];
88
+ }, ProgressionError>;
89
+ }
90
+
91
+ export { }