@voltro/plugin-matchmaking 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 (47) hide show
  1. package/CHANGELOG.md +24492 -0
  2. package/LICENSE +61 -0
  3. package/README.md +272 -2
  4. package/SECURITY.md +56 -0
  5. package/THIRD-PARTY-NOTICES.md +8333 -0
  6. package/dist/admission.entity.js +17 -0
  7. package/dist/assignment.js +125 -0
  8. package/dist/avoidPairs.js +4 -0
  9. package/dist/contract.js +105 -0
  10. package/dist/director-app/matchmaking.director.workflow.server.tsx +5 -0
  11. package/dist/director-app/matchmaking.director.workflow.tsx +13 -0
  12. package/dist/director.js +72 -0
  13. package/dist/directorContract.js +15 -0
  14. package/dist/directorWorkflow.js +5 -0
  15. package/dist/errors.d.ts +13 -0
  16. package/dist/errors.js +20 -0
  17. package/dist/index.d.ts +523 -0
  18. package/dist/index.js +12 -0
  19. package/dist/inspect.js +40 -0
  20. package/dist/packing.js +71 -0
  21. package/dist/parties.js +316 -0
  22. package/dist/party.entity.js +33 -0
  23. package/dist/partyComponents.js +176 -0
  24. package/dist/partyContract.js +24 -0
  25. package/dist/plugin.js +257 -0
  26. package/dist/port.d.ts +116 -0
  27. package/dist/port.js +4 -0
  28. package/dist/queue.d.ts +91 -0
  29. package/dist/queue.js +79 -0
  30. package/dist/queueDeclarations.js +27 -0
  31. package/dist/roomsAllocator.d.ts +67 -0
  32. package/dist/roomsAllocator.js +75 -0
  33. package/dist/rpc.d.ts +247 -0
  34. package/dist/rpc.js +201 -0
  35. package/dist/server.d.ts +337 -0
  36. package/dist/server.js +8 -0
  37. package/dist/service.js +369 -0
  38. package/dist/strategies.d.ts +97 -0
  39. package/dist/strategies.js +140 -0
  40. package/dist/testing.d.ts +296 -0
  41. package/dist/testing.js +151 -0
  42. package/dist/ticketContract.d.ts +52 -0
  43. package/dist/ticketContract.js +30 -0
  44. package/dist/tickets.entity.js +49 -0
  45. package/dist/web.d.ts +279 -0
  46. package/dist/web.js +7 -0
  47. package/package.json +104 -4
package/dist/web.d.ts ADDED
@@ -0,0 +1,279 @@
1
+ import { ActionState } from '@voltro/client';
2
+ import { ReactNode } from 'react';
3
+ import { Schema } from 'effect';
4
+ import { SubscriptionIdle } from '@voltro/client';
5
+ import { SubscriptionState } from '@voltro/client';
6
+
7
+ /** Intentions only: the server derives leader, members, capacity and expiry. */
8
+ declare interface CreatePartyIntent {
9
+ readonly requestId: string;
10
+ readonly maxSize?: number;
11
+ readonly approval?: 'open' | 'leader';
12
+ }
13
+
14
+ /** Players send a queue preference intent; never skill, members, state or assignments. */
15
+ declare interface EnqueueIntent {
16
+ readonly queue: string;
17
+ readonly requestId: string;
18
+ readonly preferences: Readonly<Record<string, unknown>>;
19
+ }
20
+
21
+ declare type Party = typeof PartySchema.Type;
22
+
23
+ export declare interface PartyLabels {
24
+ readonly title: string;
25
+ readonly empty: string;
26
+ readonly create: string;
27
+ readonly leader: string;
28
+ readonly member: string;
29
+ readonly ready: string;
30
+ readonly notReady: string;
31
+ readonly markReady: string;
32
+ readonly markNotReady: string;
33
+ readonly invite: string;
34
+ readonly invitePlaceholder: string;
35
+ readonly leave: string;
36
+ readonly kick: string;
37
+ readonly promote: string;
38
+ readonly unknown: string;
39
+ readonly full: string;
40
+ }
41
+
42
+ export declare const partyLabels: Readonly<Record<'en' | 'de', PartyLabels>>;
43
+
44
+ /** Presentational party roster; every button is an intention, never local state. */
45
+ export declare const PartyPanel: ({ party, selfId, names, labels, pending, onCreate, onInvite, onLeave, onKick, onPromote, onReady }: PartyPanelProps) => ReactNode;
46
+
47
+ export declare interface PartyPanelProps {
48
+ readonly party: Party | null;
49
+ /** The signed-in subject; actions are shown by role, the server still decides. */
50
+ readonly selfId: string;
51
+ /** Names only from an authorized projection (e.g. Players); unknown IDs show `labels.unknown`. */
52
+ readonly names?: Readonly<Record<string, string>>;
53
+ readonly labels?: PartyLabels;
54
+ readonly pending?: boolean;
55
+ readonly onCreate?: () => void;
56
+ readonly onInvite?: (subjectId: string) => void;
57
+ readonly onLeave?: () => void;
58
+ readonly onKick?: (subjectId: string) => void;
59
+ readonly onPromote?: (subjectId: string) => void;
60
+ readonly onReady?: (ready: boolean) => void;
61
+ }
62
+
63
+ declare const PartySchema: Schema.Struct<{
64
+ readonly id: Schema.String;
65
+ readonly leaderId: Schema.String;
66
+ readonly maxSize: Schema.Number;
67
+ readonly approval: Schema.Literals<readonly ["open", "leader"]>;
68
+ readonly createdAt: Schema.Number;
69
+ readonly members: Schema.$Array<Schema.Struct<{
70
+ readonly subjectId: Schema.String;
71
+ readonly role: Schema.Literals<readonly ["leader", "member"]>;
72
+ readonly ready: Schema.Boolean;
73
+ readonly joinedAt: Schema.Number;
74
+ }>>;
75
+ /** The open party search ticket, readable by every member through `matchmaking.status`. */
76
+ readonly searchTicketId: Schema.NullOr<Schema.String>;
77
+ }>;
78
+
79
+ declare interface PartyTargetIntent {
80
+ readonly partyId: string;
81
+ readonly subjectId: string;
82
+ }
83
+
84
+ export declare const useCancelMatchmaking: (apiName?: string) => ActionState<{
85
+ ticketId: string;
86
+ }, void>;
87
+
88
+ export declare const useCancelPartySearch: (apiName?: string) => ActionState<{
89
+ partyId: string;
90
+ }, {
91
+ readonly id: string;
92
+ readonly leaderId: string;
93
+ readonly maxSize: number;
94
+ readonly approval: "open" | "leader";
95
+ readonly createdAt: number;
96
+ readonly members: readonly {
97
+ readonly subjectId: string;
98
+ readonly role: "member" | "leader";
99
+ readonly ready: boolean;
100
+ readonly joinedAt: number;
101
+ }[];
102
+ readonly searchTicketId: string | null;
103
+ }>;
104
+
105
+ export declare const useCreateParty: (apiName?: string) => ActionState<CreatePartyIntent, {
106
+ readonly id: string;
107
+ readonly leaderId: string;
108
+ readonly maxSize: number;
109
+ readonly approval: "open" | "leader";
110
+ readonly createdAt: number;
111
+ readonly members: readonly {
112
+ readonly subjectId: string;
113
+ readonly role: "member" | "leader";
114
+ readonly ready: boolean;
115
+ readonly joinedAt: number;
116
+ }[];
117
+ readonly searchTicketId: string | null;
118
+ }>;
119
+
120
+ /** Explicit intent action; no effect auto-enqueues or owns a retry timer. */
121
+ export declare const useEnqueueMatchmaking: (apiName?: string) => ActionState<EnqueueIntent, {
122
+ readonly id: string;
123
+ readonly queue: string;
124
+ readonly state: "open" | "expired" | "matched" | "cancelled" | "assigned";
125
+ readonly members: readonly string[];
126
+ readonly attributes: {
127
+ readonly [x: string]: unknown;
128
+ };
129
+ readonly createdAt: number;
130
+ readonly expiresAt: number;
131
+ readonly closedAt: number | null;
132
+ readonly metadata: {
133
+ readonly [x: string]: unknown;
134
+ };
135
+ }>;
136
+
137
+ export declare const useInviteToParty: (apiName?: string) => ActionState<PartyTargetIntent, {
138
+ readonly partyId: string;
139
+ readonly inviterId: string;
140
+ readonly expiresAt: number;
141
+ }>;
142
+
143
+ export declare const useJoinParty: (apiName?: string) => ActionState<{
144
+ partyId: string;
145
+ }, {
146
+ readonly id: string;
147
+ readonly leaderId: string;
148
+ readonly maxSize: number;
149
+ readonly approval: "open" | "leader";
150
+ readonly createdAt: number;
151
+ readonly members: readonly {
152
+ readonly subjectId: string;
153
+ readonly role: "member" | "leader";
154
+ readonly ready: boolean;
155
+ readonly joinedAt: number;
156
+ }[];
157
+ readonly searchTicketId: string | null;
158
+ }>;
159
+
160
+ export declare const useKickFromParty: (apiName?: string) => ActionState<PartyTargetIntent, {
161
+ readonly id: string;
162
+ readonly leaderId: string;
163
+ readonly maxSize: number;
164
+ readonly approval: "open" | "leader";
165
+ readonly createdAt: number;
166
+ readonly members: readonly {
167
+ readonly subjectId: string;
168
+ readonly role: "member" | "leader";
169
+ readonly ready: boolean;
170
+ readonly joinedAt: number;
171
+ }[];
172
+ readonly searchTicketId: string | null;
173
+ }>;
174
+
175
+ export declare const useLeaveParty: (apiName?: string) => ActionState<{
176
+ partyId: string;
177
+ }, void>;
178
+
179
+ /** The caller's Room seats from matches, newest first; enter one with `joinSeat` from `@voltro/plugin-rooms/web`. */
180
+ export declare const useMatchmakingAssignments: (apiName?: string) => SubscriptionState<readonly {
181
+ readonly ticketId: string;
182
+ readonly queue: string;
183
+ readonly roomId: string;
184
+ readonly sessionId: string;
185
+ readonly createdAt: number;
186
+ }[]>;
187
+
188
+ /** A caller-owned SQL ticket subscription; absent selection stays idle. */
189
+ export declare const useMatchmakingStatus: (ticketId: string | undefined, apiName?: string) => SubscriptionIdle | SubscriptionState<{
190
+ readonly id: string;
191
+ readonly queue: string;
192
+ readonly state: "open" | "expired" | "matched" | "cancelled" | "assigned";
193
+ readonly members: readonly string[];
194
+ readonly attributes: {
195
+ readonly [x: string]: unknown;
196
+ };
197
+ readonly createdAt: number;
198
+ readonly expiresAt: number;
199
+ readonly closedAt: number | null;
200
+ readonly metadata: {
201
+ readonly [x: string]: unknown;
202
+ };
203
+ }>;
204
+
205
+ /** The caller's current party (or null); re-runs on every roster change. */
206
+ export declare const useParty: (apiName?: string) => SubscriptionState<{
207
+ readonly id: string;
208
+ readonly leaderId: string;
209
+ readonly maxSize: number;
210
+ readonly approval: "open" | "leader";
211
+ readonly createdAt: number;
212
+ readonly members: readonly {
213
+ readonly subjectId: string;
214
+ readonly role: "member" | "leader";
215
+ readonly ready: boolean;
216
+ readonly joinedAt: number;
217
+ }[];
218
+ readonly searchTicketId: string | null;
219
+ } | null>;
220
+
221
+ export declare const usePartyInvites: (apiName?: string) => SubscriptionState<readonly {
222
+ readonly partyId: string;
223
+ readonly inviterId: string;
224
+ readonly expiresAt: number;
225
+ }[]>;
226
+
227
+ /** Leader-only party search: every member must be ready; any roster or readiness change cancels it. */
228
+ export declare const useSearchAsParty: (apiName?: string) => ActionState<EnqueueIntent & {
229
+ partyId: string;
230
+ }, {
231
+ readonly id: string;
232
+ readonly queue: string;
233
+ readonly state: "open" | "expired" | "matched" | "cancelled" | "assigned";
234
+ readonly members: readonly string[];
235
+ readonly attributes: {
236
+ readonly [x: string]: unknown;
237
+ };
238
+ readonly createdAt: number;
239
+ readonly expiresAt: number;
240
+ readonly closedAt: number | null;
241
+ readonly metadata: {
242
+ readonly [x: string]: unknown;
243
+ };
244
+ }>;
245
+
246
+ export declare const useSetPartyReady: (apiName?: string) => ActionState<{
247
+ partyId: string;
248
+ ready: boolean;
249
+ }, {
250
+ readonly id: string;
251
+ readonly leaderId: string;
252
+ readonly maxSize: number;
253
+ readonly approval: "open" | "leader";
254
+ readonly createdAt: number;
255
+ readonly members: readonly {
256
+ readonly subjectId: string;
257
+ readonly role: "member" | "leader";
258
+ readonly ready: boolean;
259
+ readonly joinedAt: number;
260
+ }[];
261
+ readonly searchTicketId: string | null;
262
+ }>;
263
+
264
+ export declare const useTransferPartyLeader: (apiName?: string) => ActionState<PartyTargetIntent, {
265
+ readonly id: string;
266
+ readonly leaderId: string;
267
+ readonly maxSize: number;
268
+ readonly approval: "open" | "leader";
269
+ readonly createdAt: number;
270
+ readonly members: readonly {
271
+ readonly subjectId: string;
272
+ readonly role: "member" | "leader";
273
+ readonly ready: boolean;
274
+ readonly joinedAt: number;
275
+ }[];
276
+ readonly searchTicketId: string | null;
277
+ }>;
278
+
279
+ export { }
package/dist/web.js ADDED
@@ -0,0 +1,7 @@
1
+ import { BASE_NAME as e } from "./rpc.js";
2
+ import { PartyPanel as t, partyLabels as n } from "./partyComponents.js";
3
+ import { pluginTag as r } from "@voltro/protocol";
4
+ import { useAction as i, useSubscription as a } from "@voltro/client";
5
+ // src/web.ts
6
+ var o = (t = "app") => i(t, r(e, "enqueue")), s = (t = "app") => i(t, r(e, "cancel")), c = (t, n = "app") => a(n, r(e, "status"), { ticketId: t ?? "" }, { skip: t === void 0 }), l = (t = "app") => a(t, r(e, "assignments"), {}), u = (t = "app") => a(t, r(e, "parties.mine"), {}), d = (t = "app") => a(t, r(e, "parties.invites"), {}), f = (t = "app") => i(t, r(e, "parties.create")), p = (t = "app") => i(t, r(e, "parties.invite")), m = (t = "app") => i(t, r(e, "parties.join")), h = (t = "app") => i(t, r(e, "parties.leave")), g = (t = "app") => i(t, r(e, "parties.kick")), _ = (t = "app") => i(t, r(e, "parties.setReady")), v = (t = "app") => i(t, r(e, "parties.transferLeader")), y = (t = "app") => i(t, r(e, "parties.search")), b = (t = "app") => i(t, r(e, "parties.cancelSearch"));
7
+ export { t as PartyPanel, n as partyLabels, s as useCancelMatchmaking, b as useCancelPartySearch, f as useCreateParty, o as useEnqueueMatchmaking, p as useInviteToParty, m as useJoinParty, g as useKickFromParty, h as useLeaveParty, l as useMatchmakingAssignments, c as useMatchmakingStatus, u as useParty, d as usePartyInvites, y as useSearchAsParty, _ as useSetPartyReady, v as useTransferPartyLeader };
package/package.json CHANGED
@@ -1,6 +1,106 @@
1
1
  {
2
2
  "name": "@voltro/plugin-matchmaking",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "0.88.0",
4
+ "description": "SQL-owned solo search admission and bounded whole-party matching foundations",
5
+ "keywords": [
6
+ "voltro",
7
+ "typescript",
8
+ "framework"
9
+ ],
10
+ "license": "SEE LICENSE IN LICENSE",
11
+ "homepage": "https://voltro.dev",
12
+ "bugs": {
13
+ "email": "support@voltro.dev"
14
+ },
15
+ "author": {
16
+ "name": "Voltro UG",
17
+ "url": "https://voltro.dev"
18
+ },
19
+ "type": "module",
20
+ "exports": {
21
+ ".": {
22
+ "types": "./dist/index.d.ts",
23
+ "import": "./dist/index.js",
24
+ "default": "./dist/index.js"
25
+ },
26
+ "./errors": {
27
+ "types": "./dist/errors.d.ts",
28
+ "import": "./dist/errors.js",
29
+ "default": "./dist/errors.js"
30
+ },
31
+ "./strategies": {
32
+ "types": "./dist/strategies.d.ts",
33
+ "import": "./dist/strategies.js",
34
+ "default": "./dist/strategies.js"
35
+ },
36
+ "./testing": {
37
+ "types": "./dist/testing.d.ts",
38
+ "import": "./dist/testing.js",
39
+ "default": "./dist/testing.js"
40
+ },
41
+ "./queue": {
42
+ "types": "./dist/queue.d.ts",
43
+ "import": "./dist/queue.js",
44
+ "default": "./dist/queue.js"
45
+ },
46
+ "./server": {
47
+ "types": "./dist/server.d.ts",
48
+ "import": "./dist/server.js",
49
+ "default": "./dist/server.js"
50
+ },
51
+ "./port": {
52
+ "types": "./dist/port.d.ts",
53
+ "import": "./dist/port.js",
54
+ "default": "./dist/port.js"
55
+ },
56
+ "./tickets": {
57
+ "types": "./dist/ticketContract.d.ts",
58
+ "import": "./dist/ticketContract.js",
59
+ "default": "./dist/ticketContract.js"
60
+ },
61
+ "./rpc": {
62
+ "types": "./dist/rpc.d.ts",
63
+ "import": "./dist/rpc.js",
64
+ "default": "./dist/rpc.js"
65
+ },
66
+ "./web": {
67
+ "types": "./dist/web.d.ts",
68
+ "import": "./dist/web.js",
69
+ "default": "./dist/web.js"
70
+ },
71
+ "./rooms": {
72
+ "types": "./dist/roomsAllocator.d.ts",
73
+ "import": "./dist/roomsAllocator.js",
74
+ "default": "./dist/roomsAllocator.js"
75
+ },
76
+ "./package.json": "./package.json"
77
+ },
78
+ "main": "./dist/index.js",
79
+ "module": "./dist/index.js",
80
+ "types": "./dist/index.d.ts",
81
+ "sideEffects": false,
82
+ "engines": {
83
+ "node": ">=24.0.0"
84
+ },
85
+ "dependencies": {
86
+ "@voltro/database": "0.88.0",
87
+ "@voltro/protocol": "0.88.0",
88
+ "@voltro/client": "0.88.0",
89
+ "@voltro/plugin-licensing": "0.88.0",
90
+ "@voltro/ui-shadcn": "0.88.0",
91
+ "@voltro/workflow": "0.88.0"
92
+ },
93
+ "peerDependencies": {
94
+ "effect": "4.1.0",
95
+ "react": "^19.0.0",
96
+ "@voltro/plugin-rooms": "0.88.0"
97
+ },
98
+ "peerDependenciesMeta": {
99
+ "@voltro/plugin-rooms": {
100
+ "optional": true
101
+ }
102
+ },
103
+ "publishConfig": {
104
+ "access": "public"
105
+ }
106
+ }