@procedures/peer 0.14.1 → 0.15.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/CHANGELOG.md CHANGED
@@ -1,5 +1,67 @@
1
1
  # @procedures/peer
2
2
 
3
+ ## 0.15.1
4
+
5
+ ### Patch Changes
6
+
7
+ - c78da2d: The procedures server can limit the calls of each principal, tenant or route (server stack CLI-40). This change is additive. Without the new option, nothing changes. Thus it is a PATCH of the client group (decision D13).
8
+
9
+ The new behavior:
10
+
11
+ - `hostPolicy()` and `ProcedureServer` of `@procedures/client` have the new option `limits`. Each limit has a name, a key over the call, the calls that it covers, a limit policy, a store and a bound on its keys.
12
+ - The key is the principal, a claim of the principal (`{ claim: "tenant" }`), the route, a list of these, or a function of the call. A call without a value of its key is outside the limit.
13
+ - The option `covers` takes `{ writes: true }` for only the calls that can change data, `{ routes: [...] }` for some procedures, or a function of the call.
14
+ - Each limit is a keyed limiter of `@mark1russell7/service/limiter` (SYS-28) on the clock of the server. The option `limitStores` gives the stores that the replicas share.
15
+ - The server takes one unit of each limit that covers a call, after the authentication and before the run. This is one step for each face: HTTP, WebSocket, MCP and the calls in the process.
16
+ - A call above a limit gets the new error code `RATE_LIMITED` (retryable). Its metadata has the wait in `retry-after` (milliseconds) and the cause in `reason` (`limit`, `cap` or `store`). The call does not run.
17
+ - HTTP gives 429 with `Retry-After` in whole seconds. WebSocket gives the same code and metadata. MCP gives the code, `reason` and `retryAfterMs` in `_meta`.
18
+ - A circuit breaker does not count `RATE_LIMITED`, because the server is healthy.
19
+ - `createProcedureHost()` of `@procedures/peer` declares each limiter on its service with `svc.limiter()`. Thus `describe()` and `lint()` see it. `host.limiters` gives the limiters, and `ProcedureServer.limiters()` gives them too.
20
+ - The rate limit middleware of the client (`createRateLimitMiddleware`) uses the same keyed limiter. Its bucket, its queue and its statistics do not change. The new option `clock` gives the clock of the bucket and of the queue. The default is `Date.now()` and `setTimeout`, as before.
21
+ - The `Retry-After` header of the HTTP face rounds the wait up to whole seconds with the rule of `@mark1russell7/service`. A wait above a whole second only by an error of floating point does not add a second.
22
+ - The client packages use `@mark1russell7/service` 0.5.3 and `@mark1russell7/algebra` 0.7.2.
23
+
24
+ An example for the writes of each tenant:
25
+
26
+ ```ts
27
+ hostPolicy({
28
+ principalOf,
29
+ limits: [
30
+ {
31
+ name: "graph.writes",
32
+ key: { claim: "tenant" },
33
+ covers: { writes: true },
34
+ policy: { type: "sliding-window", limit: { value: 120, unit: "count" }, window: { value: 1, unit: "min" } },
35
+ store: { kind: "local" },
36
+ evict: { maxKeys: { value: 10000, unit: "count" } },
37
+ },
38
+ ],
39
+ });
40
+ ```
41
+ - 534e4ea: Fixed: `bearerOf` also reads the scheme of an `Authorization` header in another case (CLI-60). RFC 7235 makes the scheme case-insensitive, with one or more spaces (`1*SP`) before the token. Before, `bearerOf` read only a header that starts with `Bearer ` and one space, so a correct `bearer <token>` got 401.
42
+
43
+ Each header that `bearerOf` read before gives the same token. A correct header in another case passes too, also with more spaces before the token.
44
+
45
+ - A header that starts with `Bearer ` gives the rest of the header, as before.
46
+ - A header with the scheme in another case, for example `bearer` or `BEARER`, gives the token after one or more spaces. Spaces or tabs can come after the token. The token has no whitespace (`token68`).
47
+ - A tab between the scheme and the token is not `1*SP`, so it gives no token.
48
+ - `Basic x`, `Bearer` with no space and an empty header give no token, as before.
49
+ - The token comparison (`tokenMatches`) does not change.
50
+
51
+ Each user of `bearerOf` gets the change. These users are `credentialsOf`, `requestCredentials`, `procedureHandler` and the WebSocket server. The WebSocket admission of `createProcedureHost()`, `guardMcpRequest` and the credentials of the MCP face also get it.
52
+ - Updated dependencies [c78da2d]
53
+ - Updated dependencies [d99b2d5]
54
+ - Updated dependencies [534e4ea]
55
+ - Updated dependencies [44fdd60]
56
+ - @procedures/client@0.15.1
57
+
58
+ ## 0.15.0
59
+
60
+ ### Patch Changes
61
+
62
+ - Updated dependencies [c7198ca]
63
+ - @procedures/client@0.15.0
64
+
3
65
  ## 0.14.1
4
66
 
5
67
  ### Patch Changes