@chaos-overlords/server 0.9.0 → 0.9.2

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 (49) hide show
  1. package/dist/app.d.ts.map +1 -1
  2. package/dist/app.js +3 -1
  3. package/dist/app.js.map +1 -1
  4. package/dist/configEnv.d.ts +22 -0
  5. package/dist/configEnv.d.ts.map +1 -0
  6. package/dist/configEnv.js +46 -0
  7. package/dist/configEnv.js.map +1 -0
  8. package/dist/container.d.ts +17 -0
  9. package/dist/container.d.ts.map +1 -1
  10. package/dist/container.js +6 -0
  11. package/dist/container.js.map +1 -1
  12. package/dist/http/errorHandler.js +5 -0
  13. package/dist/http/errorHandler.js.map +1 -1
  14. package/dist/http/middleware.d.ts +11 -0
  15. package/dist/http/middleware.d.ts.map +1 -1
  16. package/dist/http/middleware.js +81 -18
  17. package/dist/http/middleware.js.map +1 -1
  18. package/dist/http/types.d.ts +9 -4
  19. package/dist/http/types.d.ts.map +1 -1
  20. package/dist/index.d.ts +4 -2
  21. package/dist/index.d.ts.map +1 -1
  22. package/dist/index.js +4 -2
  23. package/dist/index.js.map +1 -1
  24. package/dist/routes/bugReports.d.ts.map +1 -1
  25. package/dist/routes/bugReports.js +17 -11
  26. package/dist/routes/bugReports.js.map +1 -1
  27. package/dist/routes/events.d.ts.map +1 -1
  28. package/dist/routes/events.js +17 -0
  29. package/dist/routes/events.js.map +1 -1
  30. package/dist/routes/lobby.d.ts.map +1 -1
  31. package/dist/routes/lobby.js +3 -0
  32. package/dist/routes/lobby.js.map +1 -1
  33. package/dist/sse/LocalEventHub.d.ts +28 -9
  34. package/dist/sse/LocalEventHub.d.ts.map +1 -1
  35. package/dist/sse/LocalEventHub.js +68 -17
  36. package/dist/sse/LocalEventHub.js.map +1 -1
  37. package/dist/sse/MatchLog.d.ts +6 -0
  38. package/dist/sse/MatchLog.d.ts.map +1 -1
  39. package/dist/sse/MatchLog.js +10 -0
  40. package/dist/sse/MatchLog.js.map +1 -1
  41. package/dist/sse/createSseResponse.d.ts +12 -0
  42. package/dist/sse/createSseResponse.d.ts.map +1 -1
  43. package/dist/sse/createSseResponse.js +49 -8
  44. package/dist/sse/createSseResponse.js.map +1 -1
  45. package/dist/sse/membership.d.ts +11 -0
  46. package/dist/sse/membership.d.ts.map +1 -0
  47. package/dist/sse/membership.js +13 -0
  48. package/dist/sse/membership.js.map +1 -0
  49. package/package.json +5 -5
@@ -1 +1 @@
1
- {"version":3,"file":"lobby.js","sourceRoot":"","sources":["../../src/routes/lobby.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"lobby.js","sourceRoot":"","sources":["../../src/routes/lobby.ts"],"names":[],"mappings":"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"}
@@ -13,6 +13,8 @@ import { type EventNotifier, type EventRepository, type EventStreamOpener, type
13
13
  * predecessor is still being torn down. Reaching it closes that player's oldest stream rather than
14
14
  * refusing the new one, because the new one is the live client and the old one is the corpse.
15
15
  * `perMatch` and `perProcess` are the ceilings a client cannot talk its way past, and they refuse.
16
+ * Lobby streams may use at most one quarter of the process ceiling, so cheaply minted host tokens
17
+ * cannot fill every stream slot needed by running matches.
16
18
  */
17
19
  export interface EventHubLimits {
18
20
  perPlayer: number;
@@ -20,6 +22,20 @@ export interface EventHubLimits {
20
22
  perProcess: number;
21
23
  }
22
24
  export declare const DEFAULT_EVENT_HUB_LIMITS: EventHubLimits;
25
+ /** Runtime hooks for stream diagnostics and membership checks. */
26
+ export interface EventHubObserver {
27
+ /** A false result or failed lookup ends the stream. */
28
+ revalidate?(matchId: string, playerId: string): Promise<boolean>;
29
+ /** A stored event a stream had to skip because this build cannot read it. */
30
+ unreadable?(matchId: string, seq: number): void;
31
+ /**
32
+ * A stream request whose signal had already aborted by the time it reached the hub, answered
33
+ * with an empty stream. Routine for a client that gave up during authentication; a steady run of
34
+ * them for one player means the runtime is handing over signals that only look aborted, and
35
+ * that client is reconnecting in a loop.
36
+ */
37
+ abandoned?(matchId: string, playerId: string): void;
38
+ }
23
39
  /**
24
40
  * In-process fan-out: notifies every open stream of a match within this process. It is both the
25
41
  * notifier and the stream opener on Node, and the fan-out inside a Cloudflare Durable Object.
@@ -28,8 +44,7 @@ export declare class LocalEventHub implements EventNotifier, EventStreamOpener,
28
44
  private readonly events;
29
45
  private readonly heartbeatMs;
30
46
  private readonly limits;
31
- /** Told about a stored event a stream had to skip, so an operator can find out it exists. */
32
- private readonly onUnreadable?;
47
+ private readonly observer;
33
48
  /** Insertion-ordered, which is what makes "close this player's oldest" a first match. */
34
49
  private readonly listeners;
35
50
  /**
@@ -40,18 +55,19 @@ export declare class LocalEventHub implements EventNotifier, EventStreamOpener,
40
55
  */
41
56
  private readonly logs;
42
57
  private open_;
43
- constructor(events: EventRepository, heartbeatMs: number, limits?: EventHubLimits,
44
- /** Told about a stored event a stream had to skip, so an operator can find out it exists. */
45
- onUnreadable?: ((matchId: string, seq: number) => void) | undefined);
58
+ private lobbyOpen_;
59
+ /** The share of `perProcess` lobby streams may hold; see `makeRoom`. */
60
+ private readonly lobbyCap;
61
+ constructor(events: EventRepository, heartbeatMs: number, limits?: EventHubLimits, observer?: EventHubObserver);
46
62
  notify(event: PersistedEvent): Promise<void>;
47
63
  /** Wake every stream of a match; used when the notification arrives without the event body. */
48
64
  wake(matchId: string): void;
49
65
  /**
50
66
  * End every stream a membership holds.
51
67
  *
52
- * Revoking a token stops the next request; a stream that is already open is never authenticated
53
- * again, so without this a kicked player keeps being handed every sealed set, every desync report
54
- * (which names each player's state hash) and every host change until they choose to disconnect.
68
+ * Revoking a token stops the next request, and an open stream only re-checks its membership on
69
+ * the catch-up heartbeat; until then a kicked player keeps being handed every sealed set, every
70
+ * desync report (which names each player's state hash) and every host change.
55
71
  */
56
72
  close(input: {
57
73
  matchId: string;
@@ -74,11 +90,14 @@ export declare class LocalEventHub implements EventNotifier, EventStreamOpener,
74
90
  playerId: string;
75
91
  afterSeq: number;
76
92
  signal: AbortSignal;
93
+ lobby?: boolean;
77
94
  }): Promise<Response>;
78
95
  private logOf;
79
96
  private subscribe;
97
+ /** Stop charging a stream to the lobby share once its match is running. */
98
+ private releaseLobby;
80
99
  /**
81
- * Enforce the three caps before a stream is built.
100
+ * Enforce the stream caps before a stream is built.
82
101
  *
83
102
  * The caller's own stale streams are closed FIRST, before either ceiling is read. Closing them is
84
103
  * not a concession to the caller, it is bookkeeping: a reconnect whose predecessor has not
@@ -1 +1 @@
1
- {"version":3,"file":"LocalEventHub.d.ts","sourceRoot":"","sources":["../../src/sse/LocalEventHub.ts"],"names":[],"mappings":"AACA,OAAO,EACL,KAAK,aAAa,EAClB,KAAK,eAAe,EACpB,KAAK,iBAAiB,EACtB,KAAK,cAAc,EAEnB,KAAK,YAAY,EAClB,MAAM,yBAAyB,CAAA;AAIhC;;;;;;;;;;;;;;GAcG;AACH,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,MAAM,CAAA;IACjB,QAAQ,EAAE,MAAM,CAAA;IAChB,UAAU,EAAE,MAAM,CAAA;CACnB;AAED,eAAO,MAAM,wBAAwB,EAAE,cAItC,CAAA;AAQD;;;GAGG;AACH,qBAAa,aAAc,YAAW,aAAa,EAAE,iBAAiB,EAAE,YAAY;IAahF,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,WAAW;IAC5B,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,6FAA6F;IAC7F,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC;IAhBhC,yFAAyF;IACzF,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAuC;IACjE;;;;;OAKG;IACH,OAAO,CAAC,QAAQ,CAAC,IAAI,CAA8B;IACnD,OAAO,CAAC,KAAK,CAAI;IAEjB,YACmB,MAAM,EAAE,eAAe,EACvB,WAAW,EAAE,MAAM,EACnB,MAAM,GAAE,cAAyC;IAClE,6FAA6F;IAC5E,YAAY,CAAC,GAAE,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,KAAK,IAAI,aAAA,EACpE;IAEE,MAAM,CAAC,KAAK,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAMjD;IAED,+FAA+F;IAC/F,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAI1B;IAED;;;;;;OAMG;IACG,KAAK,CAAC,KAAK,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAMvE;IAED;;;;;;;OAOG;IACH,QAAQ,IAAI,IAAI,CAOf;IAED,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEvC;IAED,uDAAuD;IACvD,IAAI,WAAW,IAAI,MAAM,CAExB;IAEK,IAAI,CAAC,KAAK,EAAE;QAChB,OAAO,EAAE,MAAM,CAAA;QACf,QAAQ,EAAE,MAAM,CAAA;QAChB,QAAQ,EAAE,MAAM,CAAA;QAChB,MAAM,EAAE,WAAW,CAAA;KACpB,GAAG,OAAO,CAAC,QAAQ,CAAC,CAgBpB;IAED,OAAO,CAAC,KAAK;IAQb,OAAO,CAAC,SAAS;IAuBjB;;;;;;;;;;;;OAYG;IACH,OAAO,CAAC,QAAQ;CAmBjB"}
1
+ {"version":3,"file":"LocalEventHub.d.ts","sourceRoot":"","sources":["../../src/sse/LocalEventHub.ts"],"names":[],"mappings":"AACA,OAAO,EACL,KAAK,aAAa,EAClB,KAAK,eAAe,EACpB,KAAK,iBAAiB,EACtB,KAAK,cAAc,EAEnB,KAAK,YAAY,EAClB,MAAM,yBAAyB,CAAA;AAIhC;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,MAAM,CAAA;IACjB,QAAQ,EAAE,MAAM,CAAA;IAChB,UAAU,EAAE,MAAM,CAAA;CACnB;AAED,eAAO,MAAM,wBAAwB,EAAE,cAItC,CAAA;AAED,kEAAkE;AAClE,MAAM,WAAW,gBAAgB;IAC/B,uDAAuD;IACvD,UAAU,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;IAChE,6EAA6E;IAC7E,UAAU,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,CAAA;IAC/C;;;;;OAKG;IACH,SAAS,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;CACpD;AASD;;;GAGG;AACH,qBAAa,aAAc,YAAW,aAAa,EAAE,iBAAiB,EAAE,YAAY;IAgBhF,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,WAAW;IAC5B,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAlB3B,yFAAyF;IACzF,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAuC;IACjE;;;;;OAKG;IACH,OAAO,CAAC,QAAQ,CAAC,IAAI,CAA8B;IACnD,OAAO,CAAC,KAAK,CAAI;IACjB,OAAO,CAAC,UAAU,CAAI;IACtB,wEAAwE;IACxE,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAQ;IAEjC,YACmB,MAAM,EAAE,eAAe,EACvB,WAAW,EAAE,MAAM,EACnB,MAAM,GAAE,cAAyC,EACjD,QAAQ,GAAE,gBAAqB,EAGjD;IAEK,MAAM,CAAC,KAAK,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAajD;IAED,+FAA+F;IAC/F,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAI1B;IAED;;;;;;OAMG;IACG,KAAK,CAAC,KAAK,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAMvE;IAED;;;;;;;OAOG;IACH,QAAQ,IAAI,IAAI,CAOf;IAED,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEvC;IAED,uDAAuD;IACvD,IAAI,WAAW,IAAI,MAAM,CAExB;IAEK,IAAI,CAAC,KAAK,EAAE;QAChB,OAAO,EAAE,MAAM,CAAA;QACf,QAAQ,EAAE,MAAM,CAAA;QAChB,QAAQ,EAAE,MAAM,CAAA;QAChB,MAAM,EAAE,WAAW,CAAA;QACnB,KAAK,CAAC,EAAE,OAAO,CAAA;KAChB,GAAG,OAAO,CAAC,QAAQ,CAAC,CAqCpB;IAED,OAAO,CAAC,KAAK;IAQb,OAAO,CAAC,SAAS;IAoBjB,2EAA2E;IAC3E,OAAO,CAAC,YAAY;IAMpB;;;;;;;;;;;;OAYG;IACH,OAAO,CAAC,QAAQ;CA6BjB"}
@@ -1,6 +1,6 @@
1
1
  import { LIMITS } from '@chaos-overlords/contracts';
2
2
  import { RateLimitedError, } from '@chaos-overlords/kernel';
3
- import { createSseResponse } from './createSseResponse';
3
+ import { abandonedSseResponse, createSseResponse } from './createSseResponse';
4
4
  import { MatchLog } from './MatchLog';
5
5
  export const DEFAULT_EVENT_HUB_LIMITS = {
6
6
  perPlayer: 3,
@@ -15,7 +15,7 @@ export class LocalEventHub {
15
15
  events;
16
16
  heartbeatMs;
17
17
  limits;
18
- onUnreadable;
18
+ observer;
19
19
  /** Insertion-ordered, which is what makes "close this player's oldest" a first match. */
20
20
  listeners = new Map();
21
21
  /**
@@ -26,15 +26,24 @@ export class LocalEventHub {
26
26
  */
27
27
  logs = new Map();
28
28
  open_ = 0;
29
- constructor(events, heartbeatMs, limits = DEFAULT_EVENT_HUB_LIMITS,
30
- /** Told about a stored event a stream had to skip, so an operator can find out it exists. */
31
- onUnreadable) {
29
+ lobbyOpen_ = 0;
30
+ /** The share of `perProcess` lobby streams may hold; see `makeRoom`. */
31
+ lobbyCap;
32
+ constructor(events, heartbeatMs, limits = DEFAULT_EVENT_HUB_LIMITS, observer = {}) {
32
33
  this.events = events;
33
34
  this.heartbeatMs = heartbeatMs;
34
35
  this.limits = limits;
35
- this.onUnreadable = onUnreadable;
36
+ this.observer = observer;
37
+ this.lobbyCap = Math.max(1, Math.floor(limits.perProcess / 4));
36
38
  }
37
39
  async notify(event) {
40
+ // A stream opened in the lobby stays connected when play starts. Release its lobby quota now
41
+ // rather than waiting for a reconnect that may never happen.
42
+ if (event.type === 'match.started') {
43
+ for (const subscription of this.listeners.get(event.matchId) ?? []) {
44
+ this.releaseLobby(subscription);
45
+ }
46
+ }
38
47
  // The notification carries the durable row, so its frame is formatted once here and every
39
48
  // stream one event behind — which is every healthy stream of the match — is served from it
40
49
  // without reading anything. See `MatchLog`.
@@ -51,9 +60,9 @@ export class LocalEventHub {
51
60
  /**
52
61
  * End every stream a membership holds.
53
62
  *
54
- * Revoking a token stops the next request; a stream that is already open is never authenticated
55
- * again, so without this a kicked player keeps being handed every sealed set, every desync report
56
- * (which names each player's state hash) and every host change until they choose to disconnect.
63
+ * Revoking a token stops the next request, and an open stream only re-checks its membership on
64
+ * the catch-up heartbeat; until then a kicked player keeps being handed every sealed set, every
65
+ * desync report (which names each player's state hash) and every host change.
57
66
  */
58
67
  async close(input) {
59
68
  // Snapshot deliberately: `close()` removes the subscription from the set being walked.
@@ -88,17 +97,39 @@ export class LocalEventHub {
88
97
  return this.open_;
89
98
  }
90
99
  async open(input) {
91
- this.makeRoom(input.matchId, input.playerId);
100
+ // Before the caps, not only inside the response: making room closes the caller's oldest
101
+ // stream, and a request nobody is waiting on must not cost that player a live one (or be
102
+ // refused with a 429 nobody reads).
103
+ if (input.signal.aborted) {
104
+ this.observer.abandoned?.(input.matchId, input.playerId);
105
+ return abandonedSseResponse();
106
+ }
107
+ const lobby = input.lobby === true;
108
+ this.makeRoom(input.matchId, input.playerId, lobby);
92
109
  const log = this.logOf(input.matchId);
110
+ let subscription;
111
+ const revalidate = this.observer.revalidate;
93
112
  return createSseResponse({
94
- page: (afterSeq, force) => log.page(afterSeq, force),
113
+ page: async (afterSeq, force) => {
114
+ const frames = await log.page(afterSeq, force);
115
+ // `lobby` was read when the request authenticated. A match that started in between
116
+ // announced it before this stream subscribed, so the release in `notify` missed it; the
117
+ // stream's own read of the log is where it learns the match is running.
118
+ if (subscription?.lobby && log.started)
119
+ this.releaseLobby(subscription);
120
+ return frames;
121
+ },
95
122
  caughtUp: (lastSeq) => log.caughtUp(lastSeq),
96
- subscribe: (wake, close) => this.subscribe(input.matchId, input.playerId, wake, close),
123
+ subscribe: (wake, close) => {
124
+ subscription = { playerId: input.playerId, lobby: lobby && !log.started, wake, close };
125
+ return this.subscribe(input.matchId, subscription);
126
+ },
97
127
  }, {
98
128
  afterSeq: input.afterSeq,
99
129
  heartbeatMs: this.heartbeatMs,
100
130
  signal: input.signal,
101
- onUnreadable: (seq) => this.onUnreadable?.(input.matchId, seq),
131
+ onUnreadable: (seq) => this.observer.unreadable?.(input.matchId, seq),
132
+ ...(revalidate ? { revalidate: () => revalidate(input.matchId, input.playerId) } : {}),
102
133
  });
103
134
  }
104
135
  logOf(matchId) {
@@ -109,16 +140,19 @@ export class LocalEventHub {
109
140
  this.logs.set(matchId, log);
110
141
  return log;
111
142
  }
112
- subscribe(matchId, playerId, wake, close) {
143
+ subscribe(matchId, subscription) {
113
144
  const set = this.listeners.get(matchId) ?? new Set();
114
- const subscription = { playerId, wake, close };
115
145
  set.add(subscription);
116
146
  this.listeners.set(matchId, set);
117
147
  this.open_ += 1;
148
+ if (subscription.lobby)
149
+ this.lobbyOpen_ += 1;
118
150
  return () => {
119
151
  if (!set.delete(subscription))
120
152
  return;
121
153
  this.open_ -= 1;
154
+ // Clears the flag as well, so a page still in flight at close cannot release it twice.
155
+ this.releaseLobby(subscription);
122
156
  if (set.size === 0) {
123
157
  this.listeners.delete(matchId);
124
158
  // Nothing reads this match any more, so its frames are only memory. The next stream of it
@@ -127,8 +161,15 @@ export class LocalEventHub {
127
161
  }
128
162
  };
129
163
  }
164
+ /** Stop charging a stream to the lobby share once its match is running. */
165
+ releaseLobby(subscription) {
166
+ if (!subscription.lobby)
167
+ return;
168
+ subscription.lobby = false;
169
+ this.lobbyOpen_ -= 1;
170
+ }
130
171
  /**
131
- * Enforce the three caps before a stream is built.
172
+ * Enforce the stream caps before a stream is built.
132
173
  *
133
174
  * The caller's own stale streams are closed FIRST, before either ceiling is read. Closing them is
134
175
  * not a concession to the caller, it is bookkeeping: a reconnect whose predecessor has not
@@ -140,7 +181,7 @@ export class LocalEventHub {
140
181
  * `perMatch` and `perProcess` then refuse whatever is still over, which is the case no client can
141
182
  * talk its way past.
142
183
  */
143
- makeRoom(matchId, playerId) {
184
+ makeRoom(matchId, playerId, lobby) {
144
185
  const set = this.listeners.get(matchId);
145
186
  if (set) {
146
187
  const mine = [...set].filter((subscription) => subscription.playerId === playerId);
@@ -153,6 +194,16 @@ export class LocalEventHub {
153
194
  scope: 'process',
154
195
  });
155
196
  }
197
+ // Creating a lobby is unauthenticated. A caller can mint hundreds of host tokens and hold
198
+ // three streams per token, so lobby streams cannot be allowed to occupy the whole process cap.
199
+ // Running matches retain the other three quarters even when a single source spreads creation
200
+ // across many IPv6 /64s and exhausts the lobby pool.
201
+ if (lobby && this.lobbyOpen_ >= this.lobbyCap) {
202
+ throw new RateLimitedError('This server is holding as many lobby streams as it can', {
203
+ reason: 'too_many_streams',
204
+ scope: 'lobby',
205
+ });
206
+ }
156
207
  if ((this.listeners.get(matchId)?.size ?? 0) >= this.limits.perMatch) {
157
208
  throw new RateLimitedError('This match is holding as many event streams as it can', {
158
209
  reason: 'too_many_streams',
@@ -1 +1 @@
1
- {"version":3,"file":"LocalEventHub.js","sourceRoot":"","sources":["../../src/sse/LocalEventHub.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"LocalEventHub.js","sourceRoot":"","sources":["../../src/sse/LocalEventHub.ts"],"names":[],"mappings":"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"}
@@ -44,6 +44,12 @@ export declare class MatchLog {
44
44
  * every one of its reads goes to the log exactly as before.
45
45
  */
46
46
  private notified;
47
+ /**
48
+ * Whether this process has seen the match's `match.started`, by notification or by reading it.
49
+ * A stream authenticated while the match was still a lobby can subscribe after that notification
50
+ * went out; this is how the hub learns the stream is no longer a lobby stream.
51
+ */
52
+ started: boolean;
47
53
  constructor(matchId: string, events: EventRepository);
48
54
  /**
49
55
  * Remember a published event and its frame.
@@ -1 +1 @@
1
- {"version":3,"file":"MatchLog.d.ts","sourceRoot":"","sources":["../../src/sse/MatchLog.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAA;AAG9E,8EAA8E;AAC9E,MAAM,WAAW,UAAU;IACzB,GAAG,EAAE,MAAM,CAAA;IACX,+EAA+E;IAC/E,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;CACpB;AAcD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,qBAAa,QAAQ;IAgBjB,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,MAAM;IAhBzB,mFAAmF;IACnF,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAgC;IACvD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA2C;IACpE;;;;;;;;OAQG;IACH,OAAO,CAAC,QAAQ,CAAI;IAEpB,YACmB,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,eAAe,EACtC;IAEJ;;;;;OAKG;IACH,MAAM,CAAC,KAAK,EAAE,cAAc,GAAG,IAAI,CAKlC;IAED;;;;;OAKG;IACH,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAEjC;IAED;;;;;;;;;;;;;;;;;OAiBG;IACG,IAAI,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,UAAQ,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC,CAejE;IAED,OAAO,CAAC,cAAc;YAUR,IAAI;IAalB,OAAO,CAAC,IAAI;CAOb"}
1
+ {"version":3,"file":"MatchLog.d.ts","sourceRoot":"","sources":["../../src/sse/MatchLog.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAA;AAG9E,8EAA8E;AAC9E,MAAM,WAAW,UAAU;IACzB,GAAG,EAAE,MAAM,CAAA;IACX,+EAA+E;IAC/E,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;CACpB;AAcD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,qBAAa,QAAQ;IAsBjB,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,MAAM;IAtBzB,mFAAmF;IACnF,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAgC;IACvD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA2C;IACpE;;;;;;;;OAQG;IACH,OAAO,CAAC,QAAQ,CAAI;IACpB;;;;OAIG;IACH,OAAO,UAAQ;IAEf,YACmB,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,eAAe,EACtC;IAEJ;;;;;OAKG;IACH,MAAM,CAAC,KAAK,EAAE,cAAc,GAAG,IAAI,CAMlC;IAED;;;;;OAKG;IACH,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAEjC;IAED;;;;;;;;;;;;;;;;;OAiBG;IACG,IAAI,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,UAAQ,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC,CAejE;IAED,OAAO,CAAC,cAAc;YAUR,IAAI;IAclB,OAAO,CAAC,IAAI;CAOb"}
@@ -48,6 +48,12 @@ export class MatchLog {
48
48
  * every one of its reads goes to the log exactly as before.
49
49
  */
50
50
  notified = 0;
51
+ /**
52
+ * Whether this process has seen the match's `match.started`, by notification or by reading it.
53
+ * A stream authenticated while the match was still a lobby can subscribe after that notification
54
+ * went out; this is how the hub learns the stream is no longer a lobby stream.
55
+ */
56
+ started = false;
51
57
  constructor(matchId, events) {
52
58
  this.matchId = matchId;
53
59
  this.events = events;
@@ -61,6 +67,8 @@ export class MatchLog {
61
67
  record(event) {
62
68
  if (event.seq > this.notified)
63
69
  this.notified = event.seq;
70
+ if (event.type === 'match.started')
71
+ this.started = true;
64
72
  if (this.frames.has(event.seq))
65
73
  return;
66
74
  this.frames.set(event.seq, { seq: event.seq, text: tryFormatEvent(event) });
@@ -125,6 +133,8 @@ export class MatchLog {
125
133
  async read(afterSeq) {
126
134
  const rows = await this.events.listAfter(this.matchId, afterSeq, PAGE_SIZE);
127
135
  const page = rows.map((row) => {
136
+ if (row.type === 'match.started')
137
+ this.started = true;
128
138
  const known = this.frames.get(row.seq);
129
139
  if (known)
130
140
  return known;
@@ -1 +1 @@
1
- {"version":3,"file":"MatchLog.js","sourceRoot":"","sources":["../../src/sse/MatchLog.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"MatchLog.js","sourceRoot":"","sources":["../../src/sse/MatchLog.ts"],"names":[],"mappings":"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"}
@@ -30,6 +30,8 @@ export interface SseOptions {
30
30
  signal: AbortSignal;
31
31
  /** Told the sequence of a stored event this build cannot validate, so it can be logged. */
32
32
  onUnreadable?: (seq: number) => void;
33
+ /** Confirm that the subscription still belongs to an active member. */
34
+ revalidate?: () => Promise<boolean>;
33
35
  }
34
36
  /**
35
37
  * A server-sent event stream over a persisted, sequence-numbered log.
@@ -47,6 +49,16 @@ export interface SseOptions {
47
49
  * again; the log keeps the events in the meantime, which is the whole point of it being the truth.
48
50
  */
49
51
  export declare function createSseResponse(source: EventStreamSource, options: SseOptions): Response;
52
+ /**
53
+ * The answer to a stream request whose client had gone before the stream could be built.
54
+ *
55
+ * Still the contract's 200 `text/event-stream`, since response validation refuses any status the
56
+ * contract does not declare, but with no body: the stream ends before its first frame. Nobody is
57
+ * reading it in the ordinary case; a caller that wants a request which only *looked* aborted to be
58
+ * visible (a runtime passing a signal through wrongly would otherwise loop reconnects silently)
59
+ * logs the fact where it decided to answer this, as `LocalEventHub` does.
60
+ */
61
+ export declare function abandonedSseResponse(): Response;
50
62
  /**
51
63
  * One frame: the sequence number as its `id`, the contract's single event name, and the validated
52
64
  * event as JSON.
@@ -1 +1 @@
1
- {"version":3,"file":"createSseResponse.d.ts","sourceRoot":"","sources":["../../src/sse/createSseResponse.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAA;AAE7D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAE5C,MAAM,WAAW,iBAAiB;IAChC;;;;;OAKG;IACH,IAAI,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC,CAAA;IAC9D;;;;;OAKG;IACH,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAA;IAClC;;;;;;OAMG;IACH,SAAS,CAAC,IAAI,EAAE,MAAM,IAAI,EAAE,KAAK,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI,CAAA;CAC3D;AAED,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,MAAM,CAAA;IAChB,WAAW,EAAE,MAAM,CAAA;IACnB,MAAM,EAAE,WAAW,CAAA;IACnB,2FAA2F;IAC3F,YAAY,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAA;CACrC;AAkCD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,iBAAiB,EAAE,OAAO,EAAE,UAAU,GAAG,QAAQ,CAiK1F;AAED;;;;;;;;;GASG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,cAAc,GAAG,MAAM,CAIzD;AAED,oFAAoF;AACpF,wBAAgB,cAAc,CAAC,KAAK,EAAE,cAAc,GAAG,MAAM,GAAG,IAAI,CAMnE;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,cAAc,GAAG,OAAO,CAO9D"}
1
+ {"version":3,"file":"createSseResponse.d.ts","sourceRoot":"","sources":["../../src/sse/createSseResponse.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAA;AAE7D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAE5C,MAAM,WAAW,iBAAiB;IAChC;;;;;OAKG;IACH,IAAI,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC,CAAA;IAC9D;;;;;OAKG;IACH,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAA;IAClC;;;;;;OAMG;IACH,SAAS,CAAC,IAAI,EAAE,MAAM,IAAI,EAAE,KAAK,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI,CAAA;CAC3D;AAED,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,MAAM,CAAA;IAChB,WAAW,EAAE,MAAM,CAAA;IACnB,MAAM,EAAE,WAAW,CAAA;IACnB,2FAA2F;IAC3F,YAAY,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAA;IACpC,uEAAuE;IACvE,UAAU,CAAC,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAA;CACpC;AAkCD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,iBAAiB,EAAE,OAAO,EAAE,UAAU,GAAG,QAAQ,CAyL1F;AASD;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,IAAI,QAAQ,CAE/C;AAED;;;;;;;;;GASG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,cAAc,GAAG,MAAM,CAIzD;AAED,oFAAoF;AACpF,wBAAgB,cAAc,CAAC,KAAK,EAAE,cAAc,GAAG,MAAM,GAAG,IAAI,CAMnE;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,cAAc,GAAG,OAAO,CAO9D"}
@@ -44,6 +44,11 @@ const STREAM_HIGH_WATER_MARK = 32;
44
44
  * again; the log keeps the events in the meantime, which is the whole point of it being the truth.
45
45
  */
46
46
  export function createSseResponse(source, options) {
47
+ // An AbortSignal only dispatches an event for a future transition, and the caller can have done
48
+ // authentication and resume work after its client went away. Such a request is answered before
49
+ // anything is built: no subscription, no heartbeat, no abort listener that could never fire.
50
+ if (options.signal.aborted)
51
+ return abandonedSseResponse();
47
52
  const { onUnreadable } = options;
48
53
  let lastSeq = options.afterSeq;
49
54
  let draining = null;
@@ -144,6 +149,7 @@ export function createSseResponse(source, options) {
144
149
  });
145
150
  let beats = 0;
146
151
  let stalledBeats = 0;
152
+ let validating = false;
147
153
  const heartbeat = setInterval(() => {
148
154
  // A consumer that is not reading is not a consumer. The queue is full, so this frame
149
155
  // would only buffer; after a few beats of that the connection is gone in every way that
@@ -162,6 +168,27 @@ export function createSseResponse(source, options) {
162
168
  // idle server was otherwise issuing one query per stream per heartbeat to find nothing.
163
169
  beats += 1;
164
170
  const overdue = beats % CATCH_UP_EVERY_HEARTBEATS === 0;
171
+ if (overdue && options.revalidate) {
172
+ // A lookup still pending a whole catch-up cycle later is a failed one. Waiting on it
173
+ // instead left the stream never checked again for as long as that query hung.
174
+ if (validating) {
175
+ shutdown();
176
+ return;
177
+ }
178
+ validating = true;
179
+ void Promise.resolve()
180
+ .then(options.revalidate)
181
+ .then((valid) => {
182
+ validating = false;
183
+ if (!valid)
184
+ shutdown();
185
+ }, () => {
186
+ validating = false;
187
+ shutdown();
188
+ });
189
+ }
190
+ // The catch-up does not wait on the membership check: notifications keep delivering
191
+ // while it is in flight anyway, so holding this back only delayed the read.
165
192
  if (overdue || !source.caughtUp(lastSeq))
166
193
  wake(overdue);
167
194
  }, options.heartbeatMs);
@@ -169,6 +196,9 @@ export function createSseResponse(source, options) {
169
196
  if (closed)
170
197
  return;
171
198
  closed = true;
199
+ // A stream ended by `cancel`, a stall or its hub would otherwise leave this listener, and
200
+ // everything its closure holds, on the request signal for as long as that lives.
201
+ options.signal.removeEventListener('abort', shutdown);
172
202
  clearInterval(heartbeat);
173
203
  unsubscribe();
174
204
  // Release a drain parked on backpressure, so it observes `closed` and stops.
@@ -197,14 +227,25 @@ export function createSseResponse(source, options) {
197
227
  shutdown();
198
228
  },
199
229
  }, new CountQueuingStrategy({ highWaterMark: STREAM_HIGH_WATER_MARK }));
200
- return new Response(stream, {
201
- headers: {
202
- 'Content-Type': 'text/event-stream; charset=utf-8',
203
- 'Cache-Control': 'no-cache, no-transform',
204
- Connection: 'keep-alive',
205
- 'X-Accel-Buffering': 'no',
206
- },
207
- });
230
+ return new Response(stream, { headers: SSE_HEADERS });
231
+ }
232
+ const SSE_HEADERS = {
233
+ 'Content-Type': 'text/event-stream; charset=utf-8',
234
+ 'Cache-Control': 'no-cache, no-transform',
235
+ Connection: 'keep-alive',
236
+ 'X-Accel-Buffering': 'no',
237
+ };
238
+ /**
239
+ * The answer to a stream request whose client had gone before the stream could be built.
240
+ *
241
+ * Still the contract's 200 `text/event-stream`, since response validation refuses any status the
242
+ * contract does not declare, but with no body: the stream ends before its first frame. Nobody is
243
+ * reading it in the ordinary case; a caller that wants a request which only *looked* aborted to be
244
+ * visible (a runtime passing a signal through wrongly would otherwise loop reconnects silently)
245
+ * logs the fact where it decided to answer this, as `LocalEventHub` does.
246
+ */
247
+ export function abandonedSseResponse() {
248
+ return new Response(null, { headers: SSE_HEADERS });
208
249
  }
209
250
  /**
210
251
  * One frame: the sequence number as its `id`, the contract's single event name, and the validated
@@ -1 +1 @@
1
- {"version":3,"file":"createSseResponse.js","sourceRoot":"","sources":["../../src/sse/createSseResponse.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"createSseResponse.js","sourceRoot":"","sources":["../../src/sse/createSseResponse.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import type { PlayerRepository } from '@chaos-overlords/kernel';
2
+ /**
3
+ * Whether `playerId` still holds a live membership of `matchId`: the row exists, belongs to that
4
+ * match, and its token has not been revoked. A token is issued once per membership and never
5
+ * rotated, so a non-null hash is the token the stream was authenticated with.
6
+ *
7
+ * The stream route runs this right after subscribing and every hub repeats it on its catch-up
8
+ * heartbeat; one definition keeps the two from drifting apart.
9
+ */
10
+ export declare function isActiveMember(players: PlayerRepository, matchId: string, playerId: string): Promise<boolean>;
11
+ //# sourceMappingURL=membership.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"membership.d.ts","sourceRoot":"","sources":["../../src/sse/membership.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAA;AAE/D;;;;;;;GAOG;AACH,wBAAsB,cAAc,CAClC,OAAO,EAAE,gBAAgB,EACzB,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,OAAO,CAAC,CAGlB"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Whether `playerId` still holds a live membership of `matchId`: the row exists, belongs to that
3
+ * match, and its token has not been revoked. A token is issued once per membership and never
4
+ * rotated, so a non-null hash is the token the stream was authenticated with.
5
+ *
6
+ * The stream route runs this right after subscribing and every hub repeats it on its catch-up
7
+ * heartbeat; one definition keeps the two from drifting apart.
8
+ */
9
+ export async function isActiveMember(players, matchId, playerId) {
10
+ const player = await players.get(playerId);
11
+ return player?.matchId === matchId && player.tokenHash !== null;
12
+ }
13
+ //# sourceMappingURL=membership.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"membership.js","sourceRoot":"","sources":["../../src/sse/membership.ts"],"names":[],"mappings":"AAEA;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,OAAyB,EACzB,OAAe,EACf,QAAgB;IAEhB,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;IAC1C,OAAO,MAAM,EAAE,OAAO,KAAK,OAAO,IAAI,MAAM,CAAC,SAAS,KAAK,IAAI,CAAA;AACjE,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@chaos-overlords/server",
3
- "version": "0.9.0",
3
+ "version": "0.9.2",
4
4
  "description": "The Hono application both runtimes serve: REST intents, the SSE event stream, auth and the error envelope. Takes its ports through a container.",
5
5
  "keywords": [
6
6
  "chaos-overlords",
@@ -48,15 +48,15 @@
48
48
  "provenance": true
49
49
  },
50
50
  "dependencies": {
51
- "@chaos-overlords/bug-reports": "0.9.0",
52
- "@chaos-overlords/contracts": "0.9.0",
53
- "@chaos-overlords/kernel": "0.9.0",
51
+ "@chaos-overlords/bug-reports": "0.9.2",
52
+ "@chaos-overlords/contracts": "0.9.2",
53
+ "@chaos-overlords/kernel": "0.9.2",
54
54
  "@toad-contracts/core": "1.0.0",
55
55
  "@toad-contracts/hono": "1.0.0",
56
56
  "hono": "^4.13.8"
57
57
  },
58
58
  "devDependencies": {
59
- "@chaos-overlords/conformance": "0.9.0",
59
+ "@chaos-overlords/conformance": "0.9.2",
60
60
  "typescript": "^7.0.2",
61
61
  "vitest": "^4.1.11"
62
62
  },