@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.
- package/CHANGELOG.md +24492 -0
- package/LICENSE +61 -0
- package/README.md +478 -2
- package/SECURITY.md +56 -0
- package/THIRD-PARTY-NOTICES.md +9841 -0
- package/dist/achievementComponents.js +91 -0
- package/dist/achievementStore.js +602 -0
- package/dist/achievementTables.entity.js +97 -0
- package/dist/achievements.d.ts +188 -0
- package/dist/achievements.js +204 -0
- package/dist/capture.js +63 -0
- package/dist/cmsQuests.d.ts +91 -0
- package/dist/cmsQuests.js +82 -0
- package/dist/components.d.ts +172 -0
- package/dist/components.js +4 -0
- package/dist/curve.d.ts +27 -0
- package/dist/curve.js +37 -0
- package/dist/daily.d.ts +152 -0
- package/dist/daily.js +125 -0
- package/dist/dailyStore.js +420 -0
- package/dist/dailySystem.fixture.js +137 -0
- package/dist/dailyTables.entity.js +89 -0
- package/dist/declarationFixtures.js +142 -0
- package/dist/errors.d.ts +13 -0
- package/dist/errors.js +19 -0
- package/dist/index.d.ts +1833 -0
- package/dist/index.js +19 -0
- package/dist/pass.d.ts +186 -0
- package/dist/pass.js +121 -0
- package/dist/passRules.js +95 -0
- package/dist/passStore.js +484 -0
- package/dist/passTables.entity.js +95 -0
- package/dist/plugin.js +1085 -0
- package/dist/port.js +4 -0
- package/dist/progressionStore.js +705 -0
- package/dist/questComponents.js +162 -0
- package/dist/questPort.d.ts +126 -0
- package/dist/questPort.js +4 -0
- package/dist/questRefresh.js +55 -0
- package/dist/questRefresh.server.js +125 -0
- package/dist/questRerollJournal.js +76 -0
- package/dist/questStore.js +591 -0
- package/dist/questTables.entity.js +116 -0
- package/dist/quests.d.ts +142 -0
- package/dist/quests.js +152 -0
- package/dist/rank-app/schedules/progression.dispatchRankClosures.cron.tsx +19 -0
- package/dist/rank-app/workflows/progression.closeRankSeason.workflow.server.tsx +10 -0
- package/dist/rank-app/workflows/progression.closeRankSeason.workflow.tsx +1 -0
- package/dist/rankClosure.d.ts +69 -0
- package/dist/rankClosure.js +34 -0
- package/dist/rankClosure.server.js +138 -0
- package/dist/rankClosureWorkflow.d.ts +34 -0
- package/dist/rankClosureWorkflow.js +15 -0
- package/dist/rankReader.server.js +56 -0
- package/dist/rankRewardParent.server.js +64 -0
- package/dist/rankSeasons.d.ts +144 -0
- package/dist/rankSeasons.js +90 -0
- package/dist/rankStore.js +520 -0
- package/dist/rankSystem.fixture.js +169 -0
- package/dist/rankTables.entity.js +100 -0
- package/dist/ranks.d.ts +167 -0
- package/dist/ranks.js +218 -0
- package/dist/resourceStore.js +463 -0
- package/dist/resourceTables.entity.js +88 -0
- package/dist/resources.d.ts +105 -0
- package/dist/resources.js +59 -0
- package/dist/reward-app/schedules/progression.dispatchRewards.cron.tsx +19 -0
- package/dist/reward-app/workflows/progression.deliverReward.workflow.server.tsx +10 -0
- package/dist/reward-app/workflows/progression.deliverReward.workflow.tsx +1 -0
- package/dist/reward.d.ts +27 -0
- package/dist/reward.js +38 -0
- package/dist/rewardDelivery.d.ts +163 -0
- package/dist/rewardDelivery.js +37 -0
- package/dist/rewardDelivery.server.js +429 -0
- package/dist/rewardDeliveryRecord.js +47 -0
- package/dist/rewardDeliveryWorkflow.d.ts +36 -0
- package/dist/rewardDeliveryWorkflow.js +15 -0
- package/dist/rpc.d.ts +880 -0
- package/dist/rpc.js +497 -0
- package/dist/server.d.ts +2812 -0
- package/dist/server.js +21 -0
- package/dist/stats.js +44 -0
- package/dist/strategies.d.ts +131 -0
- package/dist/strategies.js +4 -0
- package/dist/systemFixtures.js +473 -0
- package/dist/tables.entity.js +154 -0
- package/dist/testing.d.ts +1566 -0
- package/dist/testing.js +11 -0
- package/dist/track.js +71 -0
- package/dist/tutorial.d.ts +157 -0
- package/dist/tutorial.js +109 -0
- package/dist/tutorialStore.js +495 -0
- package/dist/tutorialSystem.fixture.js +99 -0
- package/dist/tutorialTables.entity.js +90 -0
- package/dist/web.d.ts +363 -0
- package/dist/web.js +6 -0
- package/package.json +167 -4
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { PlayerAchievementSchema as e } from "./rpc.js";
|
|
2
|
+
import { useAchievements as t } from "./web.js";
|
|
3
|
+
import { Schema as n } from "effect";
|
|
4
|
+
import { useId as r } from "react";
|
|
5
|
+
import { useUiStrings as i } from "@voltro/ui";
|
|
6
|
+
import { jsx as a, jsxs as o } from "react/jsx-runtime";
|
|
7
|
+
// src/achievementComponents.tsx
|
|
8
|
+
var s = n.decodeUnknownSync(n.Array(e), { onExcessProperty: "error" }), c = (e) => /^[A-Za-z0-9][A-Za-z0-9._:-]{0,119}$/.test(e), l = (e) => /^(0|[1-9][0-9]{0,18})$/.test(e) && BigInt(e) <= 9223372036854775807n, u = (e) => {
|
|
9
|
+
try {
|
|
10
|
+
if (!Array.isArray(e) || e.length > 256) return;
|
|
11
|
+
let t = s(e);
|
|
12
|
+
return new Set(t.map((e) => JSON.stringify([
|
|
13
|
+
e.achievementId,
|
|
14
|
+
e.version,
|
|
15
|
+
e.tierId
|
|
16
|
+
]))).size !== t.length || t.some((e) => !c(e.achievementId) || !c(e.tierId) || !Number.isSafeInteger(e.version) || e.version < 1 || e.version > 1e6 || e.unlocked !== (e.unlockedAt !== null) || e.unlockedAt !== null && (!Number.isSafeInteger(e.unlockedAt) || e.unlockedAt < 0 || e.unlockedAt > 864e13) || !e.unlocked && e.platform !== null || e.platform !== null && Object.values(e.platform).some((e) => e !== void 0 && !c(e)) || e.progress.length < 1 || e.progress.length > 64 || e.progress.some((e) => !c(e.stat) || !l(e.value) || !l(e.target) || e.target === "0" || e.met !== BigInt(e.value) >= BigInt(e.target) || e.period === "lifetime" && e.seasonId !== null || e.period === "season" && (e.seasonId === null || !c(e.seasonId)))) ? void 0 : t;
|
|
17
|
+
} catch {
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
function d({ achievement: e, title: t, locale: n }) {
|
|
22
|
+
let s = i().achievements, c = r(), l = u([e])?.[0];
|
|
23
|
+
return l ? /* @__PURE__ */ o("article", {
|
|
24
|
+
"data-achievement": l.achievementId,
|
|
25
|
+
"data-tier": l.tierId,
|
|
26
|
+
"data-state": l.unlocked ? "unlocked" : "locked",
|
|
27
|
+
"aria-labelledby": c,
|
|
28
|
+
children: [
|
|
29
|
+
/* @__PURE__ */ o("header", { children: [/* @__PURE__ */ a("h3", {
|
|
30
|
+
id: c,
|
|
31
|
+
children: t ?? l.achievementId
|
|
32
|
+
}), /* @__PURE__ */ o("p", { children: [
|
|
33
|
+
s.tier(l.tierId),
|
|
34
|
+
" · ",
|
|
35
|
+
l.unlocked ? s.unlocked : s.locked
|
|
36
|
+
] })] }),
|
|
37
|
+
/* @__PURE__ */ a("ul", {
|
|
38
|
+
"data-achievement-progress": !0,
|
|
39
|
+
children: l.progress.map((e, t) => {
|
|
40
|
+
let n = BigInt(e.value), r = BigInt(e.target), i = Number((n >= r ? r : n) * 10000n / r);
|
|
41
|
+
return /* @__PURE__ */ o("li", { children: [/* @__PURE__ */ a("span", { children: s.progress(e.stat, e.value, e.target) }), /* @__PURE__ */ a("progress", {
|
|
42
|
+
"aria-label": e.stat,
|
|
43
|
+
"aria-valuetext": s.progress(e.stat, e.value, e.target),
|
|
44
|
+
value: i,
|
|
45
|
+
max: 1e4
|
|
46
|
+
})] }, t);
|
|
47
|
+
})
|
|
48
|
+
}),
|
|
49
|
+
l.unlockedAt === null ? null : /* @__PURE__ */ a("p", { children: /* @__PURE__ */ a("time", {
|
|
50
|
+
dateTime: new Date(l.unlockedAt).toISOString(),
|
|
51
|
+
children: s.unlockedDate(new Date(l.unlockedAt).toLocaleString(n))
|
|
52
|
+
}) })
|
|
53
|
+
]
|
|
54
|
+
}) : /* @__PURE__ */ a("p", {
|
|
55
|
+
role: "alert",
|
|
56
|
+
children: s.invalid
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
function f({ api: e = "app", locale: n, renderTitle: r }) {
|
|
60
|
+
let o = i().achievements, s = t(e), c = s.data === void 0 ? void 0 : u(s.data);
|
|
61
|
+
return s.error === void 0 ? s.loading ? /* @__PURE__ */ a("p", {
|
|
62
|
+
role: "status",
|
|
63
|
+
children: o.loading
|
|
64
|
+
}) : c ? /* @__PURE__ */ a("section", {
|
|
65
|
+
"data-achievements": !0,
|
|
66
|
+
"aria-label": o.title,
|
|
67
|
+
children: c.length === 0 ? /* @__PURE__ */ a("p", { children: o.empty }) : /* @__PURE__ */ a("ul", { children: c.map((e) => /* @__PURE__ */ a("li", { children: /* @__PURE__ */ a(d, {
|
|
68
|
+
achievement: e,
|
|
69
|
+
title: r?.(e),
|
|
70
|
+
locale: n
|
|
71
|
+
}) }, JSON.stringify([
|
|
72
|
+
e.achievementId,
|
|
73
|
+
e.version,
|
|
74
|
+
e.tierId
|
|
75
|
+
]))) })
|
|
76
|
+
}) : /* @__PURE__ */ a("p", {
|
|
77
|
+
role: "alert",
|
|
78
|
+
children: o.invalid
|
|
79
|
+
}) : /* @__PURE__ */ a("p", {
|
|
80
|
+
role: "alert",
|
|
81
|
+
children: o.unavailable
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
function p(e) {
|
|
85
|
+
let t = i().achievements;
|
|
86
|
+
return c(e.invocationScope) ? /* @__PURE__ */ a(f, { ...e }, JSON.stringify([e.api ?? "app", e.invocationScope])) : /* @__PURE__ */ a("p", {
|
|
87
|
+
role: "alert",
|
|
88
|
+
children: t.invalid
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
export { d as AchievementCard, p as AchievementList };
|
|
@@ -0,0 +1,602 @@
|
|
|
1
|
+
import { ProgressionError as e, progressionError as t } from "./errors.js";
|
|
2
|
+
import { captureArguments as n, identifier as r, integer as i, list as a, object as o, progressValue as s } from "./capture.js";
|
|
3
|
+
import { admitRewardDeliveryRecord as c } from "./rewardDeliveryRecord.js";
|
|
4
|
+
import { questHash as l } from "./questStore.js";
|
|
5
|
+
import { captureAchievementPlatform as u, captureAchievementStats as d, defaultAchievementEvaluator as f, defineAchievement as p, resolveAchievementEvaluation as m } from "./achievements.js";
|
|
6
|
+
import { achievementDefinitionsTable as h, achievementOperationsTable as g, achievementRewardsTable as _, achievementSubjectsTable as v, achievementUnlockLedgerTable as y, achievementsTable as b } from "./achievementTables.entity.js";
|
|
7
|
+
import { Effect as x, Result as S } from "effect";
|
|
8
|
+
import { and as C, eq as w, queryFor as T } from "@voltro/database";
|
|
9
|
+
// src/achievementStore.ts
|
|
10
|
+
var E = (e) => {
|
|
11
|
+
let n = o(e, [
|
|
12
|
+
"definitions",
|
|
13
|
+
"source",
|
|
14
|
+
"allowedServices",
|
|
15
|
+
"maxHistoryRows",
|
|
16
|
+
"maxPendingRewards",
|
|
17
|
+
"now",
|
|
18
|
+
"strategies"
|
|
19
|
+
]), s = Object.freeze(a(n.definitions, 128).map((e) => p(e))), c = o(n.source, ["history"]), l = o(n.strategies ?? {}, ["achievementEvaluator", "version"]), u = l.achievementEvaluator ?? f, d = n.now ?? Date.now, m = Object.freeze(a(n.allowedServices ?? [], 256).map(r));
|
|
20
|
+
if (s.length === 0 || new Set(s.map((e) => e.id)).size !== s.length || s.reduce((e, t) => e + t.tiers.length, 0) > 256 || typeof c.history != "function" || typeof u != "function" || typeof d != "function" || new Set(m).size !== m.length || u !== f && l.version === void 0) throw t("invalid_input");
|
|
21
|
+
return Object.freeze({
|
|
22
|
+
definitions: s,
|
|
23
|
+
source: Object.freeze({ history: c.history }),
|
|
24
|
+
allowedServices: m,
|
|
25
|
+
maxHistoryRows: i(n.maxHistoryRows ?? 1e4, 1, 1e5),
|
|
26
|
+
maxPendingRewards: i(n.maxPendingRewards ?? 4096, 1, 1e4),
|
|
27
|
+
now: d,
|
|
28
|
+
strategies: Object.freeze({
|
|
29
|
+
achievementEvaluator: u,
|
|
30
|
+
version: r(l.version ?? "default.v1")
|
|
31
|
+
})
|
|
32
|
+
});
|
|
33
|
+
}, D = (e, n) => {
|
|
34
|
+
let s = o(e, [
|
|
35
|
+
"version",
|
|
36
|
+
"throughSequence",
|
|
37
|
+
"initial",
|
|
38
|
+
"events"
|
|
39
|
+
]), c = i(s.throughSequence, 0, 2147483647), l = d(s.initial), u = /* @__PURE__ */ new Set(), f = 0, p = Object.freeze(a(s.events, n).map((e) => {
|
|
40
|
+
let n = o(e, [
|
|
41
|
+
"stat",
|
|
42
|
+
"period",
|
|
43
|
+
"seasonId",
|
|
44
|
+
"value",
|
|
45
|
+
"operationId",
|
|
46
|
+
"sequence",
|
|
47
|
+
"at"
|
|
48
|
+
]), a = d([{
|
|
49
|
+
stat: n.stat,
|
|
50
|
+
period: n.period,
|
|
51
|
+
seasonId: n.seasonId,
|
|
52
|
+
value: n.value
|
|
53
|
+
}])[0], s = i(n.sequence, f + 1, c), l = r(n.operationId);
|
|
54
|
+
if (u.has(l)) throw t("invalid_record");
|
|
55
|
+
return f = s, u.add(l), Object.freeze({
|
|
56
|
+
...a,
|
|
57
|
+
sequence: s,
|
|
58
|
+
operationId: l,
|
|
59
|
+
at: i(n.at, 0, 864e13)
|
|
60
|
+
});
|
|
61
|
+
}));
|
|
62
|
+
return Object.freeze({
|
|
63
|
+
version: r(s.version),
|
|
64
|
+
throughSequence: c,
|
|
65
|
+
initial: l,
|
|
66
|
+
events: p
|
|
67
|
+
});
|
|
68
|
+
}, O = (e, ...t) => e + l(t).slice(0, 56), k = (e) => {
|
|
69
|
+
let n = e instanceof Date ? e.getTime() : typeof e == "string" ? Date.parse(e) : NaN;
|
|
70
|
+
if (!Number.isSafeInteger(n) || n < 0 || n > 864e13) throw t("invalid_record");
|
|
71
|
+
return n;
|
|
72
|
+
}, A = (n) => x.tryPromise({
|
|
73
|
+
try: n,
|
|
74
|
+
catch: (n) => n instanceof e ? n : t("unavailable")
|
|
75
|
+
}), j = (e) => {
|
|
76
|
+
if (typeof e != "string" || !/^[0-9a-f]{64}$/.test(e)) throw t("invalid_record");
|
|
77
|
+
return e;
|
|
78
|
+
}, M = (d, p) => {
|
|
79
|
+
let M = E(p), N = l({
|
|
80
|
+
definitions: M.definitions,
|
|
81
|
+
rules: M.strategies.version
|
|
82
|
+
}), P = new Set(M.allowedServices), F = new Map(M.definitions.map((e) => [e.id, e])), I = () => i(M.now(), 0, 864e13), L = (e) => {
|
|
83
|
+
if (e.type !== "system" && !(e.type === "service" && P.has(e.service))) throw t("forbidden");
|
|
84
|
+
}, R = (e, t) => O("pas_", e, t), z = (e, t) => C(w("tenantId", e), w("ownerId", t)), B = (e, t) => C(w("tenantId", e), w("ownerKey", R(e, t))), V = async (e, t) => {
|
|
85
|
+
try {
|
|
86
|
+
await d.insertIgnore(e, t, { conflictColumns: ["id"] });
|
|
87
|
+
} catch (n) {
|
|
88
|
+
if (!(await d.query({
|
|
89
|
+
table: e,
|
|
90
|
+
predicate: w("id", t.id),
|
|
91
|
+
order: [],
|
|
92
|
+
take: 1,
|
|
93
|
+
skip: void 0,
|
|
94
|
+
projection: void 0
|
|
95
|
+
}))[0]) throw n;
|
|
96
|
+
}
|
|
97
|
+
}, H = (e, t) => V(v.tableName, {
|
|
98
|
+
id: R(e, t),
|
|
99
|
+
tenantId: e,
|
|
100
|
+
ownerId: t,
|
|
101
|
+
erased: !1,
|
|
102
|
+
sequence: 0,
|
|
103
|
+
admission: 0,
|
|
104
|
+
throughSequence: 0,
|
|
105
|
+
sourceVersion: null,
|
|
106
|
+
sourceDigest: null,
|
|
107
|
+
configDigest: null,
|
|
108
|
+
view: null
|
|
109
|
+
}), U = (e, n, r, a = !1) => {
|
|
110
|
+
if (e) {
|
|
111
|
+
if (e.id !== R(n, r) || e.tenantId !== n || typeof e.erased != "boolean") throw t("invalid_record");
|
|
112
|
+
if (e.erased) {
|
|
113
|
+
if (a && e.ownerId === null) return;
|
|
114
|
+
throw t("erased");
|
|
115
|
+
}
|
|
116
|
+
if (e.ownerId !== r) throw t("invalid_record");
|
|
117
|
+
if (i(e.sequence, 0, 2147483647), i(e.throughSequence, 0, 2147483647), e.configDigest !== null && e.configDigest !== N) throw t("conflict");
|
|
118
|
+
}
|
|
119
|
+
}, W = async (e, n, r, i = !1) => {
|
|
120
|
+
if (await e.updateMany(v.tableName, { admission: 0 }, { where: w("id", R(n, r)) }) !== 1) throw t("unavailable");
|
|
121
|
+
let a = (await e.query(T(v).where(w("id", R(n, r))).limit(1).descriptor))[0];
|
|
122
|
+
if (!a) throw t("invalid_record");
|
|
123
|
+
return U(a, n, r, i), a;
|
|
124
|
+
}, G = async (e, n, r, i) => {
|
|
125
|
+
let a = n === _ ? M.maxPendingRewards : M.maxHistoryRows, o = await e.query(T(n).where(B(r, i)).limit(a + 1).descriptor);
|
|
126
|
+
if (o.length > a) throw t("limit_exceeded");
|
|
127
|
+
if (o.some((e) => e.tenantId !== r || e.ownerKey !== R(r, i))) throw t("invalid_record");
|
|
128
|
+
return o;
|
|
129
|
+
}, K = (e, t, n) => e.query(T(b).where(z(t, n)).limit(257).descriptor), q = (e, n, i) => {
|
|
130
|
+
let a = F.get(r(e)), o = a?.tiers.find((e) => e.id === r(n));
|
|
131
|
+
if (!a || !o || i !== a.version) throw t("conflict");
|
|
132
|
+
return {
|
|
133
|
+
definition: a,
|
|
134
|
+
tier: o
|
|
135
|
+
};
|
|
136
|
+
}, J = (e, t, n, r, i) => O("pau_", e, t, n, String(r), i), Y = (e) => {
|
|
137
|
+
let n = o(e.receipt, [
|
|
138
|
+
"operationId",
|
|
139
|
+
"throughSequence",
|
|
140
|
+
"unlockedIds",
|
|
141
|
+
"rewardsQueued",
|
|
142
|
+
"at"
|
|
143
|
+
]), s = Object.freeze(a(n.unlockedIds, 256).map(r));
|
|
144
|
+
if (n.operationId !== e.id || new Set(s).size !== s.length || n.at !== k(e.at) || n.throughSequence !== e.throughSequence) throw t("invalid_record");
|
|
145
|
+
return Object.freeze({
|
|
146
|
+
operationId: r(e.id),
|
|
147
|
+
throughSequence: i(n.throughSequence, 0, 2147483647),
|
|
148
|
+
unlockedIds: s,
|
|
149
|
+
rewardsQueued: i(n.rewardsQueued, 0, 16384),
|
|
150
|
+
at: i(n.at, 0, 864e13)
|
|
151
|
+
});
|
|
152
|
+
}, X = (e) => {
|
|
153
|
+
let n = a(e, 256).map((e) => {
|
|
154
|
+
let n = o(e, [
|
|
155
|
+
"achievementId",
|
|
156
|
+
"version",
|
|
157
|
+
"tierId",
|
|
158
|
+
"unlocked",
|
|
159
|
+
"unlockedAt",
|
|
160
|
+
"progress",
|
|
161
|
+
"platform"
|
|
162
|
+
]), { definition: c, tier: d } = q(n.achievementId, n.tierId, n.version);
|
|
163
|
+
if (typeof n.unlocked != "boolean" || n.unlocked !== (n.unlockedAt !== null) || !n.unlocked && n.platform !== null) throw t("invalid_record");
|
|
164
|
+
let p = a(n.progress, 64).map((e) => {
|
|
165
|
+
let n = o(e, [
|
|
166
|
+
"stat",
|
|
167
|
+
"period",
|
|
168
|
+
"seasonId",
|
|
169
|
+
"value",
|
|
170
|
+
"target",
|
|
171
|
+
"met"
|
|
172
|
+
]), i = m({
|
|
173
|
+
kind: "statAtLeast",
|
|
174
|
+
stat: r(n.stat),
|
|
175
|
+
period: n.period,
|
|
176
|
+
seasonId: n.seasonId,
|
|
177
|
+
target: String(s(n.target))
|
|
178
|
+
}, [{
|
|
179
|
+
stat: r(n.stat),
|
|
180
|
+
period: n.period,
|
|
181
|
+
seasonId: n.seasonId,
|
|
182
|
+
value: String(s(n.value))
|
|
183
|
+
}]).progress[0];
|
|
184
|
+
if (i.met !== n.met) throw t("invalid_record");
|
|
185
|
+
return i;
|
|
186
|
+
}), h = f({
|
|
187
|
+
condition: d.condition,
|
|
188
|
+
stats: []
|
|
189
|
+
}).progress;
|
|
190
|
+
if (p.length !== h.length || p.some((e, t) => {
|
|
191
|
+
let n = h[t];
|
|
192
|
+
return e.stat !== n.stat || e.period !== n.period || e.seasonId !== n.seasonId || e.target !== n.target;
|
|
193
|
+
})) throw t("invalid_record");
|
|
194
|
+
let g = n.unlocked ? u(n.platform) : null;
|
|
195
|
+
if (g && l(g) !== l(d.platform)) throw t("invalid_record");
|
|
196
|
+
return Object.freeze({
|
|
197
|
+
achievementId: c.id,
|
|
198
|
+
version: c.version,
|
|
199
|
+
tierId: d.id,
|
|
200
|
+
unlocked: n.unlocked,
|
|
201
|
+
unlockedAt: n.unlocked ? i(n.unlockedAt, 0, 864e13) : null,
|
|
202
|
+
progress: Object.freeze(p),
|
|
203
|
+
platform: g
|
|
204
|
+
});
|
|
205
|
+
});
|
|
206
|
+
if (n.length !== M.definitions.reduce((e, t) => e + t.tiers.length, 0) || new Set(n.map((e) => JSON.stringify([e.achievementId, e.tierId]))).size !== n.length) throw t("invalid_record");
|
|
207
|
+
return Object.freeze(n);
|
|
208
|
+
}, Z = (e, t) => l({
|
|
209
|
+
version: e.version,
|
|
210
|
+
initial: e.initial,
|
|
211
|
+
throughSequence: t,
|
|
212
|
+
events: e.events.filter((e) => e.sequence <= t)
|
|
213
|
+
}), ee = (e, n) => {
|
|
214
|
+
let r = /* @__PURE__ */ new Map(), i = /* @__PURE__ */ new Map(), a = (e) => JSON.stringify([
|
|
215
|
+
e.stat,
|
|
216
|
+
e.period,
|
|
217
|
+
e.seasonId
|
|
218
|
+
]);
|
|
219
|
+
for (let t of e.initial) r.set(a(t), t);
|
|
220
|
+
let o = (e, t) => {
|
|
221
|
+
for (let n of M.definitions) for (let a of n.tiers) {
|
|
222
|
+
let o = m(a.condition, [...r.values()], M.strategies.achievementEvaluator), s = JSON.stringify([n.id, a.id]);
|
|
223
|
+
o.met && !i.has(s) && i.set(s, {
|
|
224
|
+
sequence: e,
|
|
225
|
+
at: t,
|
|
226
|
+
progress: o.progress
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
};
|
|
230
|
+
o(0, n);
|
|
231
|
+
for (let i of e.events) {
|
|
232
|
+
if (i.at > n) throw t("conflict");
|
|
233
|
+
r.set(a(i), Object.freeze({
|
|
234
|
+
stat: i.stat,
|
|
235
|
+
period: i.period,
|
|
236
|
+
seasonId: i.seasonId,
|
|
237
|
+
value: i.value
|
|
238
|
+
})), o(i.sequence, i.at);
|
|
239
|
+
}
|
|
240
|
+
return {
|
|
241
|
+
first: i,
|
|
242
|
+
view: Object.freeze(M.definitions.flatMap((e) => e.tiers.map((t) => {
|
|
243
|
+
let n = i.get(JSON.stringify([e.id, t.id])), a = m(t.condition, [...r.values()], M.strategies.achievementEvaluator);
|
|
244
|
+
return Object.freeze({
|
|
245
|
+
achievementId: e.id,
|
|
246
|
+
version: e.version,
|
|
247
|
+
tierId: t.id,
|
|
248
|
+
unlocked: n !== void 0,
|
|
249
|
+
unlockedAt: n?.at ?? null,
|
|
250
|
+
progress: a.progress,
|
|
251
|
+
platform: n ? t.platform : null
|
|
252
|
+
});
|
|
253
|
+
})))
|
|
254
|
+
};
|
|
255
|
+
}, te = (a, s) => {
|
|
256
|
+
try {
|
|
257
|
+
let e = n(a), c = o(s, [
|
|
258
|
+
"tenantId",
|
|
259
|
+
"ownerId",
|
|
260
|
+
"requestId"
|
|
261
|
+
]);
|
|
262
|
+
L(e);
|
|
263
|
+
let u = r(c.tenantId), f = r(c.ownerId), p = O("pao_", u, f, r(c.requestId));
|
|
264
|
+
return A(async () => {
|
|
265
|
+
await H(u, f);
|
|
266
|
+
let n = await d.transactional(async (e) => {
|
|
267
|
+
await W(e, u, f);
|
|
268
|
+
let n = (await G(e, g, u, f)).find((e) => e.id === p);
|
|
269
|
+
if (n) {
|
|
270
|
+
if (n.state !== "committed" || n.configDigest !== N) throw t("conflict");
|
|
271
|
+
return Y(n);
|
|
272
|
+
}
|
|
273
|
+
});
|
|
274
|
+
if (n) return n;
|
|
275
|
+
let r = await x.runPromise(x.result(M.source.history(e, {
|
|
276
|
+
tenantId: u,
|
|
277
|
+
ownerId: f,
|
|
278
|
+
limit: M.maxHistoryRows
|
|
279
|
+
})));
|
|
280
|
+
if (S.isFailure(r)) throw r.failure;
|
|
281
|
+
let a = D(r.success, M.maxHistoryRows), o = I(), s = Z(a, a.throughSequence), c = ee(a, o);
|
|
282
|
+
for (let e of M.definitions) await V(h.tableName, {
|
|
283
|
+
id: O("pad_", u, e.id, String(e.version)),
|
|
284
|
+
tenantId: u,
|
|
285
|
+
achievementId: e.id,
|
|
286
|
+
version: e.version,
|
|
287
|
+
config: e,
|
|
288
|
+
rulesVersion: M.strategies.version,
|
|
289
|
+
admission: 0
|
|
290
|
+
});
|
|
291
|
+
return d.transactional(async (e) => {
|
|
292
|
+
let n = await W(e, u, f), r = await G(e, g, u, f), d = await G(e, y, u, f), m = await G(e, _, u, f), x = r.find((e) => e.id === p);
|
|
293
|
+
if (x) {
|
|
294
|
+
if (x.state !== "committed" || x.configDigest !== N) throw t("conflict");
|
|
295
|
+
return Y(x);
|
|
296
|
+
}
|
|
297
|
+
if (r.length >= M.maxHistoryRows || r.length !== n.sequence) throw t(r.length >= M.maxHistoryRows ? "limit_exceeded" : "invalid_record");
|
|
298
|
+
if (n.sourceVersion !== null && (n.sourceVersion !== a.version || Number(n.throughSequence) > a.throughSequence || n.sourceDigest !== Z(a, Number(n.throughSequence)))) throw t("conflict");
|
|
299
|
+
for (let n of M.definitions) {
|
|
300
|
+
let r = O("pad_", u, n.id, String(n.version));
|
|
301
|
+
if (await e.updateMany(h.tableName, { admission: 0 }, { where: w("id", r) }) !== 1) throw t("unavailable");
|
|
302
|
+
let i = (await e.query(T(h).where(w("id", r)).limit(1).descriptor))[0];
|
|
303
|
+
if (!i || i.tenantId !== u || i.achievementId !== n.id || i.version !== n.version || i.rulesVersion !== M.strategies.version || l(i.config) !== l(n)) throw t("conflict");
|
|
304
|
+
}
|
|
305
|
+
let S = await K(e, u, f);
|
|
306
|
+
if (S.length !== d.length || d.some((e) => !S.some((t) => t.id === e.unlockId && t.operationId === e.operationId && k(t.unlockedAt) === k(e.unlockedAt)))) throw t("invalid_record");
|
|
307
|
+
let C = [], E = 0, D = c.view.map((e) => {
|
|
308
|
+
let t = J(u, f, e.achievementId, e.version, e.tierId), n = d.find((e) => e.unlockId === t);
|
|
309
|
+
return n ? Object.freeze({
|
|
310
|
+
...e,
|
|
311
|
+
unlocked: !0,
|
|
312
|
+
unlockedAt: k(n.unlockedAt),
|
|
313
|
+
platform: q(e.achievementId, e.tierId, e.version).tier.platform
|
|
314
|
+
}) : e;
|
|
315
|
+
});
|
|
316
|
+
for (let n of D) {
|
|
317
|
+
let r = J(u, f, n.achievementId, n.version, n.tierId);
|
|
318
|
+
if (!n.unlocked || d.some((e) => e.unlockId === r)) continue;
|
|
319
|
+
let i = c.first.get(JSON.stringify([n.achievementId, n.tierId]));
|
|
320
|
+
if (!i) throw t("invalid_record");
|
|
321
|
+
let { tier: s } = q(n.achievementId, n.tierId, n.version);
|
|
322
|
+
if (d.length + C.length >= M.maxHistoryRows || m.length + E + s.reward.length > M.maxPendingRewards) throw t("limit_exceeded");
|
|
323
|
+
let l = {
|
|
324
|
+
id: r,
|
|
325
|
+
tenantId: u,
|
|
326
|
+
ownerId: f,
|
|
327
|
+
achievementId: n.achievementId,
|
|
328
|
+
version: n.version,
|
|
329
|
+
tierId: n.tierId,
|
|
330
|
+
unlockedAt: new Date(i.at),
|
|
331
|
+
sourceSequence: i.sequence,
|
|
332
|
+
operationId: p
|
|
333
|
+
};
|
|
334
|
+
await e.insert(b.tableName, l), await e.insert(y.tableName, {
|
|
335
|
+
...l,
|
|
336
|
+
id: O("pal_", r),
|
|
337
|
+
ownerKey: R(u, f),
|
|
338
|
+
unlockId: r,
|
|
339
|
+
proof: {
|
|
340
|
+
sourceVersion: a.version,
|
|
341
|
+
sourceDigest: Z(a, i.sequence),
|
|
342
|
+
rulesVersion: M.strategies.version,
|
|
343
|
+
fulfilled: !0,
|
|
344
|
+
progress: i.progress
|
|
345
|
+
}
|
|
346
|
+
});
|
|
347
|
+
for (let [t, n] of s.reward.entries()) await e.insert(_.tableName, {
|
|
348
|
+
id: O("par_", r, String(t)),
|
|
349
|
+
tenantId: u,
|
|
350
|
+
ownerId: f,
|
|
351
|
+
ownerKey: R(u, f),
|
|
352
|
+
unlockId: r,
|
|
353
|
+
operationId: p,
|
|
354
|
+
reward: n,
|
|
355
|
+
state: "pending",
|
|
356
|
+
createdAt: new Date(o),
|
|
357
|
+
deliveredAt: null,
|
|
358
|
+
deliveryIntent: null,
|
|
359
|
+
deliveryDigest: null,
|
|
360
|
+
deliveryReceipt: null
|
|
361
|
+
});
|
|
362
|
+
C.push(r), E += s.reward.length;
|
|
363
|
+
}
|
|
364
|
+
let A = Object.freeze({
|
|
365
|
+
operationId: p,
|
|
366
|
+
throughSequence: a.throughSequence,
|
|
367
|
+
unlockedIds: Object.freeze(C),
|
|
368
|
+
rewardsQueued: E,
|
|
369
|
+
at: o
|
|
370
|
+
}), j = {
|
|
371
|
+
throughSequence: a.throughSequence,
|
|
372
|
+
sourceVersion: a.version,
|
|
373
|
+
sourceDigest: s,
|
|
374
|
+
configDigest: N,
|
|
375
|
+
view: Object.freeze(D)
|
|
376
|
+
}, P = i(Number(n.sequence) + 1, 1, 2147483647);
|
|
377
|
+
return await e.insert(g.tableName, {
|
|
378
|
+
id: p,
|
|
379
|
+
tenantId: u,
|
|
380
|
+
ownerKey: R(u, f),
|
|
381
|
+
state: "committed",
|
|
382
|
+
sequence: P,
|
|
383
|
+
...j,
|
|
384
|
+
receipt: A,
|
|
385
|
+
at: new Date(o)
|
|
386
|
+
}), await e.update(v.tableName, R(u, f), {
|
|
387
|
+
sequence: P,
|
|
388
|
+
...j
|
|
389
|
+
}), A;
|
|
390
|
+
});
|
|
391
|
+
});
|
|
392
|
+
} catch (n) {
|
|
393
|
+
return x.fail(n instanceof e ? n : t("invalid_input"));
|
|
394
|
+
}
|
|
395
|
+
}, ne = (i) => {
|
|
396
|
+
try {
|
|
397
|
+
let e = n(i);
|
|
398
|
+
if (e.type !== "user") throw t("forbidden");
|
|
399
|
+
let a = r(e.tenantId), o = r(e.id);
|
|
400
|
+
return A(() => d.transactional(async (e) => {
|
|
401
|
+
let t = (await e.query(T(v).where(w("id", R(a, o))).forUpdate().limit(1).descriptor))[0];
|
|
402
|
+
return U(t, a, o), !t || t.view === null ? Object.freeze(M.definitions.filter((e) => !e.hidden).flatMap((e) => e.tiers.map((t) => Object.freeze({
|
|
403
|
+
achievementId: e.id,
|
|
404
|
+
version: e.version,
|
|
405
|
+
tierId: t.id,
|
|
406
|
+
unlocked: !1,
|
|
407
|
+
unlockedAt: null,
|
|
408
|
+
progress: f({
|
|
409
|
+
condition: t.condition,
|
|
410
|
+
stats: []
|
|
411
|
+
}).progress,
|
|
412
|
+
platform: null
|
|
413
|
+
})))) : Object.freeze(X(t.view).filter((e) => e.unlocked || !F.get(e.achievementId).hidden));
|
|
414
|
+
}));
|
|
415
|
+
} catch (n) {
|
|
416
|
+
return x.fail(n instanceof e ? n : t("invalid_input"));
|
|
417
|
+
}
|
|
418
|
+
}, Q = (n, i) => {
|
|
419
|
+
try {
|
|
420
|
+
let e = o(n, [
|
|
421
|
+
"tenantId",
|
|
422
|
+
"subjectId",
|
|
423
|
+
"kind"
|
|
424
|
+
]), a = r(e.tenantId), s = r(e.subjectId);
|
|
425
|
+
if (e.kind !== "user" && e.kind !== "guest") throw t("forbidden");
|
|
426
|
+
return A(async () => (await H(a, s), d.transactional(async (e) => {
|
|
427
|
+
await W(e, a, s, !0);
|
|
428
|
+
let t = await K(e, a, s), n = await G(e, y, a, s), r = await G(e, g, a, s), o = await G(e, _, a, s);
|
|
429
|
+
if (!i) return {
|
|
430
|
+
achievements: t.map((e) => ({
|
|
431
|
+
achievementId: e.achievementId,
|
|
432
|
+
version: e.version,
|
|
433
|
+
tierId: e.tierId,
|
|
434
|
+
unlockedAt: k(e.unlockedAt),
|
|
435
|
+
sourceSequence: e.sourceSequence
|
|
436
|
+
})),
|
|
437
|
+
history: n.map((e) => ({
|
|
438
|
+
achievementId: e.achievementId,
|
|
439
|
+
tierId: e.tierId,
|
|
440
|
+
proof: e.proof
|
|
441
|
+
})),
|
|
442
|
+
evaluations: r.map((e) => e.receipt),
|
|
443
|
+
rewards: o.map((e) => ({
|
|
444
|
+
reward: e.reward,
|
|
445
|
+
state: e.state,
|
|
446
|
+
deliveryIntent: e.deliveryIntent ?? null,
|
|
447
|
+
deliveryReceipt: e.deliveryReceipt ?? null
|
|
448
|
+
}))
|
|
449
|
+
};
|
|
450
|
+
await e.deleteMany(b.tableName, { where: z(a, s) }), await e.updateMany(y.tableName, {
|
|
451
|
+
ownerId: null,
|
|
452
|
+
ownerKey: null,
|
|
453
|
+
proof: null
|
|
454
|
+
}, { where: B(a, s) }), await e.updateMany(g.tableName, {
|
|
455
|
+
ownerKey: null,
|
|
456
|
+
state: "erased",
|
|
457
|
+
sourceVersion: null,
|
|
458
|
+
sourceDigest: null,
|
|
459
|
+
configDigest: null,
|
|
460
|
+
view: null,
|
|
461
|
+
receipt: null
|
|
462
|
+
}, { where: B(a, s) }), await e.updateMany(_.tableName, {
|
|
463
|
+
ownerId: null,
|
|
464
|
+
ownerKey: null,
|
|
465
|
+
reward: null,
|
|
466
|
+
state: "erased",
|
|
467
|
+
deliveryIntent: null,
|
|
468
|
+
deliveryDigest: null,
|
|
469
|
+
deliveryReceipt: null,
|
|
470
|
+
deliveredAt: null
|
|
471
|
+
}, { where: B(a, s) }), await e.update(v.tableName, R(a, s), {
|
|
472
|
+
ownerId: null,
|
|
473
|
+
erased: !0,
|
|
474
|
+
sourceVersion: null,
|
|
475
|
+
sourceDigest: null,
|
|
476
|
+
configDigest: null,
|
|
477
|
+
view: null
|
|
478
|
+
});
|
|
479
|
+
})));
|
|
480
|
+
} catch (n) {
|
|
481
|
+
return x.fail(n instanceof e ? n : t("invalid_input"));
|
|
482
|
+
}
|
|
483
|
+
}, $ = (a, s, u, p) => {
|
|
484
|
+
try {
|
|
485
|
+
let e = n(a);
|
|
486
|
+
L(e);
|
|
487
|
+
let m = r(s), x = r(u);
|
|
488
|
+
return A(async () => (await H(m, x), d.transactional(async (e) => {
|
|
489
|
+
let n = await W(e, m, x), a = await G(e, y, m, x), s = await G(e, g, m, x), u = await G(e, _, m, x), d = [...s].sort((e, t) => Number(e.sequence) - Number(t.sequence)), S = /* @__PURE__ */ new Map(), C = 0, E = 0;
|
|
490
|
+
if (d.length > 0) for (let n of M.definitions) {
|
|
491
|
+
let r = (await e.query(T(h).where(w("id", O("pad_", m, n.id, String(n.version)))).limit(1).descriptor))[0];
|
|
492
|
+
if (!r || r.tenantId !== m || r.achievementId !== n.id || r.version !== n.version || r.rulesVersion !== M.strategies.version || l(r.config) !== l(n)) throw t("conflict");
|
|
493
|
+
}
|
|
494
|
+
if (d.length !== n.sequence) throw t("invalid_record");
|
|
495
|
+
for (let [e, n] of d.entries()) {
|
|
496
|
+
if (n.sequence !== e + 1 || n.state !== "committed" || n.configDigest !== N || Number(n.throughSequence) < C) throw t("invalid_record");
|
|
497
|
+
C = i(n.throughSequence, 0, 2147483647), r(n.sourceVersion), j(n.sourceDigest);
|
|
498
|
+
let s = Y(n);
|
|
499
|
+
if (s.at < E || e > 0 && n.sourceVersion !== d[e - 1].sourceVersion || e > 0 && n.throughSequence === d[e - 1].throughSequence && n.sourceDigest !== d[e - 1].sourceDigest) throw t("invalid_record");
|
|
500
|
+
E = s.at;
|
|
501
|
+
let p = X(n.view), h = a.filter((e) => e.operationId === n.id), g = u.filter((e) => e.operationId === n.id);
|
|
502
|
+
if (h.length !== s.unlockedIds.length || g.length !== s.rewardsQueued || new Set(h.map((e) => e.unlockId)).size !== h.length) throw t("invalid_record");
|
|
503
|
+
let _ = 0;
|
|
504
|
+
for (let e of h) {
|
|
505
|
+
let { definition: r, tier: a } = q(e.achievementId, e.tierId, e.version), u = J(m, x, r.id, r.version, a.id), d = p.find((e) => e.achievementId === r.id && e.tierId === a.id), h = o(e.proof, [
|
|
506
|
+
"sourceVersion",
|
|
507
|
+
"sourceDigest",
|
|
508
|
+
"rulesVersion",
|
|
509
|
+
"fulfilled",
|
|
510
|
+
"progress"
|
|
511
|
+
]);
|
|
512
|
+
if (S.has(u) || e.unlockId !== u || e.id !== O("pal_", u) || e.ownerId !== x || !s.unlockedIds.includes(u) || !d?.unlocked || d.unlockedAt !== k(e.unlockedAt) || k(e.unlockedAt) > s.at || h.sourceVersion !== n.sourceVersion || h.rulesVersion !== M.strategies.version || h.fulfilled !== !0) throw t("invalid_record");
|
|
513
|
+
j(h.sourceDigest), i(e.sourceSequence, 0, s.throughSequence);
|
|
514
|
+
let v = {
|
|
515
|
+
...d,
|
|
516
|
+
progress: h.progress
|
|
517
|
+
}, y = p.map((e) => e === d ? v : e), b = X(y).find((e) => e.achievementId === r.id && e.tierId === a.id);
|
|
518
|
+
if (M.strategies.achievementEvaluator === f) {
|
|
519
|
+
let e = /* @__PURE__ */ new Map();
|
|
520
|
+
for (let n of b.progress) {
|
|
521
|
+
let r = JSON.stringify([
|
|
522
|
+
n.stat,
|
|
523
|
+
n.period,
|
|
524
|
+
n.seasonId
|
|
525
|
+
]), i = e.get(r);
|
|
526
|
+
if (i && i.value !== n.value) throw t("invalid_record");
|
|
527
|
+
e.set(r, {
|
|
528
|
+
stat: n.stat,
|
|
529
|
+
period: n.period,
|
|
530
|
+
seasonId: n.seasonId,
|
|
531
|
+
value: n.value
|
|
532
|
+
});
|
|
533
|
+
}
|
|
534
|
+
if (!f({
|
|
535
|
+
condition: a.condition,
|
|
536
|
+
stats: [...e.values()]
|
|
537
|
+
}).met) throw t("invalid_record");
|
|
538
|
+
}
|
|
539
|
+
S.set(u, {
|
|
540
|
+
id: u,
|
|
541
|
+
tenantId: m,
|
|
542
|
+
ownerId: x,
|
|
543
|
+
achievementId: r.id,
|
|
544
|
+
version: r.version,
|
|
545
|
+
tierId: a.id,
|
|
546
|
+
unlockedAt: new Date(d.unlockedAt),
|
|
547
|
+
sourceSequence: e.sourceSequence,
|
|
548
|
+
operationId: n.id
|
|
549
|
+
});
|
|
550
|
+
for (let [e, n] of a.reward.entries()) {
|
|
551
|
+
let r = g.find((t) => t.id === O("par_", u, String(e)));
|
|
552
|
+
if (!r || r.unlockId !== u || r.ownerId !== x || l(r.reward) !== l(n) || k(r.createdAt) !== s.at || r.state !== "pending" && r.state !== "delivered" || r.state === "pending" && r.deliveredAt !== null || r.state === "delivered" && k(r.deliveredAt) < s.at) throw t("invalid_record");
|
|
553
|
+
c(r, "achievement", l), _++;
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
if (_ !== g.length || p.some((e) => {
|
|
557
|
+
let t = S.get(J(m, x, e.achievementId, e.version, e.tierId));
|
|
558
|
+
return e.unlocked !== (t !== void 0) || t !== void 0 && e.unlockedAt !== k(t.unlockedAt);
|
|
559
|
+
})) throw t("invalid_record");
|
|
560
|
+
}
|
|
561
|
+
if (a.length !== S.size || a.some((e) => !d.some((t) => t.id === e.operationId)) || u.some((e) => !d.some((t) => t.id === e.operationId))) throw t("invalid_record");
|
|
562
|
+
let D = d.at(-1), A = await K(e, m, x), P = (e) => ({
|
|
563
|
+
id: e.id,
|
|
564
|
+
achievementId: e.achievementId,
|
|
565
|
+
version: e.version,
|
|
566
|
+
tierId: e.tierId,
|
|
567
|
+
unlockedAt: k(e.unlockedAt),
|
|
568
|
+
sourceSequence: e.sourceSequence,
|
|
569
|
+
operationId: e.operationId
|
|
570
|
+
}), F = A.length === S.size && A.every((e) => S.has(String(e.id)) && l(P(e)) === l(P(S.get(String(e.id))))) && l(n.view) === l(D?.view ?? null) && n.throughSequence === (D?.throughSequence ?? 0) && n.sourceDigest === (D?.sourceDigest ?? null) && n.sourceVersion === (D?.sourceVersion ?? null) && n.configDigest === (D?.configDigest ?? null);
|
|
571
|
+
if (p && !F) {
|
|
572
|
+
await e.deleteMany(b.tableName, { where: z(m, x) });
|
|
573
|
+
for (let t of S.values()) await e.insert(b.tableName, t);
|
|
574
|
+
await e.update(v.tableName, R(m, x), {
|
|
575
|
+
throughSequence: D?.throughSequence ?? 0,
|
|
576
|
+
sourceDigest: D?.sourceDigest ?? null,
|
|
577
|
+
sourceVersion: D?.sourceVersion ?? null,
|
|
578
|
+
configDigest: D?.configDigest ?? null,
|
|
579
|
+
view: D?.view ?? null
|
|
580
|
+
});
|
|
581
|
+
}
|
|
582
|
+
return Object.freeze({
|
|
583
|
+
acceptedOperations: d.length,
|
|
584
|
+
unlocked: S.size,
|
|
585
|
+
rewardRows: u.length,
|
|
586
|
+
matches: p ? !0 : F
|
|
587
|
+
});
|
|
588
|
+
})));
|
|
589
|
+
} catch (n) {
|
|
590
|
+
return x.fail(n instanceof e ? n : t("invalid_input"));
|
|
591
|
+
}
|
|
592
|
+
};
|
|
593
|
+
return Object.freeze({
|
|
594
|
+
evaluate: te,
|
|
595
|
+
mine: ne,
|
|
596
|
+
exportSubject: (e) => Q(e, !1),
|
|
597
|
+
eraseSubject: (e) => x.asVoid(Q(e, !0)),
|
|
598
|
+
auditAchievements: (e, t, n) => $(e, t, n, !1),
|
|
599
|
+
rebuildAchievements: (e, t, n) => $(e, t, n, !0)
|
|
600
|
+
});
|
|
601
|
+
};
|
|
602
|
+
export { D as captureAchievementHistory, M as dataStoreAchievements, E as resolveAchievementOptions };
|