@chaos-overlords/kernel 0.9.0 → 0.9.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/logic/canonical-json.js +33 -5
- package/dist/logic/canonical-json.js.map +1 -1
- package/dist/services/RateLimiter.d.ts +27 -5
- package/dist/services/RateLimiter.d.ts.map +1 -1
- package/dist/services/RateLimiter.js +45 -14
- package/dist/services/RateLimiter.js.map +1 -1
- package/package.json +2 -2
|
@@ -20,25 +20,53 @@ export class NonCanonicalValueError extends Error {
|
|
|
20
20
|
this.name = 'NonCanonicalValueError';
|
|
21
21
|
}
|
|
22
22
|
}
|
|
23
|
-
function canonicalize(value, path =
|
|
23
|
+
function canonicalize(value, path = []) {
|
|
24
24
|
if (value === null || typeof value === 'boolean' || typeof value === 'string')
|
|
25
25
|
return value;
|
|
26
26
|
if (typeof value === 'number') {
|
|
27
27
|
if (!Number.isSafeInteger(value) || Object.is(value, -0)) {
|
|
28
|
-
throw new NonCanonicalValueError(path, `${value} is not a safe non-negative-zero integer`);
|
|
28
|
+
throw new NonCanonicalValueError(describe(path), `${value} is not a safe non-negative-zero integer`);
|
|
29
29
|
}
|
|
30
30
|
return value;
|
|
31
31
|
}
|
|
32
32
|
if (Array.isArray(value))
|
|
33
|
-
return value.map((item, index) =>
|
|
33
|
+
return value.map((item, index) => descend(path, index, item));
|
|
34
34
|
if (typeof value === 'object') {
|
|
35
35
|
const source = value;
|
|
36
36
|
const sorted = {};
|
|
37
37
|
for (const key of Object.keys(source).sort()) {
|
|
38
|
-
sorted[key] =
|
|
38
|
+
sorted[key] = descend(path, key, source[key]);
|
|
39
39
|
}
|
|
40
40
|
return sorted;
|
|
41
41
|
}
|
|
42
|
-
throw new NonCanonicalValueError(path, `unsupported type ${typeof value}`);
|
|
42
|
+
throw new NonCanonicalValueError(describe(path), `unsupported type ${typeof value}`);
|
|
43
|
+
}
|
|
44
|
+
function descend(path, segment, value) {
|
|
45
|
+
path.push(segment);
|
|
46
|
+
try {
|
|
47
|
+
return canonicalize(value, path);
|
|
48
|
+
}
|
|
49
|
+
finally {
|
|
50
|
+
path.pop();
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Renders the accumulated segments the way the C# mirror's `path` parameter spells them
|
|
55
|
+
* (`CanonicalJson.WriteObject`/`WriteArray`): an index is always `[n]`, and a key is dotted unless
|
|
56
|
+
* nothing has been rendered yet. The emptiness of what came before decides the dot, not the
|
|
57
|
+
* segment's position -- an empty-string key renders as nothing, so `{ '': { y: 1.5 } }` reports
|
|
58
|
+
* `y` rather than `.y`, matching both the mirror and the string-building version this replaced.
|
|
59
|
+
*
|
|
60
|
+
* Only a throw reaches here, so the allocation is off the hot path.
|
|
61
|
+
*/
|
|
62
|
+
function describe(path) {
|
|
63
|
+
let rendered = '';
|
|
64
|
+
for (const segment of path) {
|
|
65
|
+
if (typeof segment === 'number')
|
|
66
|
+
rendered += `[${segment}]`;
|
|
67
|
+
else
|
|
68
|
+
rendered += rendered.length === 0 ? segment : `.${segment}`;
|
|
69
|
+
}
|
|
70
|
+
return rendered;
|
|
43
71
|
}
|
|
44
72
|
//# sourceMappingURL=canonical-json.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"canonical-json.js","sourceRoot":"","sources":["../../src/logic/canonical-json.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,MAAM,UAAU,aAAa,CAAC,KAAc;IAC1C,OAAO,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,CAAA;AAC5C,CAAC;AAED,MAAM,OAAO,sBAAuB,SAAQ,KAAK;IAEpC,IAAI;IADf,YACW,IAAY,EACrB,MAAc;QAEd,KAAK,CAAC,uBAAuB,IAAI,IAAI,OAAO,KAAK,MAAM,EAAE,CAAC,CAAA;oBAHjD,IAAI;QAIb,IAAI,CAAC,IAAI,GAAG,wBAAwB,CAAA;IACtC,CAAC;CACF;
|
|
1
|
+
{"version":3,"file":"canonical-json.js","sourceRoot":"","sources":["../../src/logic/canonical-json.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,MAAM,UAAU,aAAa,CAAC,KAAc;IAC1C,OAAO,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,CAAA;AAC5C,CAAC;AAED,MAAM,OAAO,sBAAuB,SAAQ,KAAK;IAEpC,IAAI;IADf,YACW,IAAY,EACrB,MAAc;QAEd,KAAK,CAAC,uBAAuB,IAAI,IAAI,OAAO,KAAK,MAAM,EAAE,CAAC,CAAA;oBAHjD,IAAI;QAIb,IAAI,CAAC,IAAI,GAAG,wBAAwB,CAAA;IACtC,CAAC;CACF;AAID,SAAS,YAAY,CAAC,KAAc,EAAE,IAAI,GAAkB,EAAE;IAC5D,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,SAAS,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAA;IAC3F,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACzD,MAAM,IAAI,sBAAsB,CAC9B,QAAQ,CAAC,IAAI,CAAC,EACd,GAAG,KAAK,0CAA0C,CACnD,CAAA;QACH,CAAC;QACD,OAAO,KAAK,CAAA;IACd,CAAC;IACD,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC,CAAA;IACvF,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,MAAM,MAAM,GAAG,KAAgC,CAAA;QAC/C,MAAM,MAAM,GAA4B,EAAE,CAAA;QAC1C,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC;YAC7C,MAAM,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,IAAI,EAAE,GAAG,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAA;QAC/C,CAAC;QACD,OAAO,MAAM,CAAA;IACf,CAAC;IACD,MAAM,IAAI,sBAAsB,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,oBAAoB,OAAO,KAAK,EAAE,CAAC,CAAA;AACtF,CAAC;AAED,SAAS,OAAO,CAAC,IAAmB,EAAE,OAAoB,EAAE,KAAc;IACxE,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;IAClB,IAAI,CAAC;QACH,OAAO,YAAY,CAAC,KAAK,EAAE,IAAI,CAAC,CAAA;IAClC,CAAC;YAAS,CAAC;QACT,IAAI,CAAC,GAAG,EAAE,CAAA;IACZ,CAAC;AACH,CAAC;AAED;;;;;;;;GAQG;AACH,SAAS,QAAQ,CAAC,IAA4B;IAC5C,IAAI,QAAQ,GAAG,EAAE,CAAA;IACjB,KAAK,MAAM,OAAO,IAAI,IAAI,EAAE,CAAC;QAC3B,IAAI,OAAO,OAAO,KAAK,QAAQ;YAAE,QAAQ,IAAI,IAAI,OAAO,GAAG,CAAA;;YACtD,QAAQ,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,OAAO,EAAE,CAAA;IAClE,CAAC;IACD,OAAO,QAAQ,CAAA;AACjB,CAAC"}
|
|
@@ -1,4 +1,10 @@
|
|
|
1
1
|
import type { Clock } from '../ports/runtime';
|
|
2
|
+
export interface RateLimiterOptions {
|
|
3
|
+
limit: number;
|
|
4
|
+
windowMs: number;
|
|
5
|
+
/** Residency bound; defaults to {@link DEFAULT_MAX_KEYS}. */
|
|
6
|
+
maxKeys?: number;
|
|
7
|
+
}
|
|
2
8
|
/**
|
|
3
9
|
* Fixed-window counter per key, in memory. It protects the unauthenticated doors (create, join)
|
|
4
10
|
* from brute force on one process; a horizontally scaled deployment puts a shared limiter (a WAF
|
|
@@ -8,19 +14,35 @@ export declare class RateLimiter {
|
|
|
8
14
|
private readonly clock;
|
|
9
15
|
private readonly options;
|
|
10
16
|
private readonly windows;
|
|
17
|
+
private readonly maxKeys;
|
|
11
18
|
private lastPrune;
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
});
|
|
19
|
+
private lastWall;
|
|
20
|
+
private elapsed;
|
|
21
|
+
constructor(clock: Clock, options: RateLimiterOptions);
|
|
16
22
|
/** Returns the retry delay in seconds when over the limit, or null when the call is allowed. */
|
|
17
23
|
take(key: string): number | null;
|
|
18
24
|
/** What `take` would answer right now, spending nothing. */
|
|
19
25
|
peek(key: string): number | null;
|
|
20
26
|
/** How much of `key`'s budget the current window has already spent; 0 once it has rolled. */
|
|
21
27
|
spent(key: string): number;
|
|
22
|
-
/**
|
|
28
|
+
/**
|
|
29
|
+
* Milliseconds on a clock that only moves forward, accumulated from the wall clock's forward steps.
|
|
30
|
+
*
|
|
31
|
+
* Production passes the wall clock, which NTP can step backwards. Measured directly, a step back
|
|
32
|
+
* would give new windows an earlier start than older ones already at the head, breaking the
|
|
33
|
+
* eviction order, and make elapsed time negative, keeping spent windows alive past `windowMs`.
|
|
34
|
+
* A backward step here just pauses the limiter's time until the wall clock moves forward again.
|
|
35
|
+
*/
|
|
36
|
+
private tick;
|
|
37
|
+
/**
|
|
38
|
+
* The window `key` is spending from, or undefined once it has rolled or was never opened.
|
|
39
|
+
*
|
|
40
|
+
* A rolled window is removed here rather than overwritten later: Map#set keeps an existing key's
|
|
41
|
+
* insertion position, so overwriting would leave a fresh, possibly spent window at the head, first
|
|
42
|
+
* in line for eviction.
|
|
43
|
+
*/
|
|
23
44
|
private live;
|
|
45
|
+
private expired;
|
|
24
46
|
/** Whole seconds until `entry`'s window rolls, rounded up. */
|
|
25
47
|
private retryAfter;
|
|
26
48
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RateLimiter.d.ts","sourceRoot":"","sources":["../../src/services/RateLimiter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAA;
|
|
1
|
+
{"version":3,"file":"RateLimiter.d.ts","sourceRoot":"","sources":["../../src/services/RateLimiter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAA;AAe7C,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,EAAE,MAAM,CAAA;IAChB,6DAA6D;IAC7D,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAOD;;;;GAIG;AACH,qBAAa,WAAW;IAQpB,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAR1B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAiC;IACzD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAQ;IAChC,OAAO,CAAC,SAAS,CAA2B;IAC5C,OAAO,CAAC,QAAQ,CAAa;IAC7B,OAAO,CAAC,OAAO,CAAI;IAEnB,YACmB,KAAK,EAAE,KAAK,EACZ,OAAO,EAAE,kBAAkB,EAG7C;IAED,gGAAgG;IAChG,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAa/B;IAED,4DAA4D;IAC5D,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAK/B;IAED,6FAA6F;IAC7F,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAEzB;IAED;;;;;;;OAOG;IACH,OAAO,CAAC,IAAI;IAOZ;;;;;;OAMG;IACH,OAAO,CAAC,IAAI;IAOZ,OAAO,CAAC,OAAO;IAIf,8DAA8D;IAC9D,OAAO,CAAC,UAAU;IAIlB;;;;;;;OAOG;IACH,OAAO,CAAC,KAAK;IAQb,0FAA0F;IAC1F,OAAO,CAAC,WAAW;CAOpB"}
|
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* How many distinct keys one limiter holds before the oldest are dropped.
|
|
2
|
+
* How many distinct keys one limiter holds by default before the oldest are dropped.
|
|
3
3
|
*
|
|
4
4
|
* `prune` only collects windows that have EXPIRED, at most once per window period, which is right
|
|
5
5
|
* for a minute-long window and wrong for a day-long one: the bug-report budget's window is
|
|
6
6
|
* twenty-four hours, so every address that ever posted stayed resident for a day or two on an
|
|
7
|
-
* unauthenticated route.
|
|
8
|
-
*
|
|
9
|
-
*
|
|
7
|
+
* unauthenticated route. The Map iterates in window-start order — windows open on a clock that
|
|
8
|
+
* never runs backwards, and a rolled window is removed before it reopens at the tail — so the head
|
|
9
|
+
* is the oldest window and evicting from there is one shift. Dropping a live window forgives that
|
|
10
|
+
* key's remaining budget, which is the safe direction to fail on a memory bound.
|
|
10
11
|
*/
|
|
11
|
-
const
|
|
12
|
+
const DEFAULT_MAX_KEYS = 50_000;
|
|
12
13
|
/**
|
|
13
14
|
* Fixed-window counter per key, in memory. It protects the unauthenticated doors (create, join)
|
|
14
15
|
* from brute force on one process; a horizontally scaled deployment puts a shared limiter (a WAF
|
|
@@ -18,16 +19,21 @@ export class RateLimiter {
|
|
|
18
19
|
clock;
|
|
19
20
|
options;
|
|
20
21
|
windows = new Map();
|
|
22
|
+
maxKeys;
|
|
21
23
|
lastPrune = Number.NEGATIVE_INFINITY;
|
|
24
|
+
lastWall = Number.NaN;
|
|
25
|
+
elapsed = 0;
|
|
22
26
|
constructor(clock, options) {
|
|
23
27
|
this.clock = clock;
|
|
24
28
|
this.options = options;
|
|
29
|
+
this.maxKeys = options.maxKeys ?? DEFAULT_MAX_KEYS;
|
|
25
30
|
}
|
|
26
31
|
/** Returns the retry delay in seconds when over the limit, or null when the call is allowed. */
|
|
27
32
|
take(key) {
|
|
28
|
-
const now = this.
|
|
33
|
+
const now = this.tick();
|
|
29
34
|
const entry = this.live(key, now);
|
|
30
35
|
if (!entry) {
|
|
36
|
+
// `live` removed any rolled window, so this appends at the tail and keeps the Map ordered.
|
|
31
37
|
this.windows.set(key, { windowStart: now, count: 1 });
|
|
32
38
|
this.prune(now);
|
|
33
39
|
this.evictOldest();
|
|
@@ -40,7 +46,7 @@ export class RateLimiter {
|
|
|
40
46
|
}
|
|
41
47
|
/** What `take` would answer right now, spending nothing. */
|
|
42
48
|
peek(key) {
|
|
43
|
-
const now = this.
|
|
49
|
+
const now = this.tick();
|
|
44
50
|
const entry = this.live(key, now);
|
|
45
51
|
if (!entry || entry.count < this.options.limit)
|
|
46
52
|
return null;
|
|
@@ -48,14 +54,39 @@ export class RateLimiter {
|
|
|
48
54
|
}
|
|
49
55
|
/** How much of `key`'s budget the current window has already spent; 0 once it has rolled. */
|
|
50
56
|
spent(key) {
|
|
51
|
-
return this.live(key, this.
|
|
57
|
+
return this.live(key, this.tick())?.count ?? 0;
|
|
52
58
|
}
|
|
53
|
-
/**
|
|
59
|
+
/**
|
|
60
|
+
* Milliseconds on a clock that only moves forward, accumulated from the wall clock's forward steps.
|
|
61
|
+
*
|
|
62
|
+
* Production passes the wall clock, which NTP can step backwards. Measured directly, a step back
|
|
63
|
+
* would give new windows an earlier start than older ones already at the head, breaking the
|
|
64
|
+
* eviction order, and make elapsed time negative, keeping spent windows alive past `windowMs`.
|
|
65
|
+
* A backward step here just pauses the limiter's time until the wall clock moves forward again.
|
|
66
|
+
*/
|
|
67
|
+
tick() {
|
|
68
|
+
const wall = this.clock.now().getTime();
|
|
69
|
+
if (wall > this.lastWall)
|
|
70
|
+
this.elapsed += wall - this.lastWall;
|
|
71
|
+
this.lastWall = wall;
|
|
72
|
+
return this.elapsed;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* The window `key` is spending from, or undefined once it has rolled or was never opened.
|
|
76
|
+
*
|
|
77
|
+
* A rolled window is removed here rather than overwritten later: Map#set keeps an existing key's
|
|
78
|
+
* insertion position, so overwriting would leave a fresh, possibly spent window at the head, first
|
|
79
|
+
* in line for eviction.
|
|
80
|
+
*/
|
|
54
81
|
live(key, now) {
|
|
55
82
|
const entry = this.windows.get(key);
|
|
56
|
-
if (!entry ||
|
|
57
|
-
return
|
|
58
|
-
|
|
83
|
+
if (!entry || !this.expired(entry, now))
|
|
84
|
+
return entry;
|
|
85
|
+
this.windows.delete(key);
|
|
86
|
+
return undefined;
|
|
87
|
+
}
|
|
88
|
+
expired(entry, now) {
|
|
89
|
+
return now - entry.windowStart >= this.options.windowMs;
|
|
59
90
|
}
|
|
60
91
|
/** Whole seconds until `entry`'s window rolls, rounded up. */
|
|
61
92
|
retryAfter(entry, now) {
|
|
@@ -74,13 +105,13 @@ export class RateLimiter {
|
|
|
74
105
|
return;
|
|
75
106
|
this.lastPrune = now;
|
|
76
107
|
for (const [key, entry] of this.windows) {
|
|
77
|
-
if (
|
|
108
|
+
if (this.expired(entry, now))
|
|
78
109
|
this.windows.delete(key);
|
|
79
110
|
}
|
|
80
111
|
}
|
|
81
112
|
/** Hard bound on residency, for windows too long for `prune` to be the only collector. */
|
|
82
113
|
evictOldest() {
|
|
83
|
-
while (this.windows.size >
|
|
114
|
+
while (this.windows.size > this.maxKeys) {
|
|
84
115
|
const oldest = this.windows.keys().next();
|
|
85
116
|
if (oldest.done)
|
|
86
117
|
return;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RateLimiter.js","sourceRoot":"","sources":["../../src/services/RateLimiter.ts"],"names":[],"mappings":"AAEA
|
|
1
|
+
{"version":3,"file":"RateLimiter.js","sourceRoot":"","sources":["../../src/services/RateLimiter.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@chaos-overlords/kernel",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.1",
|
|
4
4
|
"description": "Runtime-neutral domain of the multiplayer server: entities, ports, pure turn logic and the lobby/turn/snapshot services.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"chaos-overlords",
|
|
@@ -52,7 +52,7 @@
|
|
|
52
52
|
"provenance": true
|
|
53
53
|
},
|
|
54
54
|
"dependencies": {
|
|
55
|
-
"@chaos-overlords/contracts": "0.9.
|
|
55
|
+
"@chaos-overlords/contracts": "0.9.1"
|
|
56
56
|
},
|
|
57
57
|
"devDependencies": {
|
|
58
58
|
"typescript": "^7.0.2",
|