@chaos-overlords/server 0.9.1 → 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 +28 -9
  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 +2 -0
  21. package/dist/index.d.ts.map +1 -1
  22. package/dist/index.js +2 -0
  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 +15 -5
  34. package/dist/sse/LocalEventHub.d.ts.map +1 -1
  35. package/dist/sse/LocalEventHub.js +56 -10
  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 +2 -0
  42. package/dist/sse/createSseResponse.d.ts.map +1 -1
  43. package/dist/sse/createSseResponse.js +22 -0
  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
package/dist/app.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAG3B,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAUlD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAA;AAQ1C,eAAO,MAAM,UAAU,YAAY,CAAA;AAInC,2FAA2F;AAC3F,wBAAgB,SAAS,CAAC,SAAS,EAAE,eAAe,GAAG,IAAI,CAAC,MAAM,CAAC,CAuBlE"}
1
+ {"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAG3B,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAWlD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAA;AAQ1C,eAAO,MAAM,UAAU,YAAY,CAAA;AAInC,2FAA2F;AAC3F,wBAAgB,SAAS,CAAC,SAAS,EAAE,eAAe,GAAG,IAAI,CAAC,MAAM,CAAC,CAuBlE"}
package/dist/app.js CHANGED
@@ -3,7 +3,7 @@ import { Hono } from 'hono';
3
3
  import { bodyLimit } from 'hono/body-limit';
4
4
  import { cors } from 'hono/cors';
5
5
  import { handleError } from './http/errorHandler';
6
- import { bearerAuth, bugReportRateLimited, memberRateLimited, rateLimited, requestId, } from './http/middleware';
6
+ import { bearerAuth, bugReportRateLimited, matchCreationRateLimited, memberRateLimited, rateLimited, requestId, } from './http/middleware';
7
7
  import { validateContractResponse } from './http/responseValidation';
8
8
  import { registerBugReportRoutes } from './routes/bugReports';
9
9
  import { registerEventRoutes } from './routes/events';
@@ -60,6 +60,8 @@ function apiRoutes() {
60
60
  registerProtocolRoutes(api);
61
61
  // The doors a stranger can knock on, throttled per client address.
62
62
  api.use('/matches', rateLimited, bodyLimit({ maxSize: LIMITS.gameSettingsBytes + SMALL_BODY }));
63
+ // Creating is also charged to one budget shared by every caller; browsing the same path is not.
64
+ api.on('POST', '/matches', matchCreationRateLimited);
63
65
  api.use('/matches/join', rateLimited, bodyLimit({ maxSize: SMALL_BODY }));
64
66
  // `use(path, ...)` matches the path verbatim, so neither of the two above covers this one. It is
65
67
  // a password-gated door like `/matches/join` and needs the same throttle and the same cap on a
package/dist/app.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"app.js","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"app.js","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Shared environment parsing for settings exposed by both server runtimes.
3
+ *
4
+ * Each parser takes the raw value as the runtime hands it over. On Node that is always a string; a
5
+ * Worker's `[vars]` entry written without quotes arrives as a number or a boolean instead, so the
6
+ * value is read through `String` rather than trusted to be one. `name`, when given, is put in front
7
+ * of a refusal so the log says which variable to fix.
8
+ */
9
+ type RawVar = string | number | boolean | undefined;
10
+ /**
11
+ * A whole number of at least `minimum`, or `fallback` when the variable is unset or empty.
12
+ *
13
+ * A rate limit of `0` is not "unlimited" and not "closed" — the limiter admits one call per window
14
+ * and refuses the rest, which nobody means — so every budget passes a floor of one, and the refusal
15
+ * names it rather than letting a misconfiguration run. Only decimal digits are read: `Number` would
16
+ * otherwise take a blank value as `0` and `0x10` or `1e3` as numbers nobody typed.
17
+ */
18
+ export declare function configInteger(raw: RawVar, fallback: number, minimum?: number, name?: string): number;
19
+ export declare function configFlag(raw: RawVar, fallback: boolean, name?: string): boolean;
20
+ export declare function configList(raw: RawVar): string[];
21
+ export {};
22
+ //# sourceMappingURL=configEnv.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"configEnv.d.ts","sourceRoot":"","sources":["../src/configEnv.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,KAAK,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,CAAA;AAMnD;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,SAAI,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAQ/F;AAED,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAmBjF;AAED,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CAKhD"}
@@ -0,0 +1,46 @@
1
+ function refuse(name, message) {
2
+ throw new Error(name ? `${name}: ${message}` : message);
3
+ }
4
+ /**
5
+ * A whole number of at least `minimum`, or `fallback` when the variable is unset or empty.
6
+ *
7
+ * A rate limit of `0` is not "unlimited" and not "closed" — the limiter admits one call per window
8
+ * and refuses the rest, which nobody means — so every budget passes a floor of one, and the refusal
9
+ * names it rather than letting a misconfiguration run. Only decimal digits are read: `Number` would
10
+ * otherwise take a blank value as `0` and `0x10` or `1e3` as numbers nobody typed.
11
+ */
12
+ export function configInteger(raw, fallback, minimum = 0, name) {
13
+ if (raw === undefined || raw === '')
14
+ return fallback;
15
+ const text = String(raw).trim();
16
+ const value = /^\d+$/.test(text) ? Number(text) : Number.NaN;
17
+ if (!Number.isSafeInteger(value) || value < minimum) {
18
+ refuse(name, `Expected an integer of at least ${minimum}, got "${String(raw)}"`);
19
+ }
20
+ return value;
21
+ }
22
+ export function configFlag(raw, fallback, name) {
23
+ if (raw === undefined || raw === '')
24
+ return fallback;
25
+ switch (String(raw).trim().toLowerCase()) {
26
+ case 'true':
27
+ case '1':
28
+ case 'yes':
29
+ case 'on':
30
+ return true;
31
+ case 'false':
32
+ case '0':
33
+ case 'no':
34
+ case 'off':
35
+ return false;
36
+ default:
37
+ return refuse(name, `Expected a boolean (true/false, 1/0, yes/no, on/off), got "${String(raw)}"`);
38
+ }
39
+ }
40
+ export function configList(raw) {
41
+ return String(raw ?? '')
42
+ .split(',')
43
+ .map((entry) => entry.trim())
44
+ .filter((entry) => entry.length > 0);
45
+ }
46
+ //# sourceMappingURL=configEnv.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"configEnv.js","sourceRoot":"","sources":["../src/configEnv.ts"],"names":[],"mappings":"AAUA,SAAS,MAAM,CAAC,IAAwB,EAAE,OAAe;IACvD,MAAM,IAAI,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,KAAK,OAAO,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAA;AACzD,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,aAAa,CAAC,GAAW,EAAE,QAAgB,EAAE,OAAO,GAAG,CAAC,EAAE,IAAa;IACrF,IAAI,GAAG,KAAK,SAAS,IAAI,GAAG,KAAK,EAAE;QAAE,OAAO,QAAQ,CAAA;IACpD,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAA;IAC/B,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAA;IAC5D,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,OAAO,EAAE,CAAC;QACpD,MAAM,CAAC,IAAI,EAAE,mCAAmC,OAAO,UAAU,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;IAClF,CAAC;IACD,OAAO,KAAK,CAAA;AACd,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,GAAW,EAAE,QAAiB,EAAE,IAAa;IACtE,IAAI,GAAG,KAAK,SAAS,IAAI,GAAG,KAAK,EAAE;QAAE,OAAO,QAAQ,CAAA;IACpD,QAAQ,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC;QACzC,KAAK,MAAM,CAAC;QACZ,KAAK,GAAG,CAAC;QACT,KAAK,KAAK,CAAC;QACX,KAAK,IAAI;YACP,OAAO,IAAI,CAAA;QACb,KAAK,OAAO,CAAC;QACb,KAAK,GAAG,CAAC;QACT,KAAK,IAAI,CAAC;QACV,KAAK,KAAK;YACR,OAAO,KAAK,CAAA;QACd;YACE,OAAO,MAAM,CACX,IAAI,EACJ,8DAA8D,MAAM,CAAC,GAAG,CAAC,GAAG,CAC7E,CAAA;IACL,CAAC;AACH,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,GAAW;IACpC,OAAO,MAAM,CAAC,GAAG,IAAI,EAAE,CAAC;SACrB,KAAK,CAAC,GAAG,CAAC;SACV,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;SAC5B,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAA;AACxC,CAAC"}
@@ -56,6 +56,17 @@ export interface RateLimiters {
56
56
  * part worth keeping.
57
57
  */
58
58
  bugReportState: RateLimiter;
59
+ /**
60
+ * Matches this process creates per window, from every caller together, under one key.
61
+ *
62
+ * The anonymous tier is per address, so it bounds one stranger and nothing about many. Each
63
+ * create is a stored lobby that lives until lobby retention collects it, and a PBKDF2 hash when it
64
+ * carries a password, so a flood from a few thousand addresses at the per-address rate would grow
65
+ * the matches table and hold the CPU without ever meeting a limit. This is the ceiling that
66
+ * distributed case meets. Joining and browsing are not charged here, so an existing lobby stays
67
+ * reachable while it is spent.
68
+ */
69
+ matchCreation: RateLimiter;
59
70
  }
60
71
  export interface ServerContainer {
61
72
  kernel: Kernel;
@@ -87,5 +98,11 @@ export declare const DEFAULT_RATE_LIMITS: {
87
98
  * of the default global budget, so no single address can crowd everybody else out of it.
88
99
  */
89
100
  readonly bugReportStatePerDay: 5;
101
+ /**
102
+ * Matches created per minute across every caller. Two a second is far beyond what players open by
103
+ * hand on any server this is likely to run, and caps a flood at under three thousand lobbies an
104
+ * hour for lobby retention to collect.
105
+ */
106
+ readonly matchCreationPerMinute: 120;
90
107
  };
91
108
  //# sourceMappingURL=container.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"container.d.ts","sourceRoot":"","sources":["../src/container.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAA;AACpE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAA;AACrF,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAA;AACnC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAA;AAE1C,MAAM,WAAW,YAAY;IAC3B;;;;;;;;OAQG;IACH,aAAa,EAAE,OAAO,CAAA;IACtB,+CAA+C;IAC/C,cAAc,EAAE,MAAM,CAAA;IACtB;;;;OAIG;IACH,WAAW,EAAE,SAAS,MAAM,EAAE,CAAA;CAC/B;AAED;;;;;;;;;GASG;AACH,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,WAAW,CAAA;IACtB,MAAM,EAAE,WAAW,CAAA;IACnB,MAAM,EAAE,WAAW,CAAA;IACnB;;;;;;;OAOG;IACH,SAAS,EAAE,WAAW,CAAA;IACtB;;;;;;;;;OASG;IACH,cAAc,EAAE,WAAW,CAAA;CAC5B;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAA;IACd;;;OAGG;IACH,UAAU,CAAC,EAAE,gBAAgB,CAAA;IAC7B,WAAW,EAAE,iBAAiB,CAAA;IAC9B,YAAY,EAAE,YAAY,CAAA;IAC1B,MAAM,EAAE,YAAY,CAAA;IACpB,wFAAwF;IACxF,aAAa,CAAC,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,KAAK,MAAM,CAAA;CAC/C;AAED,eAAO,MAAM,qBAAqB,EAAE,YAInC,CAAA;AAED,sFAAsF;AACtF,eAAO,MAAM,mBAAmB;aAC9B,kBAAkB,EAAE,EAAE;aACtB,eAAe,EAAE,GAAG;aACpB,eAAe,EAAE,EAAE;IACnB;;;;OAIG;aACH,kBAAkB,EAAE,CAAC;IACrB;;;OAGG;aACH,oBAAoB,EAAE,CAAC;CACf,CAAA"}
1
+ {"version":3,"file":"container.d.ts","sourceRoot":"","sources":["../src/container.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAA;AACpE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAA;AACrF,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAA;AACnC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAA;AAE1C,MAAM,WAAW,YAAY;IAC3B;;;;;;;;OAQG;IACH,aAAa,EAAE,OAAO,CAAA;IACtB,+CAA+C;IAC/C,cAAc,EAAE,MAAM,CAAA;IACtB;;;;OAIG;IACH,WAAW,EAAE,SAAS,MAAM,EAAE,CAAA;CAC/B;AAED;;;;;;;;;GASG;AACH,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,WAAW,CAAA;IACtB,MAAM,EAAE,WAAW,CAAA;IACnB,MAAM,EAAE,WAAW,CAAA;IACnB;;;;;;;OAOG;IACH,SAAS,EAAE,WAAW,CAAA;IACtB;;;;;;;;;OASG;IACH,cAAc,EAAE,WAAW,CAAA;IAC3B;;;;;;;;;OASG;IACH,aAAa,EAAE,WAAW,CAAA;CAC3B;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAA;IACd;;;OAGG;IACH,UAAU,CAAC,EAAE,gBAAgB,CAAA;IAC7B,WAAW,EAAE,iBAAiB,CAAA;IAC9B,YAAY,EAAE,YAAY,CAAA;IAC1B,MAAM,EAAE,YAAY,CAAA;IACpB,wFAAwF;IACxF,aAAa,CAAC,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,KAAK,MAAM,CAAA;CAC/C;AAED,eAAO,MAAM,qBAAqB,EAAE,YAInC,CAAA;AAED,sFAAsF;AACtF,eAAO,MAAM,mBAAmB;aAC9B,kBAAkB,EAAE,EAAE;aACtB,eAAe,EAAE,GAAG;aACpB,eAAe,EAAE,EAAE;IACnB;;;;OAIG;aACH,kBAAkB,EAAE,CAAC;IACrB;;;OAGG;aACH,oBAAoB,EAAE,CAAC;IACvB;;;;OAIG;aACH,sBAAsB,EAAE,GAAG;CACnB,CAAA"}
package/dist/container.js CHANGED
@@ -19,5 +19,11 @@ export const DEFAULT_RATE_LIMITS = {
19
19
  * of the default global budget, so no single address can crowd everybody else out of it.
20
20
  */
21
21
  bugReportStatePerDay: 5,
22
+ /**
23
+ * Matches created per minute across every caller. Two a second is far beyond what players open by
24
+ * hand on any server this is likely to run, and caps a flood at under three thousand lobbies an
25
+ * hour for lobby retention to collect.
26
+ */
27
+ matchCreationPerMinute: 120,
22
28
  };
23
29
  //# sourceMappingURL=container.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"container.js","sourceRoot":"","sources":["../src/container.ts"],"names":[],"mappings":"AA4EA,MAAM,CAAC,MAAM,qBAAqB,GAAiB;IACjD,aAAa,EAAE,IAAI;IACnB,cAAc,EAAE,MAAM;IACtB,WAAW,EAAE,EAAE;CAChB,CAAA;AAED,sFAAsF;AACtF,MAAM,CAAC,MAAM,mBAAmB,GAAG;IACjC,kBAAkB,EAAE,EAAE;IACtB,eAAe,EAAE,GAAG;IACpB,eAAe,EAAE,EAAE;IACnB;;;;OAIG;IACH,kBAAkB,EAAE,CAAC;IACrB;;;OAGG;IACH,oBAAoB,EAAE,CAAC;CACf,CAAA"}
1
+ {"version":3,"file":"container.js","sourceRoot":"","sources":["../src/container.ts"],"names":[],"mappings":"AAuFA,MAAM,CAAC,MAAM,qBAAqB,GAAiB;IACjD,aAAa,EAAE,IAAI;IACnB,cAAc,EAAE,MAAM;IACtB,WAAW,EAAE,EAAE;CAChB,CAAA;AAED,sFAAsF;AACtF,MAAM,CAAC,MAAM,mBAAmB,GAAG;IACjC,kBAAkB,EAAE,EAAE;IACtB,eAAe,EAAE,GAAG;IACpB,eAAe,EAAE,EAAE;IACnB;;;;OAIG;IACH,kBAAkB,EAAE,CAAC;IACrB;;;OAGG;IACH,oBAAoB,EAAE,CAAC;IACvB;;;;OAIG;IACH,sBAAsB,EAAE,GAAG;CACnB,CAAA"}
@@ -94,6 +94,11 @@ function codeForStatus(status) {
94
94
  }
95
95
  function respond(c, { code, message, details, requestId }) {
96
96
  const body = { error: { code, message, details, requestId } };
97
+ // Hono carries every header already set on this context onto the error response that replaces
98
+ // a handler's, so a caching policy the handler chose for its success (the sealed-order set's
99
+ // `immutable`, say) would otherwise be applied to the refusal. It must be overwritten on the
100
+ // context itself: the `c.res` setter copies the previous response's headers over the new one.
101
+ c.header('Cache-Control', 'no-store');
97
102
  return c.json(validateSync(errorEnvelopeSchema, body), STATUS_BY_CODE[code]);
98
103
  }
99
104
  //# sourceMappingURL=errorHandler.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"errorHandler.js","sourceRoot":"","sources":["../../src/http/errorHandler.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"errorHandler.js","sourceRoot":"","sources":["../../src/http/errorHandler.ts"],"names":[],"mappings":"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"}
@@ -25,6 +25,17 @@ export declare const rateLimited: MiddlewareHandler<AppEnv>;
25
25
  * one must not be able to exhaust the other.
26
26
  */
27
27
  export declare const bugReportRateLimited: MiddlewareHandler<AppEnv>;
28
+ /**
29
+ * The process-wide budget on creating a match, checked here and spent by the create handler.
30
+ *
31
+ * Mounted for `POST /matches` alone, because the same path also serves the public listing, which
32
+ * must not spend it. It runs after `rateLimited`, so a single address over its own budget is
33
+ * refused without touching the shared one. It only PEEKS: a spent budget is refused before the
34
+ * body is read, but a request is charged only once its body has passed the contract validator,
35
+ * through `spendMatchCreation`. Charging here would let a handful of addresses sending malformed
36
+ * bodies, which never store a lobby, hold the shared budget at zero for every legitimate host.
37
+ */
38
+ export declare const matchCreationRateLimited: MiddlewareHandler<AppEnv>;
28
39
  /**
29
40
  * Limiter for an authenticated member, keyed by player rather than address so one player on a shared
30
41
  * address cannot spend another's budget. Must run after `bearerAuth`.
@@ -1 +1 @@
1
- {"version":3,"file":"middleware.d.ts","sourceRoot":"","sources":["../../src/http/middleware.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,iBAAiB,EAAE,MAAM,MAAM,CAAA;AACtD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAChD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,SAAS,CAAA;AAErC;;;;;GAKG;AACH,eAAO,MAAM,SAAS,EAAE,iBAAiB,CAAC,MAAM,CAK/C,CAAA;AAgBD;;;;;;;GAOG;AACH,eAAO,MAAM,UAAU,EAAE,iBAAiB,CAAC,MAAM,CAgBhD,CAAA;AAgBD,kFAAkF;AAClF,eAAO,MAAM,WAAW,EAAE,iBAAiB,CAAC,MAAM,CAOjD,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,EAAE,iBAAiB,CAAC,MAAM,CAe1D,CAAA;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,GAAE,MAAM,YAAuB,GAAG,iBAAiB,CAAC,MAAM,CAAC,CAMhG;AAQD;;;;;;;;;GASG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAoBpD;AAmED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,oBAAoB,CAClC,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,EAClB,OAAO,GAAE;IAAE,UAAU,CAAC,EAAE,OAAO,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAO,GACpD,MAAM,CAaR"}
1
+ {"version":3,"file":"middleware.d.ts","sourceRoot":"","sources":["../../src/http/middleware.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,iBAAiB,EAAE,MAAM,MAAM,CAAA;AACtD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAChD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,SAAS,CAAA;AAErC;;;;;GAKG;AACH,eAAO,MAAM,SAAS,EAAE,iBAAiB,CAAC,MAAM,CAK/C,CAAA;AAgBD;;;;;;;GAOG;AACH,eAAO,MAAM,UAAU,EAAE,iBAAiB,CAAC,MAAM,CAgBhD,CAAA;AAgBD,kFAAkF;AAClF,eAAO,MAAM,WAAW,EAAE,iBAAiB,CAAC,MAAM,CAOjD,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,EAAE,iBAAiB,CAAC,MAAM,CAU1D,CAAA;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,wBAAwB,EAAE,iBAAiB,CAAC,MAAM,CAM9D,CAAA;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,GAAE,MAAM,YAAuB,GAAG,iBAAiB,CAAC,MAAM,CAAC,CAMhG;AAQD;;;;;;;;;GASG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAoBpD;AAyED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,oBAAoB,CAClC,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,EAClB,OAAO,GAAE;IAAE,UAAU,CAAC,EAAE,OAAO,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAO,GACpD,MAAM,CAaR"}
@@ -82,12 +82,27 @@ export const bugReportRateLimited = async (c, next) => {
82
82
  const container = c.get('container');
83
83
  const key = addressOf(c);
84
84
  enforce(container.rateLimiters, 'bugReport', key, c);
85
- // The daily journal budget is NOT spent here. It used to be, before the body had even been read,
86
- // so five text-only reports or five requests the contract validator answered 413 or 422 for spent
87
- // it, and the sixth — the one that actually carried a journal — was quietly filed with
88
- // `stateStored: 'omitted'`. Everyone behind one NAT shares those five. The handler spends it
89
- // instead, once it knows there is a journal to spend it on; see the bug report route.
90
- c.set('bugReportJournalBudget', () => container.rateLimiters.bugReportState.take(`bugReportState:${rateLimitKey(key)}`) === null);
85
+ // The handler reserves one unit only for a validated report carrying a journal, then releases it
86
+ // if the journal fails its digest check or is omitted by the storage budget.
87
+ c.set('bugReportJournalBudget', () => container.rateLimiters.bugReportState.reserve(`bugReportState:${rateLimitKey(key)}`));
88
+ await next();
89
+ };
90
+ /**
91
+ * The process-wide budget on creating a match, checked here and spent by the create handler.
92
+ *
93
+ * Mounted for `POST /matches` alone, because the same path also serves the public listing, which
94
+ * must not spend it. It runs after `rateLimited`, so a single address over its own budget is
95
+ * refused without touching the shared one. It only PEEKS: a spent budget is refused before the
96
+ * body is read, but a request is charged only once its body has passed the contract validator,
97
+ * through `spendMatchCreation`. Charging here would let a handful of addresses sending malformed
98
+ * bodies, which never store a lobby, hold the shared budget at zero for every legitimate host.
99
+ */
100
+ export const matchCreationRateLimited = async (c, next) => {
101
+ const limiters = c.get('container').rateLimiters;
102
+ const retryAfter = limiters.matchCreation.peek(`matchCreation:${MATCH_CREATION_KEY}`);
103
+ if (retryAfter !== null)
104
+ refuse(c, retryAfter);
105
+ c.set('spendMatchCreation', () => enforce(limiters, 'matchCreation', MATCH_CREATION_KEY, c));
91
106
  await next();
92
107
  };
93
108
  /**
@@ -187,11 +202,15 @@ function ipv6Prefix64(address) {
187
202
  * `rateLimitKey` masks IPv6 prefixes and strips ports, which is meaningless work on a player UUID
188
203
  * and runs on every authenticated request.
189
204
  */
190
- const IDENTITY_TIERS = new Set(['member', 'upload']);
205
+ const IDENTITY_TIERS = new Set(['member', 'upload', 'matchCreation']);
206
+ /** The one key the match-creation tier counts under; it is a process-wide budget, not a per-caller one. */
207
+ const MATCH_CREATION_KEY = 'all';
191
208
  function enforce(limiters, tier, key, c) {
192
209
  const retryAfter = limiters[tier].take(`${tier}:${IDENTITY_TIERS.has(tier) ? key : rateLimitKey(key)}`);
193
- if (retryAfter === null)
194
- return;
210
+ if (retryAfter !== null)
211
+ refuse(c, retryAfter);
212
+ }
213
+ function refuse(c, retryAfter) {
195
214
  c.header('Retry-After', String(retryAfter));
196
215
  throw new RateLimitedError('Too many attempts; slow down', {
197
216
  reason: 'rate_limited',
@@ -1 +1 @@
1
- {"version":3,"file":"middleware.js","sourceRoot":"","sources":["../../src/http/middleware.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"middleware.js","sourceRoot":"","sources":["../../src/http/middleware.ts"],"names":[],"mappings":"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"}
@@ -15,11 +15,16 @@ export interface AppEnv {
15
15
  */
16
16
  caller?: string;
17
17
  /**
18
- * Spends one unit of this caller's daily attached-journal budget and says whether there was
19
- * any left. Set by `bugReportRateLimited`, called by the handler and only for a report that
20
- * actually carries a journal; absent everywhere else.
18
+ * Reserves one unit of this caller's daily attached-journal budget. Returns a release function
19
+ * when allowed, or null when spent. The handler releases it unless the journal is stored.
21
20
  */
22
- bugReportJournalBudget?: () => boolean;
21
+ bugReportJournalBudget?: () => (() => void) | null;
22
+ /**
23
+ * Spends one unit of the process-wide match-creation budget, or throws the 429 when it is gone.
24
+ * Set by `matchCreationRateLimited`, called by the create handler once the body has validated;
25
+ * absent everywhere else.
26
+ */
27
+ spendMatchCreation?: () => void;
23
28
  /**
24
29
  * The object a contract handler answered with, recorded by `contractJson` so the response
25
30
  * validator can check it without parsing the body back out. Wrapped so that a handler
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/http/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAA;AACxD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAA;AACvD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAA;AAEnD,MAAM,WAAW,MAAM;IACrB,SAAS,EAAE;QACT,SAAS,EAAE,eAAe,CAAA;QAC1B,SAAS,EAAE,MAAM,CAAA;QACjB,SAAS,EAAE,SAAS,CAAA;QACpB,wFAAwF;QACxF,WAAW,CAAC,EAAE,WAAW,CAAA;QACzB;;;;WAIG;QACH,MAAM,CAAC,EAAE,MAAM,CAAA;QACf;;;;WAIG;QACH,sBAAsB,CAAC,EAAE,MAAM,OAAO,CAAA;QACtC;;;;WAIG;QACH,YAAY,CAAC,EAAE;YAAE,KAAK,EAAE,OAAO,CAAA;SAAE,CAAA;KAClC,CAAA;CACF"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/http/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAA;AACxD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAA;AACvD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAA;AAEnD,MAAM,WAAW,MAAM;IACrB,SAAS,EAAE;QACT,SAAS,EAAE,eAAe,CAAA;QAC1B,SAAS,EAAE,MAAM,CAAA;QACjB,SAAS,EAAE,SAAS,CAAA;QACpB,wFAAwF;QACxF,WAAW,CAAC,EAAE,WAAW,CAAA;QACzB;;;;WAIG;QACH,MAAM,CAAC,EAAE,MAAM,CAAA;QACf;;;WAGG;QACH,sBAAsB,CAAC,EAAE,MAAM,CAAC,MAAM,IAAI,CAAC,GAAG,IAAI,CAAA;QAClD;;;;WAIG;QACH,kBAAkB,CAAC,EAAE,MAAM,IAAI,CAAA;QAC/B;;;;WAIG;QACH,YAAY,CAAC,EAAE;YAAE,KAAK,EAAE,OAAO,CAAA;SAAE,CAAA;KAClC,CAAA;CACF"}
package/dist/index.d.ts CHANGED
@@ -1,8 +1,10 @@
1
1
  export { API_PREFIX, createApp } from './app';
2
+ export { configFlag, configInteger, configList } from './configEnv';
2
3
  export { DEFAULT_RATE_LIMITS, DEFAULT_SERVER_CONFIG, type RateLimiters, type ServerConfig, type ServerContainer, } from './container';
3
4
  export { bugReportRateLimited, defaultClientAddress, rateLimitKey } from './http/middleware';
4
5
  export type { AppEnv } from './http/types';
5
6
  export { createSseResponse, type EventStreamSource, formatEvent, isReadableEvent, } from './sse/createSseResponse';
6
7
  export { type EventFrame, MatchLog } from './sse/MatchLog';
8
+ export { isActiveMember } from './sse/membership';
7
9
  export { DEFAULT_EVENT_HUB_LIMITS, type EventHubLimits, type EventHubObserver, LocalEventHub, } from './sse/LocalEventHub';
8
10
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAC7C,OAAO,EACL,mBAAmB,EACnB,qBAAqB,EACrB,KAAK,YAAY,EACjB,KAAK,YAAY,EACjB,KAAK,eAAe,GACrB,MAAM,aAAa,CAAA;AACpB,OAAO,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAC5F,YAAY,EAAE,MAAM,EAAE,MAAM,cAAc,CAAA;AAC1C,OAAO,EACL,iBAAiB,EACjB,KAAK,iBAAiB,EACtB,WAAW,EACX,eAAe,GAChB,MAAM,yBAAyB,CAAA;AAChC,OAAO,EAAE,KAAK,UAAU,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AAC1D,OAAO,EACL,wBAAwB,EACxB,KAAK,cAAc,EACnB,KAAK,gBAAgB,EACrB,aAAa,GACd,MAAM,qBAAqB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAC7C,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AACnE,OAAO,EACL,mBAAmB,EACnB,qBAAqB,EACrB,KAAK,YAAY,EACjB,KAAK,YAAY,EACjB,KAAK,eAAe,GACrB,MAAM,aAAa,CAAA;AACpB,OAAO,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAC5F,YAAY,EAAE,MAAM,EAAE,MAAM,cAAc,CAAA;AAC1C,OAAO,EACL,iBAAiB,EACjB,KAAK,iBAAiB,EACtB,WAAW,EACX,eAAe,GAChB,MAAM,yBAAyB,CAAA;AAChC,OAAO,EAAE,KAAK,UAAU,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAA;AACjD,OAAO,EACL,wBAAwB,EACxB,KAAK,cAAc,EACnB,KAAK,gBAAgB,EACrB,aAAa,GACd,MAAM,qBAAqB,CAAA"}
package/dist/index.js CHANGED
@@ -1,7 +1,9 @@
1
1
  export { API_PREFIX, createApp } from './app';
2
+ export { configFlag, configInteger, configList } from './configEnv';
2
3
  export { DEFAULT_RATE_LIMITS, DEFAULT_SERVER_CONFIG, } from './container';
3
4
  export { bugReportRateLimited, defaultClientAddress, rateLimitKey } from './http/middleware';
4
5
  export { createSseResponse, formatEvent, isReadableEvent, } from './sse/createSseResponse';
5
6
  export { MatchLog } from './sse/MatchLog';
7
+ export { isActiveMember } from './sse/membership';
6
8
  export { DEFAULT_EVENT_HUB_LIMITS, LocalEventHub, } from './sse/LocalEventHub';
7
9
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAC7C,OAAO,EACL,mBAAmB,EACnB,qBAAqB,GAItB,MAAM,aAAa,CAAA;AACpB,OAAO,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAE5F,OAAO,EACL,iBAAiB,EAEjB,WAAW,EACX,eAAe,GAChB,MAAM,yBAAyB,CAAA;AAChC,OAAO,EAAmB,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AAC1D,OAAO,EACL,wBAAwB,EAGxB,aAAa,GACd,MAAM,qBAAqB,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAC7C,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AACnE,OAAO,EACL,mBAAmB,EACnB,qBAAqB,GAItB,MAAM,aAAa,CAAA;AACpB,OAAO,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAE5F,OAAO,EACL,iBAAiB,EAEjB,WAAW,EACX,eAAe,GAChB,MAAM,yBAAyB,CAAA;AAChC,OAAO,EAAmB,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAA;AACjD,OAAO,EACL,wBAAwB,EAGxB,aAAa,GACd,MAAM,qBAAqB,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"bugReports.d.ts","sourceRoot":"","sources":["../../src/routes/bugReports.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAGhC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,eAAe,CAAA;AAE3C;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,IAAI,CAAC,MAAM,CAAC,GAAG,IAAI,CAqB/D"}
1
+ {"version":3,"file":"bugReports.d.ts","sourceRoot":"","sources":["../../src/routes/bugReports.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAGhC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,eAAe,CAAA;AAE3C;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,IAAI,CAAC,MAAM,CAAC,GAAG,IAAI,CAyB/D"}
@@ -19,17 +19,23 @@ export function registerBugReportRoutes(api) {
19
19
  });
20
20
  }
21
21
  const request = c.req.valid('json');
22
- // The daily journal budget is spent HERE: after the contract has validated the body, and only
23
- // when there is a journal to spend it on. Charging it in the middleware meant five text-only
24
- // reports, or five bodies the validator refused, used up the day's allowance for everyone
25
- // behind one address — and the sixth report, the one carrying the journal somebody wanted, was
26
- // filed without it and said so only in the receipt.
27
- //
28
- // An address that really has spent it files the description without the journal, and the
29
- // receipt says `omitted` — the same outcome the global byte budget produces.
30
- const allowed = request.state === undefined || (c.get('bugReportJournalBudget')?.() ?? true);
31
- const submitted = allowed ? request : { ...request, state: undefined };
32
- return c.json(answering(c, await bugReports.submit(submitted)), 201);
22
+ const release = request.state === undefined ? undefined : c.get('bugReportJournalBudget')?.();
23
+ const denied = release === null;
24
+ const submitted = denied ? { ...request, state: undefined } : request;
25
+ let stored = false;
26
+ try {
27
+ const receipt = await bugReports.submit(submitted);
28
+ stored = receipt.stateStored === 'stored';
29
+ // The intake sees no journal when this address is spent, but the client did send one.
30
+ return c.json(answering(c, denied ? { ...receipt, stateStored: 'omitted' } : receipt), 201);
31
+ }
32
+ finally {
33
+ // A digest refusal, global-byte omission, row failure, or any other non-storage outcome
34
+ // cannot spend the caller's allowance. The reservation is per request and safe to release
35
+ // even if another request has since entered the same address window.
36
+ if (!stored)
37
+ release?.();
38
+ }
33
39
  });
34
40
  }
35
41
  //# sourceMappingURL=bugReports.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"bugReports.js","sourceRoot":"","sources":["../../src/routes/bugReports.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,MAAM,4BAA4B,CAAA;AACpE,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAA;AAEvD,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAA;AAChD,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;AAG/C;;;;;;;GAOG;AACH,MAAM,UAAU,uBAAuB,CAAC,GAAiB;IACvD,cAAc,CAAC,GAAG,EAAE,uBAAuB,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;QACvD,MAAM,EAAE,UAAU,EAAE,GAAG,CAAC,CAAC,GAAG,CAAC,WAAW,CAAC,CAAA;QACzC,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,MAAM,IAAI,aAAa,CAAC,yCAAyC,EAAE;gBACjE,MAAM,EAAE,sBAAsB;aAC/B,CAAC,CAAA;QACJ,CAAC;QACD,MAAM,OAAO,GAAG,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAA;QACnC,8FAA8F;QAC9F,6FAA6F;QAC7F,0FAA0F;QAC1F,+FAA+F;QAC/F,oDAAoD;QACpD,EAAE;QACF,yFAAyF;QACzF,6EAA6E;QAC7E,MAAM,OAAO,GAAG,OAAO,CAAC,KAAK,KAAK,SAAS,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,wBAAwB,CAAC,EAAE,EAAE,IAAI,IAAI,CAAC,CAAA;QAC5F,MAAM,SAAS,GAAG,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,GAAG,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,CAAA;QACtE,OAAO,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,MAAM,UAAU,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,EAAE,GAAG,CAAC,CAAA;IACtE,CAAC,CAAC,CAAA;AACJ,CAAC"}
1
+ {"version":3,"file":"bugReports.js","sourceRoot":"","sources":["../../src/routes/bugReports.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,MAAM,4BAA4B,CAAA;AACpE,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAA;AAEvD,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAA;AAChD,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;AAG/C;;;;;;;GAOG;AACH,MAAM,UAAU,uBAAuB,CAAC,GAAiB;IACvD,cAAc,CAAC,GAAG,EAAE,uBAAuB,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;QACvD,MAAM,EAAE,UAAU,EAAE,GAAG,CAAC,CAAC,GAAG,CAAC,WAAW,CAAC,CAAA;QACzC,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,MAAM,IAAI,aAAa,CAAC,yCAAyC,EAAE;gBACjE,MAAM,EAAE,sBAAsB;aAC/B,CAAC,CAAA;QACJ,CAAC;QACD,MAAM,OAAO,GAAG,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAA;QACnC,MAAM,OAAO,GAAG,OAAO,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,wBAAwB,CAAC,EAAE,EAAE,CAAA;QAC7F,MAAM,MAAM,GAAG,OAAO,KAAK,IAAI,CAAA;QAC/B,MAAM,SAAS,GAAG,MAAM,CAAC,CAAC,CAAC,EAAE,GAAG,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,OAAO,CAAA;QACrE,IAAI,MAAM,GAAG,KAAK,CAAA;QAClB,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,UAAU,CAAC,MAAM,CAAC,SAAS,CAAC,CAAA;YAClD,MAAM,GAAG,OAAO,CAAC,WAAW,KAAK,QAAQ,CAAA;YACzC,sFAAsF;YACtF,OAAO,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,GAAG,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,GAAG,CAAC,CAAA;QAC7F,CAAC;gBAAS,CAAC;YACT,wFAAwF;YACxF,0FAA0F;YAC1F,qEAAqE;YACrE,IAAI,CAAC,MAAM;gBAAE,OAAO,EAAE,EAAE,CAAA;QAC1B,CAAC;IACH,CAAC,CAAC,CAAA;AACJ,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../../src/routes/events.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAIhC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,eAAe,CAAA;AAG3C,4FAA4F;AAC5F,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,IAAI,CAAC,MAAM,CAAC,GAAG,IAAI,CA0C3D"}
1
+ {"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../../src/routes/events.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAIhC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,eAAe,CAAA;AAI3C,4FAA4F;AAC5F,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,IAAI,CAAC,MAAM,CAAC,GAAG,IAAI,CA2D3D"}
@@ -1,8 +1,10 @@
1
1
  import { INT32_MAX, listEventsContract, streamEventsContract } from '@chaos-overlords/contracts';
2
+ import { UnauthorizedError } from '@chaos-overlords/kernel';
2
3
  import { answering } from '../http/contractJson';
3
4
  import { requireMember } from '../http/guards';
4
5
  import { buildHonoRoute } from '../http/routes';
5
6
  import { isReadableEvent } from '../sse/createSseResponse';
7
+ import { isActiveMember } from '../sse/membership';
6
8
  /** The event log: a paged REST read (the fallback) and the SSE stream over the same log. */
7
9
  export function registerEventRoutes(api) {
8
10
  buildHonoRoute(api, listEventsContract, async (c) => {
@@ -36,7 +38,22 @@ export function registerEventRoutes(api) {
36
38
  playerId: principal.player.id,
37
39
  afterSeq,
38
40
  signal: c.req.raw.signal,
41
+ lobby: principal.match.status === 'lobby',
39
42
  });
43
+ // The kick may have revoked the token and run hangUp after bearerAuth but before the hub
44
+ // subscribed. That hangUp saw no listener. Re-read the row after open and cancel the new stream
45
+ // before returning any of its buffered frames when the membership is already gone.
46
+ let stillMember = false;
47
+ try {
48
+ stillMember = await isActiveMember(c.get('container').kernel.deps.storage.players, principal.match.id, principal.player.id);
49
+ }
50
+ finally {
51
+ if (!stillMember)
52
+ await stream.body?.cancel();
53
+ }
54
+ if (!stillMember) {
55
+ throw new UnauthorizedError('Invalid or expired player token', { reason: 'invalid_token' });
56
+ }
40
57
  // The stream is a raw `Response`, and Hono does not merge the headers the middleware prepared
41
58
  // into one of those — so the one response an operator most wants to correlate, a stream that
42
59
  // misbehaved for an hour, was the only one without an `X-Request-Id`.
@@ -1 +1 @@
1
- {"version":3,"file":"events.js","sourceRoot":"","sources":["../../src/routes/events.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"events.js","sourceRoot":"","sources":["../../src/routes/events.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"lobby.d.ts","sourceRoot":"","sources":["../../src/routes/lobby.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAIhC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,eAAe,CAAA;AAE3C;;;;;;GAMG;AACH,wBAAgB,yBAAyB,CAAC,GAAG,EAAE,IAAI,CAAC,MAAM,CAAC,GAAG,IAAI,CAgCjE;AAED,4DAA4D;AAC5D,wBAAgB,yBAAyB,CAAC,GAAG,EAAE,IAAI,CAAC,MAAM,CAAC,GAAG,IAAI,CA8DjE"}
1
+ {"version":3,"file":"lobby.d.ts","sourceRoot":"","sources":["../../src/routes/lobby.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAIhC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,eAAe,CAAA;AAE3C;;;;;;GAMG;AACH,wBAAgB,yBAAyB,CAAC,GAAG,EAAE,IAAI,CAAC,MAAM,CAAC,GAAG,IAAI,CAmCjE;AAED,4DAA4D;AAC5D,wBAAgB,yBAAyB,CAAC,GAAG,EAAE,IAAI,CAAC,MAAM,CAAC,GAAG,IAAI,CA8DjE"}
@@ -21,6 +21,9 @@ export function registerPublicLobbyRoutes(api) {
21
21
  return c.json(answering(c, { matches: await kernel.query.listPublicLobbies(50) }), 200);
22
22
  });
23
23
  buildHonoRoute(api, createMatchContract, async (c) => {
24
+ // Charged here, after the contract validator, so a body that was never going to store a lobby
25
+ // does not spend the budget every host shares; `matchCreationRateLimited` only checks it.
26
+ c.get('spendMatchCreation')?.();
24
27
  const membership = await c.get('container').kernel.lobby.createMatch(c.req.valid('json'));
25
28
  return c.json(answering(c, membership), 201);
26
29
  });
@@ -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,8 +22,10 @@ export interface EventHubLimits {
20
22
  perProcess: number;
21
23
  }
22
24
  export declare const DEFAULT_EVENT_HUB_LIMITS: EventHubLimits;
23
- /** What the hub tells its runtime about, so an operator can find out it happened. */
25
+ /** Runtime hooks for stream diagnostics and membership checks. */
24
26
  export interface EventHubObserver {
27
+ /** A false result or failed lookup ends the stream. */
28
+ revalidate?(matchId: string, playerId: string): Promise<boolean>;
25
29
  /** A stored event a stream had to skip because this build cannot read it. */
26
30
  unreadable?(matchId: string, seq: number): void;
27
31
  /**
@@ -51,6 +55,9 @@ export declare class LocalEventHub implements EventNotifier, EventStreamOpener,
51
55
  */
52
56
  private readonly logs;
53
57
  private open_;
58
+ private lobbyOpen_;
59
+ /** The share of `perProcess` lobby streams may hold; see `makeRoom`. */
60
+ private readonly lobbyCap;
54
61
  constructor(events: EventRepository, heartbeatMs: number, limits?: EventHubLimits, observer?: EventHubObserver);
55
62
  notify(event: PersistedEvent): Promise<void>;
56
63
  /** Wake every stream of a match; used when the notification arrives without the event body. */
@@ -58,9 +65,9 @@ export declare class LocalEventHub implements EventNotifier, EventStreamOpener,
58
65
  /**
59
66
  * End every stream a membership holds.
60
67
  *
61
- * Revoking a token stops the next request; a stream that is already open is never authenticated
62
- * again, so without this a kicked player keeps being handed every sealed set, every desync report
63
- * (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.
64
71
  */
65
72
  close(input: {
66
73
  matchId: string;
@@ -83,11 +90,14 @@ export declare class LocalEventHub implements EventNotifier, EventStreamOpener,
83
90
  playerId: string;
84
91
  afterSeq: number;
85
92
  signal: AbortSignal;
93
+ lobby?: boolean;
86
94
  }): Promise<Response>;
87
95
  private logOf;
88
96
  private subscribe;
97
+ /** Stop charging a stream to the lobby share once its match is running. */
98
+ private releaseLobby;
89
99
  /**
90
- * Enforce the three caps before a stream is built.
100
+ * Enforce the stream caps before a stream is built.
91
101
  *
92
102
  * The caller's own stale streams are closed FIRST, before either ceiling is read. Closing them is
93
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;AAED,qFAAqF;AACrF,MAAM,WAAW,gBAAgB;IAC/B,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;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,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAf3B,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,EACjD,QAAQ,GAAE,gBAAqB,EAC9C;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,CAuBpB;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"}
@@ -26,13 +26,24 @@ export class LocalEventHub {
26
26
  */
27
27
  logs = new Map();
28
28
  open_ = 0;
29
+ lobbyOpen_ = 0;
30
+ /** The share of `perProcess` lobby streams may hold; see `makeRoom`. */
31
+ lobbyCap;
29
32
  constructor(events, heartbeatMs, limits = DEFAULT_EVENT_HUB_LIMITS, observer = {}) {
30
33
  this.events = events;
31
34
  this.heartbeatMs = heartbeatMs;
32
35
  this.limits = limits;
33
36
  this.observer = observer;
37
+ this.lobbyCap = Math.max(1, Math.floor(limits.perProcess / 4));
34
38
  }
35
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
+ }
36
47
  // The notification carries the durable row, so its frame is formatted once here and every
37
48
  // stream one event behind — which is every healthy stream of the match — is served from it
38
49
  // without reading anything. See `MatchLog`.
@@ -49,9 +60,9 @@ export class LocalEventHub {
49
60
  /**
50
61
  * End every stream a membership holds.
51
62
  *
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.
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.
55
66
  */
56
67
  async close(input) {
57
68
  // Snapshot deliberately: `close()` removes the subscription from the set being walked.
@@ -93,17 +104,32 @@ export class LocalEventHub {
93
104
  this.observer.abandoned?.(input.matchId, input.playerId);
94
105
  return abandonedSseResponse();
95
106
  }
96
- this.makeRoom(input.matchId, input.playerId);
107
+ const lobby = input.lobby === true;
108
+ this.makeRoom(input.matchId, input.playerId, lobby);
97
109
  const log = this.logOf(input.matchId);
110
+ let subscription;
111
+ const revalidate = this.observer.revalidate;
98
112
  return createSseResponse({
99
- 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
+ },
100
122
  caughtUp: (lastSeq) => log.caughtUp(lastSeq),
101
- 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
+ },
102
127
  }, {
103
128
  afterSeq: input.afterSeq,
104
129
  heartbeatMs: this.heartbeatMs,
105
130
  signal: input.signal,
106
131
  onUnreadable: (seq) => this.observer.unreadable?.(input.matchId, seq),
132
+ ...(revalidate ? { revalidate: () => revalidate(input.matchId, input.playerId) } : {}),
107
133
  });
108
134
  }
109
135
  logOf(matchId) {
@@ -114,16 +140,19 @@ export class LocalEventHub {
114
140
  this.logs.set(matchId, log);
115
141
  return log;
116
142
  }
117
- subscribe(matchId, playerId, wake, close) {
143
+ subscribe(matchId, subscription) {
118
144
  const set = this.listeners.get(matchId) ?? new Set();
119
- const subscription = { playerId, wake, close };
120
145
  set.add(subscription);
121
146
  this.listeners.set(matchId, set);
122
147
  this.open_ += 1;
148
+ if (subscription.lobby)
149
+ this.lobbyOpen_ += 1;
123
150
  return () => {
124
151
  if (!set.delete(subscription))
125
152
  return;
126
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);
127
156
  if (set.size === 0) {
128
157
  this.listeners.delete(matchId);
129
158
  // Nothing reads this match any more, so its frames are only memory. The next stream of it
@@ -132,8 +161,15 @@ export class LocalEventHub {
132
161
  }
133
162
  };
134
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
+ }
135
171
  /**
136
- * Enforce the three caps before a stream is built.
172
+ * Enforce the stream caps before a stream is built.
137
173
  *
138
174
  * The caller's own stale streams are closed FIRST, before either ceiling is read. Closing them is
139
175
  * not a concession to the caller, it is bookkeeping: a reconnect whose predecessor has not
@@ -145,7 +181,7 @@ export class LocalEventHub {
145
181
  * `perMatch` and `perProcess` then refuse whatever is still over, which is the case no client can
146
182
  * talk its way past.
147
183
  */
148
- makeRoom(matchId, playerId) {
184
+ makeRoom(matchId, playerId, lobby) {
149
185
  const set = this.listeners.get(matchId);
150
186
  if (set) {
151
187
  const mine = [...set].filter((subscription) => subscription.playerId === playerId);
@@ -158,6 +194,16 @@ export class LocalEventHub {
158
194
  scope: 'process',
159
195
  });
160
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
+ }
161
207
  if ((this.listeners.get(matchId)?.size ?? 0) >= this.limits.perMatch) {
162
208
  throw new RateLimitedError('This match is holding as many event streams as it can', {
163
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.
@@ -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;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"}
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"}
@@ -149,6 +149,7 @@ export function createSseResponse(source, options) {
149
149
  });
150
150
  let beats = 0;
151
151
  let stalledBeats = 0;
152
+ let validating = false;
152
153
  const heartbeat = setInterval(() => {
153
154
  // A consumer that is not reading is not a consumer. The queue is full, so this frame
154
155
  // would only buffer; after a few beats of that the connection is gone in every way that
@@ -167,6 +168,27 @@ export function createSseResponse(source, options) {
167
168
  // idle server was otherwise issuing one query per stream per heartbeat to find nothing.
168
169
  beats += 1;
169
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.
170
192
  if (overdue || !source.caughtUp(lastSeq))
171
193
  wake(overdue);
172
194
  }, options.heartbeatMs);
@@ -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.1",
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.1",
52
- "@chaos-overlords/contracts": "0.9.1",
53
- "@chaos-overlords/kernel": "0.9.1",
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.1",
59
+ "@chaos-overlords/conformance": "0.9.2",
60
60
  "typescript": "^7.0.2",
61
61
  "vitest": "^4.1.11"
62
62
  },