@voltro/plugin-leaderboards 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 (67) hide show
  1. package/CHANGELOG.md +24329 -0
  2. package/LICENSE +61 -0
  3. package/README.md +1087 -2
  4. package/SECURITY.md +56 -0
  5. package/THIRD-PARTY-NOTICES.md +5007 -0
  6. package/dist/administration.js +5 -0
  7. package/dist/bracketAdmission.js +294 -0
  8. package/dist/bracketAdmissionPolicy.js +22 -0
  9. package/dist/bracketInstallation.js +133 -0
  10. package/dist/bracketMatchPorts.js +5 -0
  11. package/dist/bracketMatches.js +546 -0
  12. package/dist/brackets.d.ts +149 -0
  13. package/dist/brackets.js +379 -0
  14. package/dist/bucketStore.js +93 -0
  15. package/dist/buckets.js +9 -0
  16. package/dist/errors.d.ts +13 -0
  17. package/dist/errors.js +17 -0
  18. package/dist/glicko2.js +72 -0
  19. package/dist/index.d.ts +1208 -0
  20. package/dist/index.js +15 -0
  21. package/dist/inspect.js +84 -0
  22. package/dist/json.js +39 -0
  23. package/dist/leaderboard.d.ts +49 -0
  24. package/dist/leaderboard.js +57 -0
  25. package/dist/leagueSchedule.js +40 -0
  26. package/dist/leagues.js +31 -0
  27. package/dist/openskill.js +74 -0
  28. package/dist/plugin.js +338 -0
  29. package/dist/portLifetime.js +67 -0
  30. package/dist/ports.d.ts +294 -0
  31. package/dist/ports.js +7 -0
  32. package/dist/rankQuery.js +24 -0
  33. package/dist/ranking.d.ts +42 -0
  34. package/dist/ranking.js +71 -0
  35. package/dist/rating.d.ts +103 -0
  36. package/dist/rating.js +50 -0
  37. package/dist/ratingPools.js +134 -0
  38. package/dist/ratingStore.js +334 -0
  39. package/dist/ratingStrategies.js +108 -0
  40. package/dist/records.d.ts +116 -0
  41. package/dist/records.js +88 -0
  42. package/dist/rpc.d.ts +321 -0
  43. package/dist/rpc.js +306 -0
  44. package/dist/score.d.ts +13 -0
  45. package/dist/score.js +27 -0
  46. package/dist/server.d.ts +1477 -0
  47. package/dist/server.js +17 -0
  48. package/dist/service.js +949 -0
  49. package/dist/subjectFences.js +44 -0
  50. package/dist/tables.entity.js +188 -0
  51. package/dist/testing.d.ts +872 -0
  52. package/dist/testing.js +368 -0
  53. package/dist/tournament-app/tournament.advance.workflow.server.tsx +3 -0
  54. package/dist/tournament-app/tournament.advance.workflow.tsx +12 -0
  55. package/dist/tournament-app/tournament.stage.workflow.server.tsx +3 -0
  56. package/dist/tournament-app/tournament.stage.workflow.tsx +10 -0
  57. package/dist/tournamentInstallation.js +168 -0
  58. package/dist/tournamentPrizes.js +34 -0
  59. package/dist/tournamentStage.js +151 -0
  60. package/dist/tournamentStagePorts.js +5 -0
  61. package/dist/tournamentWorkflow.js +101 -0
  62. package/dist/tournamentWorkflowSchemas.js +54 -0
  63. package/dist/tournaments.d.ts +32 -0
  64. package/dist/tournaments.js +21 -0
  65. package/dist/web.d.ts +175 -0
  66. package/dist/web.js +17 -0
  67. package/package.json +113 -4
@@ -0,0 +1,5 @@
1
+ import { Context as e } from "effect";
2
+ //#region src/administration.ts
3
+ var t = class extends e.Service()("@voltro/LeaderboardAdministration") {};
4
+ //#endregion
5
+ export { t as LeaderboardAdministration };
@@ -0,0 +1,294 @@
1
+ import { LeaderboardError as e, leaderboardError as t } from "./errors.js";
2
+ import { canonicalLeaderboardJson as n, captureLeaderboardJson as r } from "./json.js";
3
+ import { defineBracketAdmission as i } from "./bracketAdmissionPolicy.js";
4
+ import { makeLeaderboardSubjectFences as a } from "./subjectFences.js";
5
+ import { BracketAdmissionPort as o } from "./ports.js";
6
+ import { Effect as s, Layer as c, Schema as l } from "effect";
7
+ import { Subject as u } from "@voltro/protocol";
8
+ import { createHash as d } from "node:crypto";
9
+ import { and as f, eq as p, id as m, json as h, table as g, text as _, timestamp as v } from "@voltro/database";
10
+ //#region src/bracketAdmission.ts
11
+ var y = "_voltro_tournament_admissions", b = g(y, {
12
+ id: m({ prefix: "tadm" }),
13
+ tenantId: _().maxLength(120).externalId().sensitive("pii"),
14
+ tournamentId: _().maxLength(120).serverOnly(),
15
+ state: h().sensitive("pii"),
16
+ createdAt: v(),
17
+ updatedAt: v()
18
+ }).unique("byBracketAdmission", ["tenantId", "tournamentId"]).index(["tenantId"]), x = (e) => typeof e == "string" && e.length > 0 && e.length <= 120 && e.trim() === e && e.isWellFormed() && !/[\u0000-\u001f\u007f]/.test(e) ? e : S("invalid_input");
19
+ function S(e) {
20
+ throw t(e);
21
+ }
22
+ var C = (e) => Number.isSafeInteger(e) && e >= 0 && e <= 864e13 ? e : S("invalid_input"), w = (e) => {
23
+ let t = r(e, 1024);
24
+ return (!t || Object.keys(t).length !== 2 || !Object.hasOwn(t, "tenantId") || !Object.hasOwn(t, "tournamentId")) && S("invalid_input"), Object.freeze({
25
+ tenantId: x(t.tenantId),
26
+ tournamentId: x(t.tournamentId)
27
+ });
28
+ }, T = l.Struct({
29
+ ownerId: l.String,
30
+ joinedAt: l.Int,
31
+ checkedInAt: l.NullOr(l.Int)
32
+ }), E = l.Struct({
33
+ version: l.Literal(1),
34
+ definition: l.Struct({
35
+ registrationOpensAt: l.Int,
36
+ registrationClosesAt: l.Int,
37
+ checkInOpensAt: l.Int,
38
+ checkInClosesAt: l.Int,
39
+ maxEntries: l.Int
40
+ }),
41
+ phase: l.Literals([
42
+ "open",
43
+ "sealed",
44
+ "erasing",
45
+ "cancelled"
46
+ ]),
47
+ entries: l.Array(T),
48
+ eraseRequest: l.NullOr(l.String),
49
+ eraseTarget: l.NullOr(l.String)
50
+ }), D = (e, t) => {
51
+ (e.tenantId !== t.tenantId || e.tournamentId !== t.tournamentId) && S("unavailable");
52
+ let n = l.decodeUnknownSync(E)(r(e.state, 65536), { onExcessProperty: "error" });
53
+ i(n.definition), (n.entries.length > n.definition.maxEntries || new Set(n.entries.map((e) => e.ownerId)).size !== n.entries.length) && S("unavailable");
54
+ for (let e of n.entries) x(e.ownerId), C(e.joinedAt), (e.joinedAt < n.definition.registrationOpensAt || e.joinedAt >= n.definition.registrationClosesAt) && S("unavailable"), e.checkedInAt !== null && (C(e.checkedInAt) < n.definition.checkInOpensAt || e.checkedInAt >= n.definition.checkInClosesAt) && S("unavailable");
55
+ n.eraseRequest !== null && x(n.eraseRequest), (n.eraseRequest === null != (n.eraseTarget === null) || n.eraseTarget !== null && !/^[a-f0-9]{64}$/.test(n.eraseTarget) || n.phase === "erasing" && n.eraseRequest === null || ["open", "sealed"].includes(n.phase) && n.eraseRequest !== null) && S("unavailable");
56
+ for (let t of ["createdAt", "updatedAt"]) (!(e[t] instanceof Date) || !Number.isFinite(e[t].getTime())) && S("unavailable");
57
+ return n;
58
+ }, O = async (e, t, n = !1) => {
59
+ let r = await e.query({
60
+ table: y,
61
+ predicate: f(p("tenantId", t.tenantId), p("tournamentId", t.tournamentId)),
62
+ order: [],
63
+ take: 2,
64
+ skip: void 0,
65
+ projection: void 0,
66
+ ...n ? { lock: "update" } : {}
67
+ });
68
+ return r.length !== 1 && S(r.length ? "unavailable" : "not_found"), {
69
+ row: r[0],
70
+ state: D(r[0], t)
71
+ };
72
+ }, k = (n, r) => {
73
+ let i;
74
+ try {
75
+ i = w(r);
76
+ } catch (n) {
77
+ return s.fail(n instanceof e ? n : t("invalid_input"));
78
+ }
79
+ return s.tryPromise({
80
+ try: async () => {
81
+ let { state: e } = await O(n, i);
82
+ return Object.freeze({
83
+ phase: e.phase,
84
+ definition: Object.freeze({ ...e.definition })
85
+ });
86
+ },
87
+ catch: (n) => n instanceof e ? n : t("unavailable")
88
+ }).pipe(s.uninterruptible);
89
+ }, A = (e) => {
90
+ let t = r(e, 2048);
91
+ return (!t || Object.keys(t).some((e) => !["requestId", "target"].includes(e)) || !t.target || Object.keys(t.target).some((e) => ![
92
+ "tenantId",
93
+ "subjectId",
94
+ "kind"
95
+ ].includes(e)) || !["user", "guest"].includes(t.target.kind)) && S("invalid_input"), Object.freeze({
96
+ requestId: x(t.requestId),
97
+ target: Object.freeze({
98
+ tenantId: x(t.target.tenantId),
99
+ subjectId: x(t.target.subjectId),
100
+ kind: t.target.kind
101
+ })
102
+ });
103
+ }, j = (e) => {
104
+ (!e || typeof e != "object" || Object.getPrototypeOf(e) !== Object.prototype || Object.getOwnPropertySymbols(e).length) && S("invalid_input");
105
+ let t = Object.getOwnPropertyDescriptors(e);
106
+ Object.entries(t).some(([e, t]) => ![
107
+ "epochNow",
108
+ "maxTenantTournaments",
109
+ "authorize",
110
+ "withdrawSubject",
111
+ "withdrawTournament",
112
+ "authorizeExport"
113
+ ].includes(e) || !t.enumerable || !("value" in t)) && S("invalid_input");
114
+ let n = e.maxTenantTournaments ?? 1024;
115
+ return (typeof e.epochNow != "function" || !Number.isSafeInteger(n) || n < 1 || n > 4096 || [
116
+ "authorize",
117
+ "withdrawSubject",
118
+ "withdrawTournament",
119
+ "authorizeExport"
120
+ ].some((t) => typeof Reflect.get(e, t) != "function")) && S("invalid_input"), Object.freeze({
121
+ epochNow: e.epochNow.bind(e),
122
+ maxTenantTournaments: n,
123
+ authorize: e.authorize.bind(e),
124
+ withdrawSubject: e.withdrawSubject.bind(e),
125
+ withdrawTournament: e.withdrawTournament.bind(e),
126
+ authorizeExport: e.authorizeExport.bind(e)
127
+ });
128
+ }, M = (o, c) => {
129
+ let f = j(c), m = f.epochNow, h = f.maxTenantTournaments, { authorize: g, withdrawSubject: _, withdrawTournament: v, authorizeExport: b } = f, { seedSubject: T, subjectFence: E, eraseSubjectFence: k } = a(o), M = (n) => {
130
+ try {
131
+ return n();
132
+ } catch (n) {
133
+ return s.fail(n instanceof e ? n : t("invalid_input"));
134
+ }
135
+ }, N = (n) => s.tryPromise({
136
+ try: n,
137
+ catch: (n) => n instanceof e ? n : t("unavailable")
138
+ }).pipe(s.uninterruptible), P = O, F = async (e, t, n) => {
139
+ r(n, 65536), await e.update("_voltro_tournament_admissions", String(t.id), {
140
+ state: n,
141
+ updatedAt: new Date(C(m()))
142
+ }) || S("unavailable");
143
+ }, I = (e, t) => ((e.type !== "user" || e.tenantId !== t.tenantId || e.id === null) && S("forbidden"), x(e.id)), L = (e) => {
144
+ e.type !== "system" && e.type !== "service" && S("forbidden");
145
+ }, R = (e, t) => Object.freeze({
146
+ phase: e.phase,
147
+ entries: e.entries.length,
148
+ checkedIn: e.entries.filter((e) => e.checkedInAt !== null).length,
149
+ own: e.entries.some((e) => e.ownerId === t) ? Object.freeze({ ...e.entries.find((e) => e.ownerId === t) }) : null
150
+ }), z = async (e) => {
151
+ let t = await o.query({
152
+ table: y,
153
+ predicate: p("tenantId", e),
154
+ order: [],
155
+ take: h + 1,
156
+ skip: void 0,
157
+ projection: void 0
158
+ });
159
+ t.length > h && S("limit_exceeded");
160
+ let n = t.map((t) => {
161
+ let n = w({
162
+ tenantId: e,
163
+ tournamentId: x(t.tournamentId)
164
+ });
165
+ return {
166
+ scope: n,
167
+ state: D(t, n)
168
+ };
169
+ });
170
+ return new Set(n.map((e) => e.scope.tournamentId)).size !== n.length && S("unavailable"), n.sort((e, t) => e.scope.tournamentId < t.scope.tournamentId ? -1 : +(e.scope.tournamentId > t.scope.tournamentId));
171
+ };
172
+ return Object.freeze({
173
+ create: (e, t, r) => M(() => {
174
+ let a = w(t), c = l.decodeUnknownSync(l.toType(u))(structuredClone(e)), d = i(r);
175
+ return L(c), g(c, a, "create").pipe(s.flatMap(() => N(async () => {
176
+ let e = C(m());
177
+ await o.insertIgnore(y, {
178
+ ...a,
179
+ state: {
180
+ version: 1,
181
+ definition: d,
182
+ phase: "open",
183
+ entries: [],
184
+ eraseRequest: null,
185
+ eraseTarget: null
186
+ },
187
+ createdAt: new Date(e),
188
+ updatedAt: new Date(e)
189
+ }, { conflictColumns: ["tenantId", "tournamentId"] });
190
+ let { state: t } = await P(o, a);
191
+ n(t.definition) !== n(d) && S("conflict");
192
+ })));
193
+ }),
194
+ register: (e, t) => M(() => {
195
+ let n = w(t), r = l.decodeUnknownSync(l.toType(u))(structuredClone(e)), i = I(r, n);
196
+ return g(r, n, "register").pipe(s.flatMap(() => N(() => T(n.tenantId, i))), s.flatMap(() => N(() => o.transactional(async (e) => {
197
+ await E(e, n.tenantId, i);
198
+ let { row: t, state: r } = await P(e, n, !0), a = C(m());
199
+ if (r.phase !== "open" && S("conflict"), r.entries.some((e) => e.ownerId === i)) return R(r, i);
200
+ (a < r.definition.registrationOpensAt || a >= r.definition.registrationClosesAt) && S("conflict"), r.entries.length >= r.definition.maxEntries && S("limit_exceeded");
201
+ let o = {
202
+ ...r,
203
+ entries: [...r.entries, {
204
+ ownerId: i,
205
+ joinedAt: a,
206
+ checkedInAt: null
207
+ }]
208
+ };
209
+ return await F(e, t, o), R(o, i);
210
+ }))));
211
+ }),
212
+ checkIn: (e, t) => M(() => {
213
+ let n = w(t), r = l.decodeUnknownSync(l.toType(u))(structuredClone(e)), i = I(r, n);
214
+ return g(r, n, "checkIn").pipe(s.flatMap(() => N(() => T(n.tenantId, i))), s.flatMap(() => N(() => o.transactional(async (e) => {
215
+ await E(e, n.tenantId, i);
216
+ let { row: t, state: r } = await P(e, n, !0), a = C(m()), o = r.entries.find((e) => e.ownerId === i);
217
+ if ((r.phase !== "open" || !o) && S("conflict"), o.checkedInAt !== null) return R(r, i);
218
+ (a < r.definition.checkInOpensAt || a >= r.definition.checkInClosesAt) && S("conflict");
219
+ let s = {
220
+ ...r,
221
+ entries: r.entries.map((e) => e.ownerId === i ? {
222
+ ...e,
223
+ checkedInAt: a
224
+ } : e)
225
+ };
226
+ return await F(e, t, s), R(s, i);
227
+ }))));
228
+ }),
229
+ status: (e, t) => M(() => {
230
+ let n = w(t), r = l.decodeUnknownSync(l.toType(u))(structuredClone(e)), i = I(r, n);
231
+ return g(r, n, "status").pipe(s.flatMap(() => N(async () => R((await P(o, n)).state, i))));
232
+ }),
233
+ entrants: (e, t) => M(() => {
234
+ let n = w(t), r = l.decodeUnknownSync(l.toType(u))(structuredClone(e));
235
+ return L(r), g(r, n, "entrants").pipe(s.flatMap(() => N(async () => {
236
+ let e = (await P(o, n)).state;
237
+ return Object.freeze({
238
+ phase: e.phase,
239
+ entries: Object.freeze(e.entries.map((e) => Object.freeze({ ...e })))
240
+ });
241
+ })));
242
+ }),
243
+ seal: (e, t) => M(() => {
244
+ let r = w(t), i = l.decodeUnknownSync(l.toType(u))(structuredClone(e));
245
+ return L(i), g(i, r, "seal").pipe(s.flatMap(() => N(() => P(o, r))), s.flatMap((e) => N(() => o.transactional(async (t) => {
246
+ let i = e.state.entries.map((e) => e.ownerId).sort();
247
+ for (let e of i) await E(t, r.tenantId, e);
248
+ let { row: a, state: o } = await P(t, r, !0);
249
+ return n(o.entries.map((e) => e.ownerId).sort()) !== n(i) && S("conflict"), (!["open", "sealed"].includes(o.phase) || C(m()) < o.definition.checkInClosesAt) && S("conflict"), o.phase === "open" && await F(t, a, {
250
+ ...o,
251
+ phase: "sealed"
252
+ }), Object.freeze({
253
+ checkedIn: Object.freeze(o.entries.filter((e) => e.checkedInAt !== null).map((e) => e.ownerId)),
254
+ noShows: Object.freeze(o.entries.filter((e) => e.checkedInAt === null).map((e) => e.ownerId))
255
+ });
256
+ }))));
257
+ }),
258
+ exportSubject: (e) => M(() => {
259
+ let t = A(e);
260
+ return b(t).pipe(s.flatMap(() => N(async () => (await z(t.target.tenantId)).flatMap(({ scope: e, state: n }) => {
261
+ let r = n.entries.find((e) => e.ownerId === t.target.subjectId);
262
+ return r ? [{
263
+ tournamentId: e.tournamentId,
264
+ phase: n.phase,
265
+ ...r
266
+ }] : [];
267
+ }))));
268
+ }),
269
+ eraseSubject: (e) => M(() => {
270
+ let t = A(e), r = d("sha256").update(n(t.target)).digest("hex");
271
+ return _(t).pipe(s.flatMap(() => N(() => k(t.target.tenantId, t.target.subjectId))), s.flatMap(() => N(() => z(t.target.tenantId))), s.flatMap((e) => s.forEach(e.filter((e) => e.state.entries.some((e) => e.ownerId === t.target.subjectId) || e.state.eraseTarget === r && e.state.eraseRequest === t.requestId), ({ scope: e }) => N(() => o.transactional(async (n) => {
272
+ let { row: i, state: a } = await P(n, e, !0), o = a.entries.some((e) => e.ownerId === t.target.subjectId);
273
+ return !o && a.phase === "cancelled" && a.eraseRequest === t.requestId && a.eraseTarget === r || (o || S("unavailable"), a.phase === "erasing" && (a.eraseRequest !== t.requestId || a.eraseTarget !== r) && S("conflict"), await F(n, i, {
274
+ ...a,
275
+ phase: "erasing",
276
+ eraseRequest: t.requestId,
277
+ eraseTarget: r
278
+ }), !1);
279
+ })).pipe(s.flatMap((n) => n ? s.void : v(e, t).pipe(s.flatMap(() => N(() => o.transactional(async (n) => {
280
+ let { row: i, state: a } = await P(n, e, !0);
281
+ (a.phase !== "erasing" || a.eraseRequest !== t.requestId || a.eraseTarget !== r) && S("conflict"), await F(n, i, {
282
+ ...a,
283
+ phase: "cancelled",
284
+ entries: a.entries.filter((e) => e.ownerId !== t.target.subjectId)
285
+ });
286
+ })))))), {
287
+ concurrency: 1,
288
+ discard: !0
289
+ })));
290
+ })
291
+ });
292
+ }, N = (e, t) => c.succeed(o, M(e, t));
293
+ //#endregion
294
+ export { y as BRACKET_ADMISSIONS_TABLE, N as bracketAdmissionLayer, b as bracketAdmissionsTable, M as dataStoreBracketAdmissions, k as readBracketAdmissionWindow, j as resolveBracketAdmissionOptions };
@@ -0,0 +1,22 @@
1
+ import { leaderboardError as e } from "./errors.js";
2
+ import { captureLeaderboardJson as t } from "./json.js";
3
+ import { Schema as n } from "effect";
4
+ //#region src/bracketAdmissionPolicy.ts
5
+ var r = n.Struct({
6
+ registrationOpensAt: n.Int,
7
+ registrationClosesAt: n.Int,
8
+ checkInOpensAt: n.Int,
9
+ checkInClosesAt: n.Int,
10
+ maxEntries: n.Int
11
+ }), i = (i) => {
12
+ let a;
13
+ try {
14
+ a = n.decodeUnknownSync(r)(t(i, 1024), { onExcessProperty: "error" });
15
+ } catch {
16
+ throw e("invalid_input");
17
+ }
18
+ if (a.registrationOpensAt < 0 || a.registrationClosesAt <= a.registrationOpensAt || a.checkInOpensAt < a.registrationClosesAt || a.checkInClosesAt <= a.checkInOpensAt || a.checkInClosesAt > 864e13 || a.maxEntries < 2 || a.maxEntries > 256) throw e("invalid_input");
19
+ return Object.freeze(a);
20
+ };
21
+ //#endregion
22
+ export { i as defineBracketAdmission };
@@ -0,0 +1,133 @@
1
+ import { LeaderboardError as e, leaderboardError as t } from "./errors.js";
2
+ import { captureLeaderboardJson as n } from "./json.js";
3
+ import { defineBracketAdmission as r } from "./bracketAdmissionPolicy.js";
4
+ import { dataStoreBracketAdmissions as i, resolveBracketAdmissionOptions as a } from "./bracketAdmission.js";
5
+ import { Effect as o, Schema as s } from "effect";
6
+ import { Subject as c } from "@voltro/protocol";
7
+ //#region src/bracketInstallation.ts
8
+ var l = [
9
+ "create",
10
+ "register",
11
+ "checkIn",
12
+ "status",
13
+ "seal",
14
+ "entrants",
15
+ "exportSubject",
16
+ "eraseSubject"
17
+ ];
18
+ function u() {
19
+ throw t("invalid_input");
20
+ }
21
+ var d = (e) => {
22
+ (!e || typeof e != "object") && u();
23
+ for (let t of l) {
24
+ let n = Object.getOwnPropertyDescriptor(e, t);
25
+ (!n || !("value" in n) || typeof n.value != "function") && u();
26
+ }
27
+ return Object.freeze({
28
+ create: e.create.bind(e),
29
+ register: e.register.bind(e),
30
+ checkIn: e.checkIn.bind(e),
31
+ status: e.status.bind(e),
32
+ seal: e.seal.bind(e),
33
+ entrants: e.entrants.bind(e),
34
+ exportSubject: e.exportSubject.bind(e),
35
+ eraseSubject: e.eraseSubject.bind(e)
36
+ });
37
+ }, f = (l) => {
38
+ let f, p, m = null, h = Object.freeze([]);
39
+ if (l !== void 0) {
40
+ (!l || Object.getPrototypeOf(l) !== Object.prototype || Object.getOwnPropertySymbols(l).length) && u();
41
+ let e = Object.getOwnPropertyDescriptors(l);
42
+ Object.values(e).some((e) => !e.enumerable || !("value" in e)) && u(), l.backend === "sql" && Object.keys(e).length === 2 && Object.hasOwn(e, "options") ? (f = a(l.options), h = Object.freeze(["_voltro_tournament_admissions"]), m = Object.freeze({
43
+ backend: "sql",
44
+ version: "voltro:bracket-admission:1",
45
+ maxTenantTournaments: f.maxTenantTournaments
46
+ })) : l.backend === "custom" && Object.keys(e).length === 4 && Object.hasOwn(e, "version") && Object.hasOwn(e, "service") && Object.hasOwn(e, "sources") ? ((typeof l.version != "string" || !/^[a-zA-Z0-9][a-zA-Z0-9:._-]{0,119}$/.test(l.version) || l.version.startsWith("voltro:")) && u(), p = d(l.service), h = n(l.sources, 4096), (!Array.isArray(h) || h.length < 1 || h.length > 32 || new Set(h).size !== h.length || h.some((e) => typeof e != "string" || !/^[a-zA-Z_][a-zA-Z0-9_]{0,119}$/.test(e))) && u(), m = Object.freeze({
47
+ backend: "custom",
48
+ version: l.version,
49
+ maxTenantTournaments: null
50
+ })) : u();
51
+ }
52
+ let g, _ = !1, v = 0, y = /* @__PURE__ */ new Set(), b = () => {
53
+ if (v--, v === 0) for (let e of [...y]) e();
54
+ }, x = (n) => {
55
+ let r;
56
+ try {
57
+ r = n();
58
+ } catch (n) {
59
+ return o.fail(n instanceof e ? n : t("invalid_input"));
60
+ }
61
+ return o.acquireUseRelease(o.suspend(() => g === void 0 || _ ? o.fail(t("unavailable")) : (v++, o.succeed(g))), (e) => o.suspend(() => r(e)), () => o.sync(b)).pipe(o.uninterruptible);
62
+ }, S = (e) => s.decodeUnknownSync(s.toType(c))(structuredClone(e)), C = (e) => s.decodeUnknownSync(s.Struct({
63
+ requestId: s.NonEmptyString,
64
+ target: s.Struct({
65
+ subjectId: s.NonEmptyString,
66
+ tenantId: s.NullOr(s.NonEmptyString),
67
+ kind: s.Literals(["user", "guest"])
68
+ })
69
+ }))(n(e, 2048), { onExcessProperty: "error" }), w = Object.freeze({
70
+ create: (e, t, i) => x(() => {
71
+ let a = S(e), o = n(t, 1024), s = r(i);
72
+ return (e) => e.create(a, o, s);
73
+ }),
74
+ register: (e, t) => x(() => {
75
+ let r = S(e), i = n(t, 1024);
76
+ return (e) => e.register(r, i);
77
+ }),
78
+ checkIn: (e, t) => x(() => {
79
+ let r = S(e), i = n(t, 1024);
80
+ return (e) => e.checkIn(r, i);
81
+ }),
82
+ status: (e, t) => x(() => {
83
+ let r = S(e), i = n(t, 1024);
84
+ return (e) => e.status(r, i);
85
+ }),
86
+ seal: (e, t) => x(() => {
87
+ let r = S(e), i = n(t, 1024);
88
+ return (e) => e.seal(r, i);
89
+ }),
90
+ entrants: (e, t) => x(() => {
91
+ let r = S(e), i = n(t, 1024);
92
+ return (e) => e.entrants(r, i);
93
+ }),
94
+ exportSubject: (e) => x(() => {
95
+ let t = C(e);
96
+ return (e) => e.exportSubject(t);
97
+ }),
98
+ eraseSubject: (e) => x(() => {
99
+ let t = C(e);
100
+ return (e) => e.eraseSubject(t);
101
+ })
102
+ });
103
+ return Object.freeze({
104
+ configuration: m,
105
+ sources: h,
106
+ service: w,
107
+ isBound: () => g !== void 0 && !_,
108
+ boundService: () => _ ? void 0 : g,
109
+ bind: (e) => {
110
+ if (_) throw t("unavailable");
111
+ g = f === void 0 ? p : i(e, f);
112
+ },
113
+ close: () => {
114
+ _ = !0, g = void 0;
115
+ },
116
+ deactivate: () => o.sync(() => {
117
+ _ = !0, g = void 0;
118
+ }).pipe(o.flatMap(() => o.callback((e) => {
119
+ if (v === 0) {
120
+ e(o.void);
121
+ return;
122
+ }
123
+ let t = () => {
124
+ y.delete(t), e(o.void);
125
+ };
126
+ return y.add(t), o.sync(() => {
127
+ y.delete(t);
128
+ });
129
+ })))
130
+ });
131
+ };
132
+ //#endregion
133
+ export { f as makeBracketAdmissionInstallation };
@@ -0,0 +1,5 @@
1
+ import { Context as e } from "effect";
2
+ //#region src/bracketMatchPorts.ts
3
+ var t = class extends e.Service()("@voltro/TournamentBracketPort") {};
4
+ //#endregion
5
+ export { t as TournamentBracketPort };