@chaos-overlords/kernel 0.9.1 → 0.9.3
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/dist/domain/entities.d.ts +13 -5
- package/dist/domain/entities.d.ts.map +1 -1
- package/dist/domain/entities.js +6 -0
- package/dist/domain/entities.js.map +1 -1
- package/dist/logic/turn-logic.d.ts +22 -3
- package/dist/logic/turn-logic.d.ts.map +1 -1
- package/dist/logic/turn-logic.js +32 -6
- package/dist/logic/turn-logic.js.map +1 -1
- package/dist/ports/runtime.d.ts +2 -0
- package/dist/ports/runtime.d.ts.map +1 -1
- package/dist/ports/storage.d.ts +46 -11
- package/dist/ports/storage.d.ts.map +1 -1
- package/dist/services/LobbyService.d.ts +29 -2
- package/dist/services/LobbyService.d.ts.map +1 -1
- package/dist/services/LobbyService.js +96 -24
- package/dist/services/LobbyService.js.map +1 -1
- package/dist/services/RateLimiter.d.ts +8 -0
- package/dist/services/RateLimiter.d.ts.map +1 -1
- package/dist/services/RateLimiter.js +32 -8
- package/dist/services/RateLimiter.js.map +1 -1
- package/dist/services/RetentionService.d.ts +50 -10
- package/dist/services/RetentionService.d.ts.map +1 -1
- package/dist/services/RetentionService.js +36 -11
- package/dist/services/RetentionService.js.map +1 -1
- package/dist/services/TurnService.d.ts +46 -1
- package/dist/services/TurnService.d.ts.map +1 -1
- package/dist/services/TurnService.js +149 -39
- package/dist/services/TurnService.js.map +1 -1
- package/dist/testing/InMemoryStorage.d.ts.map +1 -1
- package/dist/testing/InMemoryStorage.js +37 -1
- package/dist/testing/InMemoryStorage.js.map +1 -1
- package/package.json +2 -2
|
@@ -23,8 +23,11 @@ export interface Match {
|
|
|
23
23
|
/** Seats taken in the lobby; capacity is enforced on this counter atomically. */
|
|
24
24
|
seatCount: number;
|
|
25
25
|
/**
|
|
26
|
-
*
|
|
27
|
-
*
|
|
26
|
+
* The next position in the match's join sequence: advanced by every lobby seat claimed and every
|
|
27
|
+
* late-join position taken, including claims whose join then failed, so it is an upper bound on
|
|
28
|
+
* the players ever seated rather than a count of them. It never decreases, so the value handed to
|
|
29
|
+
* each player as `joinOrder` is a stable total order even after someone leaves and a newcomer
|
|
30
|
+
* takes the seat; gaps in that order carry no meaning.
|
|
28
31
|
*/
|
|
29
32
|
joinCounter: number;
|
|
30
33
|
createdAt: Date;
|
|
@@ -41,9 +44,10 @@ export interface Player {
|
|
|
41
44
|
/**
|
|
42
45
|
* The overlord face this player chose when they created or joined the match.
|
|
43
46
|
*
|
|
44
|
-
*
|
|
45
|
-
* is generated from is part of the state hash the turn verdict
|
|
46
|
-
* moved after the
|
|
47
|
+
* Changeable in the lobby, and never after the match starts: every client builds its city from
|
|
48
|
+
* the roster, and the setup a city is generated from is part of the state hash the turn verdict
|
|
49
|
+
* is taken over, so a face that moved after the start would read as a desync on any client that
|
|
50
|
+
* bootstrapped before it. The same holds for `displayName`.
|
|
47
51
|
*/
|
|
48
52
|
portraitId: number;
|
|
49
53
|
/**
|
|
@@ -54,6 +58,8 @@ export interface Player {
|
|
|
54
58
|
status: PlayerStatus;
|
|
55
59
|
joinedAt: Date;
|
|
56
60
|
}
|
|
61
|
+
/** What a lobby member may change about themselves before the match starts. */
|
|
62
|
+
export type PlayerProfile = Pick<Player, 'displayName' | 'portraitId'>;
|
|
57
63
|
/** One participant of a sealed turn: the slot its orders were hashed under. */
|
|
58
64
|
export interface SealedSlot {
|
|
59
65
|
playerId: string;
|
|
@@ -156,6 +162,8 @@ export interface TakeoverVote {
|
|
|
156
162
|
export type PersistedEvent = MatchEvent;
|
|
157
163
|
export declare const ACTIVE_PLAYER: PlayerStatus;
|
|
158
164
|
export declare function activePlayers(players: readonly Player[]): Player[];
|
|
165
|
+
/** A human seat nobody is playing: the ones an absence vote can hand to the computer. */
|
|
166
|
+
export declare const ABSENT_HUMAN_STATUSES: ReadonlyArray<PlayerStatus>;
|
|
159
167
|
/** A seat a human still holds: present, or absent and waited for while a takeover is voted on. */
|
|
160
168
|
export declare function isHumanParticipant(player: Pick<Player, 'status'>): boolean;
|
|
161
169
|
/** Human-controlled seats, including an absent player the lobby elected to keep waiting for. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"entities.d.ts","sourceRoot":"","sources":["../../src/domain/entities.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,YAAY,EACZ,UAAU,EACV,aAAa,EACb,WAAW,EACX,aAAa,EACb,YAAY,EACZ,UAAU,EACX,MAAM,4BAA4B,CAAA;AAEnC,MAAM,WAAW,KAAK;IACpB,EAAE,EAAE,MAAM,CAAA;IACV,oEAAoE;IACpE,eAAe,EAAE,MAAM,CAAA;IACvB;;;;;;;OAOG;IACH,cAAc,EAAE,MAAM,CAAA;IACtB,MAAM,EAAE,WAAW,CAAA;IACnB,QAAQ,EAAE,aAAa,CAAA;IACvB,YAAY,EAAE,MAAM,CAAA;IACpB,QAAQ,EAAE,MAAM,CAAA;IAChB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3B,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;IACnB,yDAAyD;IACzD,WAAW,EAAE,MAAM,CAAA;IACnB,iFAAiF;IACjF,SAAS,EAAE,MAAM,CAAA;IACjB
|
|
1
|
+
{"version":3,"file":"entities.d.ts","sourceRoot":"","sources":["../../src/domain/entities.ts"],"names":[],"mappings":"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"}
|
package/dist/domain/entities.js
CHANGED
|
@@ -2,6 +2,12 @@ export const ACTIVE_PLAYER = 'active';
|
|
|
2
2
|
export function activePlayers(players) {
|
|
3
3
|
return players.filter((player) => player.status === ACTIVE_PLAYER);
|
|
4
4
|
}
|
|
5
|
+
/** A human seat nobody is playing: the ones an absence vote can hand to the computer. */
|
|
6
|
+
export const ABSENT_HUMAN_STATUSES = [
|
|
7
|
+
'takeoverPending',
|
|
8
|
+
'left',
|
|
9
|
+
'kicked',
|
|
10
|
+
];
|
|
5
11
|
/** A seat a human still holds: present, or absent and waited for while a takeover is voted on. */
|
|
6
12
|
export function isHumanParticipant(player) {
|
|
7
13
|
return player.status === 'active' || player.status === 'takeoverPending';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"entities.js","sourceRoot":"","sources":["../../src/domain/entities.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"entities.js","sourceRoot":"","sources":["../../src/domain/entities.ts"],"names":[],"mappings":"AA6LA,MAAM,CAAC,MAAM,aAAa,GAAiB,QAAQ,CAAA;AAEnD,MAAM,UAAU,aAAa,CAAC,OAA0B;IACtD,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,KAAK,aAAa,CAAC,CAAA;AACpE,CAAC;AAED,yFAAyF;AACzF,MAAM,CAAC,MAAM,qBAAqB,GAAgC;IAChE,iBAAiB;IACjB,MAAM;IACN,QAAQ;CACT,CAAA;AAED,kGAAkG;AAClG,MAAM,UAAU,kBAAkB,CAAC,MAA8B;IAC/D,OAAO,MAAM,CAAC,MAAM,KAAK,QAAQ,IAAI,MAAM,CAAC,MAAM,KAAK,iBAAiB,CAAA;AAC1E,CAAC;AAED,gGAAgG;AAChG,MAAM,UAAU,iBAAiB,CAAC,OAA0B;IAC1D,OAAO,OAAO,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAA;AAC3C,CAAC;AAED,4FAA4F;AAC5F,MAAM,UAAU,YAAY,CAAC,KAA4B;IACvD,OAAO,KAAK,CAAC,MAAM,KAAK,SAAS,IAAI,KAAK,CAAC,MAAM,KAAK,UAAU,CAAA;AAClE,CAAC"}
|
|
@@ -1,6 +1,25 @@
|
|
|
1
|
-
import { type Player, type TurnOrders, type TurnReport } from '../domain/entities';
|
|
2
|
-
/**
|
|
3
|
-
|
|
1
|
+
import { type Player, type Turn, type TurnOrders, type TurnReport } from '../domain/entities';
|
|
2
|
+
/**
|
|
3
|
+
* The seats a turn waits on: every human participant, and a seat that left while the absence vote
|
|
4
|
+
* on it is still open.
|
|
5
|
+
*
|
|
6
|
+
* Leaving does not decide a seat; the vote does. A departed player's turn used to seal the moment
|
|
7
|
+
* everyone present was ready, before anybody had answered the prompt — or after they had voted to
|
|
8
|
+
* `wait` — so the player came back a turn later than the one they left on, having given no orders
|
|
9
|
+
* for it. Until the vote hands the seat to the computer, the turn is theirs too. A kicked seat is
|
|
10
|
+
* never waited on: its token is revoked, so its player cannot come back to finish the turn.
|
|
11
|
+
*/
|
|
12
|
+
export declare function awaitedSeats(players: readonly Player[], openPrompts: ReadonlySet<string>): Player[];
|
|
13
|
+
/** Every awaited seat that was asked for orders has marked ready. An empty roster is never "ready". */
|
|
14
|
+
export declare function allAwaitedReady(awaited: readonly Player[], orders: ReadonlyArray<Pick<TurnOrders, 'playerId' | 'ready'>>): boolean;
|
|
15
|
+
/**
|
|
16
|
+
* Whether the turn was sealed by its clock running out rather than by everyone being ready. Read
|
|
17
|
+
* from the stored row alone, so a sweep finishing an interrupted seal reaches the same answer as the
|
|
18
|
+
* call that sealed it: a deadline seal is refused until the deadline has passed, so its `sealedAt`
|
|
19
|
+
* is never earlier. A turn without a deadline (timer off, or paused by an absence vote) can only
|
|
20
|
+
* seal on readiness.
|
|
21
|
+
*/
|
|
22
|
+
export declare function sealedByDeadline(turn: Pick<Turn, 'deadlineAt' | 'sealedAt'>): boolean;
|
|
4
23
|
export type Consensus = {
|
|
5
24
|
kind: 'pending';
|
|
6
25
|
} | {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"turn-logic.d.ts","sourceRoot":"","sources":["../../src/logic/turn-logic.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"turn-logic.d.ts","sourceRoot":"","sources":["../../src/logic/turn-logic.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,MAAM,EACX,KAAK,IAAI,EACT,KAAK,UAAU,EACf,KAAK,UAAU,EAChB,MAAM,oBAAoB,CAAA;AAE3B;;;;;;;;;GASG;AACH,wBAAgB,YAAY,CAC1B,OAAO,EAAE,SAAS,MAAM,EAAE,EAC1B,WAAW,EAAE,WAAW,CAAC,MAAM,CAAC,GAC/B,MAAM,EAAE,CAKV;AAED,uGAAuG;AACvG,wBAAgB,eAAe,CAC7B,OAAO,EAAE,SAAS,MAAM,EAAE,EAC1B,MAAM,EAAE,aAAa,CAAC,IAAI,CAAC,UAAU,EAAE,UAAU,GAAG,OAAO,CAAC,CAAC,GAC5D,OAAO,CAMT;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,YAAY,GAAG,UAAU,CAAC,GAAG,OAAO,CAGrF;AAED,MAAM,MAAM,SAAS,GACjB;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,GACnB;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,OAAO,CAAA;CAAE,GAC3D;IACE,IAAI,EAAE,UAAU,CAAA;IAChB,OAAO,EAAE,KAAK,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IACvD,gFAAgF;IAChF,oBAAoB,EAAE,MAAM,EAAE,CAAA;CAC/B,CAAA;AAEL;;;;;;;;;;;;GAYG;AACH,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,SAAS,MAAM,EAAE,EAC1B,OAAO,EAAE,SAAS,UAAU,EAAE,GAC7B,MAAM,EAAE,CAaV;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,SAAS,MAAM,EAAE,EAC1B,OAAO,EAAE,SAAS,UAAU,EAAE,EAC9B,iBAAiB,EAAE,MAAM,GAAG,IAAI,GAC/B,SAAS,CAgCX;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CACzB,OAAO,EAAE,SAAS,MAAM,EAAE,EAC1B,YAAY,EAAE,MAAM,GACnB,KAAK,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,CAQ3C;AAED,wBAAgB,YAAY,CAAC,QAAQ,EAAE,IAAI,EAAE,gBAAgB,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAElF"}
|
package/dist/logic/turn-logic.js
CHANGED
|
@@ -1,11 +1,37 @@
|
|
|
1
|
-
import { activePlayers, humanParticipants, } from '../domain/entities';
|
|
2
|
-
/**
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
import { activePlayers, humanParticipants, isHumanParticipant, } from '../domain/entities';
|
|
2
|
+
/**
|
|
3
|
+
* The seats a turn waits on: every human participant, and a seat that left while the absence vote
|
|
4
|
+
* on it is still open.
|
|
5
|
+
*
|
|
6
|
+
* Leaving does not decide a seat; the vote does. A departed player's turn used to seal the moment
|
|
7
|
+
* everyone present was ready, before anybody had answered the prompt — or after they had voted to
|
|
8
|
+
* `wait` — so the player came back a turn later than the one they left on, having given no orders
|
|
9
|
+
* for it. Until the vote hands the seat to the computer, the turn is theirs too. A kicked seat is
|
|
10
|
+
* never waited on: its token is revoked, so its player cannot come back to finish the turn.
|
|
11
|
+
*/
|
|
12
|
+
export function awaitedSeats(players, openPrompts) {
|
|
13
|
+
return players.filter((player) => isHumanParticipant(player) || (player.status === 'left' && openPrompts.has(player.id)));
|
|
14
|
+
}
|
|
15
|
+
/** Every awaited seat that was asked for orders has marked ready. An empty roster is never "ready". */
|
|
16
|
+
export function allAwaitedReady(awaited, orders) {
|
|
17
|
+
const asked = new Set(orders.map((row) => row.playerId));
|
|
18
|
+
const seats = awaited.filter((player) => asked.has(player.id));
|
|
19
|
+
if (seats.length === 0)
|
|
6
20
|
return false;
|
|
7
21
|
const readyIds = new Set(orders.filter((row) => row.ready).map((row) => row.playerId));
|
|
8
|
-
return
|
|
22
|
+
return seats.every((player) => readyIds.has(player.id));
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Whether the turn was sealed by its clock running out rather than by everyone being ready. Read
|
|
26
|
+
* from the stored row alone, so a sweep finishing an interrupted seal reaches the same answer as the
|
|
27
|
+
* call that sealed it: a deadline seal is refused until the deadline has passed, so its `sealedAt`
|
|
28
|
+
* is never earlier. A turn without a deadline (timer off, or paused by an absence vote) can only
|
|
29
|
+
* seal on readiness.
|
|
30
|
+
*/
|
|
31
|
+
export function sealedByDeadline(turn) {
|
|
32
|
+
if (turn.deadlineAt === null || turn.sealedAt === null)
|
|
33
|
+
return false;
|
|
34
|
+
return turn.sealedAt.getTime() >= turn.deadlineAt.getTime();
|
|
9
35
|
}
|
|
10
36
|
/**
|
|
11
37
|
* The state hashes that the most active players reported, tied if more than one.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"turn-logic.js","sourceRoot":"","sources":["../../src/logic/turn-logic.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,EACb,iBAAiB,
|
|
1
|
+
{"version":3,"file":"turn-logic.js","sourceRoot":"","sources":["../../src/logic/turn-logic.ts"],"names":[],"mappings":"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"}
|
package/dist/ports/runtime.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../src/ports/runtime.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAA;AAExD,MAAM,WAAW,KAAK;IACpB,GAAG,IAAI,IAAI,CAAA;CACZ;AAED,MAAM,WAAW,MAAM;IACrB,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAA;IAC1D,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAA;IACzD,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAA;IACzD,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAA;CAC3D;AAED,eAAO,MAAM,UAAU,EAAE,MAKxB,CAAA;AAED,+EAA+E;AAC/E,MAAM,WAAW,aAAa;IAC5B,MAAM,CAAC,KAAK,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CAC7C;AAED;;;GAGG;AACH,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,KAAK,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,IAAI,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CAC/E;AAED;;;;;;GAMG;AACH,MAAM,WAAW,iBAAiB;IAChC,IAAI,CAAC,KAAK,EAAE;QACV,OAAO,EAAE,MAAM,CAAA;QACf,QAAQ,EAAE,MAAM,CAAA;QAChB,QAAQ,EAAE,MAAM,CAAA;QAChB,MAAM,EAAE,WAAW,CAAA;
|
|
1
|
+
{"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../src/ports/runtime.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAA;AAExD,MAAM,WAAW,KAAK;IACpB,GAAG,IAAI,IAAI,CAAA;CACZ;AAED,MAAM,WAAW,MAAM;IACrB,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAA;IAC1D,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAA;IACzD,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAA;IACzD,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAA;CAC3D;AAED,eAAO,MAAM,UAAU,EAAE,MAKxB,CAAA;AAED,+EAA+E;AAC/E,MAAM,WAAW,aAAa;IAC5B,MAAM,CAAC,KAAK,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CAC7C;AAED;;;GAGG;AACH,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,KAAK,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,IAAI,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CAC/E;AAED;;;;;;GAMG;AACH,MAAM,WAAW,iBAAiB;IAChC,IAAI,CAAC,KAAK,EAAE;QACV,OAAO,EAAE,MAAM,CAAA;QACf,QAAQ,EAAE,MAAM,CAAA;QAChB,QAAQ,EAAE,MAAM,CAAA;QAChB,MAAM,EAAE,WAAW,CAAA;QACnB,mFAAmF;QACnF,KAAK,CAAC,EAAE,OAAO,CAAA;KAChB,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAA;CACtB;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,YAAY;IAC3B,KAAK,CAAC,KAAK,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CACnE"}
|
package/dist/ports/storage.d.ts
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import type { MatchEventBody, MatchSettings, MatchStatus, TurnStatus } from '@chaos-overlords/contracts';
|
|
2
|
-
import type { Match, MatchSeat, OrderSummary, PersistedEvent, Player, PublicLobbyRow, SealedSlot, Snapshot, SnapshotSummary, TakeoverDecision, TakeoverVote, Turn, TurnOrders, TurnReport } from '../domain/entities';
|
|
2
|
+
import type { Match, MatchSeat, OrderSummary, PersistedEvent, Player, PlayerProfile, PublicLobbyRow, SealedSlot, Snapshot, SnapshotSummary, TakeoverDecision, TakeoverVote, Turn, TurnOrders, TurnReport } from '../domain/entities';
|
|
3
3
|
/**
|
|
4
4
|
* Persistence ports. There are NO transactions: D1 has none, so every invariant that two writers
|
|
5
5
|
* could race on is a single conditional statement whose row count says who won. Each `transition`
|
|
6
|
-
* is such a compare-and-swap; `claimSeat`/`releaseSeat`
|
|
7
|
-
*
|
|
6
|
+
* is such a compare-and-swap; `claimSeat`/`releaseSeat` and `claimLateJoinOrder` are atomic
|
|
7
|
+
* counters; `submitOrders` is
|
|
8
|
+
* conditional on the turn still being open and on a draft not replacing a ready document; `append`
|
|
9
|
+
* allocates its own sequence number.
|
|
8
10
|
*
|
|
9
11
|
* Writes that a unique constraint can refuse answer `false` instead of throwing, so the services
|
|
10
12
|
* can retry (a join code collision) without knowing anything about a driver's error shapes.
|
|
@@ -27,6 +29,15 @@ export interface MatchRepository {
|
|
|
27
29
|
* position in the match's monotonic join sequence, or null when no seat was available.
|
|
28
30
|
*/
|
|
29
31
|
claimSeat(matchId: string): Promise<number | null>;
|
|
32
|
+
/**
|
|
33
|
+
* Atomically take the next position in the match's join sequence for a late joiner, while the
|
|
34
|
+
* match is running; null when it is not running or no longer exists. It advances the same
|
|
35
|
+
* `joinCounter` `claimSeat` does, in one conditional UPDATE — a separate sequence, or a read
|
|
36
|
+
* followed by a write, would hand two joiners the same `joinOrder` — and it never returns a
|
|
37
|
+
* position a stored player of the match already holds. It does not test capacity: `createLate`
|
|
38
|
+
* does, and a position taken for a join that `createLate` then refuses stays unused.
|
|
39
|
+
*/
|
|
40
|
+
claimLateJoinOrder(matchId: string): Promise<number | null>;
|
|
30
41
|
releaseSeat(matchId: string): Promise<void>;
|
|
31
42
|
/** Host-only lobby configuration; false after the match starts or below the occupied seat count. */
|
|
32
43
|
updateSettings(matchId: string, settings: MatchSettings, updatedAt: Date): Promise<boolean>;
|
|
@@ -52,8 +63,8 @@ export interface MatchRepository {
|
|
|
52
63
|
* being `active` only through `leave`, `kick` or a missed deadline, and the game's default is an
|
|
53
64
|
* untimed match, so two friends whose clients both died mid-match leave two `active` rows that
|
|
54
65
|
* nothing ever clears: with the roster test alone their match is immortal. The longer window drops
|
|
55
|
-
* the test, because `updated_at` is refreshed by every turn open
|
|
56
|
-
* months of silence on
|
|
66
|
+
* the test, because `updated_at` is refreshed by every turn open, every status change and every
|
|
67
|
+
* join or rejoin, and months of silence on all of them is not something a live match does.
|
|
57
68
|
*/
|
|
58
69
|
deleteAbandonedLive(before: Date, limit: number, requireEmptyRoster: boolean): Promise<number>;
|
|
59
70
|
/**
|
|
@@ -66,7 +77,7 @@ export interface MatchRepository {
|
|
|
66
77
|
* on every report and every snapshot upload, so a match that nothing touched since the previous
|
|
67
78
|
* pass has no new evidence and its verdict cannot have changed; without the bound a public
|
|
68
79
|
* server's parked desyncs — the documented way a match ends when a host never uploads — were
|
|
69
|
-
* re-judged every fifteen seconds for the
|
|
80
|
+
* re-judged every fifteen seconds for the weeks retention keeps them. It also ends the
|
|
70
81
|
* starvation of a page ordered by an `updatedAt` that never moves: pass null to sweep everything,
|
|
71
82
|
* which is what a freshly started process does once to pick up whatever it missed.
|
|
72
83
|
*/
|
|
@@ -79,6 +90,8 @@ export interface MatchRepository {
|
|
|
79
90
|
hostPlayerId?: string;
|
|
80
91
|
updatedAt: Date;
|
|
81
92
|
}): Promise<boolean>;
|
|
93
|
+
/** Advance the current turn in one conditional write; a late sweep may never move it backwards. */
|
|
94
|
+
advanceCurrentTurn(matchId: string, number: number, updatedAt: Date): Promise<boolean>;
|
|
82
95
|
}
|
|
83
96
|
export interface PlayerRepository {
|
|
84
97
|
/**
|
|
@@ -109,6 +122,14 @@ export interface PlayerRepository {
|
|
|
109
122
|
setStatus(playerId: string, status: Player['status']): Promise<void>;
|
|
110
123
|
/** Compare-and-swap a player status; exactly one return/takeover race may win. */
|
|
111
124
|
transitionStatus(playerId: string, from: readonly Player['status'][], status: Player['status']): Promise<boolean>;
|
|
125
|
+
/**
|
|
126
|
+
* Replace an active lobby member's name and portrait, in ONE statement conditional on the match
|
|
127
|
+
* still being in the lobby. False when the match has started (or is gone) or the player is not
|
|
128
|
+
* active. Tested in the statement rather than by the caller because `start` reads the roster it
|
|
129
|
+
* seats after its own transition: an update that lands before that transition is in the roster
|
|
130
|
+
* every client generates its city from, and one that lands after it must not land at all.
|
|
131
|
+
*/
|
|
132
|
+
updateProfile(playerId: string, profile: PlayerProfile): Promise<boolean>;
|
|
112
133
|
/** Clears the token hash, so the player's bearer token stops authenticating immediately. */
|
|
113
134
|
revokeToken(playerId: string): Promise<void>;
|
|
114
135
|
/**
|
|
@@ -132,14 +153,25 @@ export interface PlayerRepository {
|
|
|
132
153
|
}
|
|
133
154
|
export interface TurnRepository {
|
|
134
155
|
/**
|
|
135
|
-
* Insert the turn and one empty orders row per player
|
|
136
|
-
*
|
|
156
|
+
* Insert the turn and one empty orders row per player that has none yet. Rows are only added while
|
|
157
|
+
* the stored turn is still `open`: a top-up that races a seal must not land in the sealed turn.
|
|
158
|
+
* False when the turn already exists, which is how the seal repair can re-run the open step
|
|
159
|
+
* without publishing a second `turn.opened`.
|
|
137
160
|
*/
|
|
138
161
|
open(turn: Turn, playerIds: readonly string[]): Promise<boolean>;
|
|
139
162
|
get(matchId: string, number: number): Promise<Turn | null>;
|
|
140
163
|
/**
|
|
141
164
|
* Overwrite a player's orders only while the turn is `open`, in ONE statement.
|
|
142
|
-
* Returns false when the turn is no longer open
|
|
165
|
+
* Returns false when the turn is no longer open, the player has no row, or the row is already
|
|
166
|
+
* ready and the submission is not.
|
|
167
|
+
*
|
|
168
|
+
* The last condition is what keeps a stale draft from reopening a finished turn. A client never
|
|
169
|
+
* takes readiness back: once it has sent its final document for a turn, any non-ready document
|
|
170
|
+
* for that turn is one it sent earlier, which arrived late — a draft whose request was superseded
|
|
171
|
+
* but had already left, or a timed-out attempt the server still ran. Applied, it put the seat
|
|
172
|
+
* back to drafting with an older document, and the turn then waited on a player whose screen
|
|
173
|
+
* said they were done until they submitted again. It has to be part of the same statement:
|
|
174
|
+
* checking the previous row first leaves the window in which the two requests run side by side.
|
|
143
175
|
*/
|
|
144
176
|
submitOrders(matchId: string, number: number, playerId: string, submission: {
|
|
145
177
|
orders: TurnOrders['orders'];
|
|
@@ -227,7 +259,7 @@ export interface TurnRepository {
|
|
|
227
259
|
* which is why a missing turn counts as stalled rather than being skipped.
|
|
228
260
|
*
|
|
229
261
|
* `touchedSince` bounds the join to matches something happened to recently. A seal in flight is
|
|
230
|
-
* seconds old, but abandoned matches are deliberately kept `running` for
|
|
262
|
+
* seconds old, but abandoned matches are deliberately kept `running` for weeks, so the
|
|
231
263
|
* unbounded join walked thousands of rows every fifteen seconds to find nothing. The caller runs
|
|
232
264
|
* the bounded scan every tick and the unbounded one (null) on a much longer period, which is what
|
|
233
265
|
* still finds a seal interrupted while the process was down.
|
|
@@ -285,7 +317,10 @@ export interface CastVoteInput {
|
|
|
285
317
|
* are one indexed read instead of a scan of every event the match ever logged.
|
|
286
318
|
*/
|
|
287
319
|
export interface TakeoverRepository {
|
|
288
|
-
/**
|
|
320
|
+
/**
|
|
321
|
+
* Opens a prompt only while the seat is a human absence (`ABSENT_HUMAN_STATUSES`) of that match;
|
|
322
|
+
* false when one is already open or the seat is active, computer controlled or not in the match.
|
|
323
|
+
*/
|
|
289
324
|
openPrompt(matchId: string, playerId: string, turn: number, openedAt: Date): Promise<boolean>;
|
|
290
325
|
/** Closes the prompt and discards its votes. A no-op when none is open. */
|
|
291
326
|
closePrompt(matchId: string, playerId: string): Promise<void>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../../src/ports/storage.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,cAAc,EACd,aAAa,EACb,WAAW,EACX,UAAU,EACX,MAAM,4BAA4B,CAAA;AACnC,OAAO,KAAK,EACV,KAAK,EACL,SAAS,EACT,YAAY,EACZ,cAAc,EACd,MAAM,EACN,cAAc,EACd,UAAU,EACV,QAAQ,EACR,eAAe,EACf,gBAAgB,EAChB,YAAY,EACZ,IAAI,EACJ,UAAU,EACV,UAAU,EACX,MAAM,oBAAoB,CAAA;AAE3B
|
|
1
|
+
{"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../../src/ports/storage.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type CreateMatchRequest, type JoinMatchRequest, type JoinRunningMatchRequest, type MatchSettings, type MembershipView, type TakeoverVoteRequest } from '@chaos-overlords/contracts';
|
|
1
|
+
import { type CreateMatchRequest, type JoinMatchRequest, type JoinRunningMatchRequest, type MatchSettings, type MembershipView, type TakeoverVoteRequest, type UpdatePlayerProfileRequest } from '@chaos-overlords/contracts';
|
|
2
2
|
import type { Principal } from './AuthService';
|
|
3
3
|
import type { KernelDeps } from './deps';
|
|
4
4
|
import type { EventPublisher } from './EventPublisher';
|
|
@@ -37,9 +37,22 @@ export declare class LobbyService {
|
|
|
37
37
|
createMatch(request: CreateMatchRequest): Promise<MembershipView>;
|
|
38
38
|
join(request: JoinMatchRequest, caller?: string): Promise<MembershipView>;
|
|
39
39
|
joinRunning(request: JoinRunningMatchRequest, caller?: string): Promise<MembershipView>;
|
|
40
|
+
/** Why the late-join claim found no running match: it stopped running, or it is gone. */
|
|
41
|
+
private lateJoinClaimRefused;
|
|
40
42
|
leave(principal: Principal): Promise<void>;
|
|
41
43
|
rejoin(principal: Principal): Promise<void>;
|
|
44
|
+
/** A seat claim can cross a seal, so use the turn current after the seat was committed. */
|
|
45
|
+
private topUpCurrentTurn;
|
|
42
46
|
updateSettings(principal: Principal, settings: MatchSettings): Promise<void>;
|
|
47
|
+
/**
|
|
48
|
+
* Change the caller's own name and portrait while the match is still in the lobby.
|
|
49
|
+
*
|
|
50
|
+
* Any seated member may, not only the host: it is their own seat. The name is held to the same
|
|
51
|
+
* uniqueness a join is, against everybody but the caller, so renaming to a different case of
|
|
52
|
+
* one's own name is allowed. Refused once the match has started, because the roster is then what
|
|
53
|
+
* every client has generated its city from.
|
|
54
|
+
*/
|
|
55
|
+
updateProfile(principal: Principal, request: UpdatePlayerProfileRequest): Promise<void>;
|
|
43
56
|
kick(principal: Principal, targetPlayerId: string): Promise<void>;
|
|
44
57
|
/** The player a host or a voter named, refused unless it is a member of the caller's match. */
|
|
45
58
|
private requireTarget;
|
|
@@ -61,12 +74,26 @@ export declare class LobbyService {
|
|
|
61
74
|
private retallyOpenPrompts;
|
|
62
75
|
start(principal: Principal): Promise<void>;
|
|
63
76
|
private remove;
|
|
77
|
+
/**
|
|
78
|
+
* Restart a running or desynced match's retention age: somebody has just come (back) to it.
|
|
79
|
+
*
|
|
80
|
+
* The abandoned and silent windows both run from `updatedAt`, and neither a join nor a rejoin
|
|
81
|
+
* otherwise moves it — a player returning to an untimed match whose partner is still away opens
|
|
82
|
+
* no turn and changes no status — so a match somebody was demonstrably playing could be collected
|
|
83
|
+
* on the age it had before they came back. A no-op on any other status.
|
|
84
|
+
*/
|
|
85
|
+
private refreshRetention;
|
|
64
86
|
/**
|
|
65
87
|
* Move the host role of a started match and announce it. `at` is the caller's to supply: `remove`
|
|
66
88
|
* stamps the handoff with the time it read on entry, and the other callers read the clock as
|
|
67
89
|
* they call.
|
|
68
90
|
*/
|
|
69
91
|
private handHostTo;
|
|
92
|
+
/**
|
|
93
|
+
* Hand the host role of a started match to its first active player, if it has one. Answers
|
|
94
|
+
* whether anybody was there to take it.
|
|
95
|
+
*/
|
|
96
|
+
private handHostToFirstActive;
|
|
70
97
|
/**
|
|
71
98
|
* Hang up a revoked membership's streams. Best effort by design: the token is already gone, so a
|
|
72
99
|
* fan-out that cannot be reached costs one stale stream until it drops, never the revoke itself.
|
|
@@ -89,7 +116,7 @@ export declare class LobbyService {
|
|
|
89
116
|
private assertNameIsFree;
|
|
90
117
|
/**
|
|
91
118
|
* Undo a join that could not be completed. The token was never returned, so the row is
|
|
92
|
-
* unreachable: leaving it would hold a seat and keep `
|
|
119
|
+
* unreachable: leaving it would hold a seat and keep `allAwaitedReady` waiting forever on a player
|
|
93
120
|
* who does not exist. Deleting the row is safe precisely because nobody ever held its token.
|
|
94
121
|
*/
|
|
95
122
|
private rollbackJoin;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LobbyService.d.ts","sourceRoot":"","sources":["../../src/services/LobbyService.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,kBAAkB,EAGvB,KAAK,gBAAgB,EACrB,KAAK,uBAAuB,EAE5B,KAAK,aAAa,EAClB,KAAK,cAAc,EACnB,KAAK,mBAAmB,
|
|
1
|
+
{"version":3,"file":"LobbyService.d.ts","sourceRoot":"","sources":["../../src/services/LobbyService.ts"],"names":[],"mappings":"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"}
|