@mark1russell7/service 0.5.2 → 0.5.4
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/README.md +68 -0
- package/build/{builder-BzjhWk2E.d.ts → builder-DyDB7zM9.d.ts} +9 -2
- package/build/http.d.ts +9 -1
- package/build/http.js +25 -1
- package/build/http.js.map +1 -1
- package/build/index.d.ts +31 -8
- package/build/index.js +117 -5
- package/build/index.js.map +1 -1
- package/build/{lifecycle-DjEpgpRk.d.ts → lifecycle-Chu9Pri2.d.ts} +7 -1
- package/build/limiter-wv0uXDk9.js +126 -0
- package/build/limiter-wv0uXDk9.js.map +1 -0
- package/build/limiter.d.ts +3 -0
- package/build/limiter.js +3 -0
- package/build/policy-CgS4y94U.js +187 -0
- package/build/policy-CgS4y94U.js.map +1 -0
- package/build/policy-G4QJ1ZZq.d.ts +176 -0
- package/build/redis.d.ts +43 -3
- package/build/redis.js +154 -1
- package/build/redis.js.map +1 -1
- package/build/store-DzTyosou.d.ts +72 -0
- package/build/testing.d.ts +2 -2
- package/package.json +9 -4
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { n as Clock } from "./clock-D-38uH_z.js";
|
|
2
|
+
import { a as LimitRule, c as LimiterSpec, n as Decision } from "./policy-G4QJ1ZZq.js";
|
|
3
|
+
//#region src/limiter/store.d.ts
|
|
4
|
+
/** A take request is one take of one key, with the rule and the cap of its limiter in numbers. */
|
|
5
|
+
interface TakeRequest {
|
|
6
|
+
/** This name is the limiter. A store keeps the keys of each limiter apart. */
|
|
7
|
+
readonly limiter: string;
|
|
8
|
+
readonly key: string;
|
|
9
|
+
readonly rule: LimitRule;
|
|
10
|
+
/** This count is the most keys that the store holds for the limiter. */
|
|
11
|
+
readonly maxKeys: number;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* A limiter store keeps the state of each key, and it decides each take in one atomic step, on its
|
|
15
|
+
* own clock. Thus two takes of one key do not read the same state at any time. A store in this
|
|
16
|
+
* process uses `decide`. A store that the replicas share does the same arithmetic in one step of its
|
|
17
|
+
* own, for example one script of Redis that reads `TIME`.
|
|
18
|
+
*/
|
|
19
|
+
interface LimiterStore {
|
|
20
|
+
/** This kind tells where the counts are: in the memory of this replica, or in a store that the replicas share. */
|
|
21
|
+
readonly kind: "local" | "shared";
|
|
22
|
+
/**
|
|
23
|
+
* This method decides one take. It removes a key only when its state is equal to the state of a
|
|
24
|
+
* new key. It holds at most `maxKeys` keys for each limiter. A failure of a shared store rejects
|
|
25
|
+
* the take, and the limiter then applies the `onStoreFailure` of its spec.
|
|
26
|
+
*/
|
|
27
|
+
take(request: TakeRequest): Decision | Promise<Decision>;
|
|
28
|
+
}
|
|
29
|
+
/** A memory store is the store of one replica, on the injected monotonic clock. */
|
|
30
|
+
interface MemoryStore extends LimiterStore {
|
|
31
|
+
readonly kind: "local";
|
|
32
|
+
/** This method gives the count of keys that the store holds for a limiter. */
|
|
33
|
+
size(limiter: string): number;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* This function makes the store of one replica. It reads time only through the clock. Thus a step
|
|
37
|
+
* of the wall clock does not move a count, and a fake clock gives exact decisions in a test.
|
|
38
|
+
* - The eviction is exact. A key whose bucket is full again, or whose window has no take, is equal
|
|
39
|
+
* to a new key. The store removes it at its next take, or at a sweep.
|
|
40
|
+
* - The count of keys has a bound. At the cap, a take of a new key sweeps the table, but only when
|
|
41
|
+
* a held key can be free. Each sweep reads each key one time. When no key is free, the store
|
|
42
|
+
* refuses the new key with the cause `cap`. Its `retryAfter` is at most the time until the
|
|
43
|
+
* earliest held key is free, and that time is at most `idleSpan` of the policy.
|
|
44
|
+
*/
|
|
45
|
+
declare const memoryStore: (clock: Clock) => MemoryStore;
|
|
46
|
+
/** A keyed limiter is the runtime of one declared limiter: its spec, its rule in numbers, and its store. */
|
|
47
|
+
interface KeyedLimiter {
|
|
48
|
+
readonly name: string;
|
|
49
|
+
/** This spec is the declaration, the same data that `svc.limiter(name, spec)` takes and `describe()` shows. */
|
|
50
|
+
readonly spec: LimiterSpec;
|
|
51
|
+
readonly rule: LimitRule;
|
|
52
|
+
/** This count is the most keys that the store holds for the limiter. */
|
|
53
|
+
readonly maxKeys: number;
|
|
54
|
+
/**
|
|
55
|
+
* This method takes one unit for a key, and gives the decision of the store. When a shared store
|
|
56
|
+
* fails, it gives the decision of `onStoreFailure`, with the failure as text.
|
|
57
|
+
*/
|
|
58
|
+
take(key: string): Promise<Decision>;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* This function makes the runtime of a limiter from its spec and its store. It refuses a spec with a
|
|
62
|
+
* problem, because the limiter has no defaults. It also refuses a store of the wrong kind: a spec
|
|
63
|
+
* with a shared store needs a store that the replicas share.
|
|
64
|
+
* - A failure of a shared store gives the decision of `onStoreFailure`. With `open`, the take is
|
|
65
|
+
* permitted with `remaining` 0. With `closed`, it is refused with the cause `store`.
|
|
66
|
+
* - The `retryAfter` of the cause `store` is the longest `retryAfter` of the policy.
|
|
67
|
+
* - A failure of a local store rejects the take, because a local store has no `onStoreFailure`.
|
|
68
|
+
*/
|
|
69
|
+
declare const keyedLimiter: (name: string, spec: LimiterSpec, store: LimiterStore) => KeyedLimiter;
|
|
70
|
+
//#endregion
|
|
71
|
+
export { keyedLimiter as a, TakeRequest as i, LimiterStore as n, memoryStore as o, MemoryStore as r, KeyedLimiter as t };
|
|
72
|
+
//# sourceMappingURL=store-DzTyosou.d.ts.map
|
package/build/testing.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { n as Clock } from "./clock-D-38uH_z.js";
|
|
2
|
-
import { D as Outcome, E as CheckFn, ct as ExitTrigger, d as TransportImpl, pt as ProcessPort, r as Lifecycle, st as ExitSignal } from "./lifecycle-
|
|
3
|
-
import { n as ServiceBuilder } from "./builder-
|
|
2
|
+
import { D as Outcome, E as CheckFn, ct as ExitTrigger, d as TransportImpl, pt as ProcessPort, r as Lifecycle, st as ExitSignal } from "./lifecycle-Chu9Pri2.js";
|
|
3
|
+
import { n as ServiceBuilder } from "./builder-DyDB7zM9.js";
|
|
4
4
|
//#region src/fakes.d.ts
|
|
5
5
|
/** A fake clock moves only when a test tells it to. */
|
|
6
6
|
interface FakeClock extends Clock {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://json.schemastore.org/package",
|
|
3
3
|
"name": "@mark1russell7/service",
|
|
4
|
-
"version": "0.5.
|
|
4
|
+
"version": "0.5.4",
|
|
5
5
|
"description": "A service declared as data before it starts, and its runtime: checks on jittered loops, a latch for each policy, probes from the cache, the startup in its sequence, and a staged, capped drain. The timer-ordering law checks the declaration. Its clock, heartbeat and backoff also work alone, in a browser too.",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"service",
|
|
@@ -11,7 +11,8 @@
|
|
|
11
11
|
"graceful-shutdown",
|
|
12
12
|
"idempotency",
|
|
13
13
|
"timeouts",
|
|
14
|
-
"kubernetes"
|
|
14
|
+
"kubernetes",
|
|
15
|
+
"rate-limit"
|
|
15
16
|
],
|
|
16
17
|
"homepage": "https://mark1russell7.github.io/systems/",
|
|
17
18
|
"repository": {
|
|
@@ -57,6 +58,10 @@
|
|
|
57
58
|
"types": "./build/http.d.ts",
|
|
58
59
|
"default": "./build/http.js"
|
|
59
60
|
},
|
|
61
|
+
"./limiter": {
|
|
62
|
+
"types": "./build/limiter.d.ts",
|
|
63
|
+
"default": "./build/limiter.js"
|
|
64
|
+
},
|
|
60
65
|
"./package.json": "./package.json"
|
|
61
66
|
},
|
|
62
67
|
"files": [
|
|
@@ -68,7 +73,7 @@
|
|
|
68
73
|
"node": ">=22.19"
|
|
69
74
|
},
|
|
70
75
|
"dependencies": {
|
|
71
|
-
"@mark1russell7/algebra": "^0.7.
|
|
76
|
+
"@mark1russell7/algebra": "^0.7.2",
|
|
72
77
|
"@mark1russell7/quantity": "^0.2.0"
|
|
73
78
|
},
|
|
74
79
|
"peerDependencies": {
|
|
@@ -85,7 +90,7 @@
|
|
|
85
90
|
},
|
|
86
91
|
"devDependencies": {
|
|
87
92
|
"@mark1russell7/cue": "github:mark1russell7/cue",
|
|
88
|
-
"@mark1russell7/harness": "^0.11.
|
|
93
|
+
"@mark1russell7/harness": "^0.11.18",
|
|
89
94
|
"@types/node": "^26.6.4",
|
|
90
95
|
"ioredis": "6.0.0",
|
|
91
96
|
"testcontainers": "12.2.0",
|