@procedures/client 0.14.0 → 0.14.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 +36 -0
- package/README.md +12 -3
- package/dist/.tsbuildinfo +1 -1
- package/dist/adapters/http/server/body.d.ts +17 -0
- package/dist/adapters/http/server/body.d.ts.map +1 -0
- package/dist/adapters/http/server/body.js +44 -0
- package/dist/adapters/http/server/body.js.map +1 -0
- package/dist/adapters/http/server/cors.d.ts +24 -1
- package/dist/adapters/http/server/cors.d.ts.map +1 -1
- package/dist/adapters/http/server/cors.js +33 -1
- package/dist/adapters/http/server/cors.js.map +1 -1
- package/dist/adapters/http/server/handler.d.ts +3 -1
- package/dist/adapters/http/server/handler.d.ts.map +1 -1
- package/dist/adapters/http/server/handler.js +4 -34
- package/dist/adapters/http/server/handler.js.map +1 -1
- package/dist/browser.d.ts +4 -3
- package/dist/browser.d.ts.map +1 -1
- package/dist/browser.js +4 -1
- package/dist/browser.js.map +1 -1
- package/dist/events/publisher.d.ts.map +1 -1
- package/dist/events/publisher.js +10 -5
- package/dist/events/publisher.js.map +1 -1
- package/dist/events/rows.d.ts +12 -4
- package/dist/events/rows.d.ts.map +1 -1
- package/dist/events/rows.js +13 -16
- package/dist/events/rows.js.map +1 -1
- package/dist/index.d.ts +5 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -2
- package/dist/index.js.map +1 -1
- package/dist/node.d.ts +10 -1
- package/dist/node.d.ts.map +1 -1
- package/dist/node.js +11 -0
- package/dist/node.js.map +1 -1
- package/dist/procedures/collection/admission.d.ts +77 -0
- package/dist/procedures/collection/admission.d.ts.map +1 -0
- package/dist/procedures/collection/admission.js +204 -0
- package/dist/procedures/collection/admission.js.map +1 -0
- package/dist/procedures/collection/changes.d.ts +3 -1
- package/dist/procedures/collection/changes.d.ts.map +1 -1
- package/dist/procedures/collection/changes.js +10 -6
- package/dist/procedures/collection/changes.js.map +1 -1
- package/dist/procedures/collection/index.d.ts +2 -0
- package/dist/procedures/collection/index.d.ts.map +1 -1
- package/dist/procedures/collection/index.js +2 -0
- package/dist/procedures/collection/index.js.map +1 -1
- package/dist/procedures/collection/patch-in-parts.d.ts +15 -0
- package/dist/procedures/collection/patch-in-parts.d.ts.map +1 -0
- package/dist/procedures/collection/patch-in-parts.js +47 -0
- package/dist/procedures/collection/patch-in-parts.js.map +1 -0
- package/dist/procedures/collection/procedures.d.ts +8 -0
- package/dist/procedures/collection/procedures.d.ts.map +1 -1
- package/dist/procedures/collection/procedures.js +54 -77
- package/dist/procedures/collection/procedures.js.map +1 -1
- package/dist/procedures/index.d.ts +2 -2
- package/dist/procedures/index.d.ts.map +1 -1
- package/dist/procedures/index.js +3 -1
- package/dist/procedures/index.js.map +1 -1
- package/dist/procedures/invoke.d.ts +5 -2
- package/dist/procedures/invoke.d.ts.map +1 -1
- package/dist/procedures/invoke.js +5 -1
- package/dist/procedures/invoke.js.map +1 -1
- package/dist/procedures/types.d.ts +7 -0
- package/dist/procedures/types.d.ts.map +1 -1
- package/dist/procedures/types.js.map +1 -1
- package/dist/server/index.d.ts +70 -5
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +26 -3
- package/dist/server/index.js.map +1 -1
- package/package.json +12 -1
- package/src/adapters/http/server/body.ts +43 -0
- package/src/adapters/http/server/cors.ts +42 -1
- package/src/adapters/http/server/handler.ts +7 -32
- package/src/browser.ts +9 -1
- package/src/events/publisher.ts +8 -5
- package/src/events/rows.ts +19 -6
- package/src/index.ts +9 -6
- package/src/node.ts +13 -1
- package/src/procedures/collection/admission.ts +243 -0
- package/src/procedures/collection/changes.ts +11 -5
- package/src/procedures/collection/index.ts +4 -0
- package/src/procedures/collection/patch-in-parts.ts +56 -0
- package/src/procedures/collection/procedures.ts +58 -80
- package/src/procedures/index.ts +7 -0
- package/src/procedures/invoke.ts +7 -2
- package/src/procedures/types.ts +8 -0
- package/src/server/index.ts +94 -17
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,41 @@
|
|
|
1
1
|
# @procedures/client
|
|
2
2
|
|
|
3
|
+
## 0.14.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 85999c1: MCP tasks and the guards of the HTTP face (CLI-35).
|
|
8
|
+
|
|
9
|
+
- A procedure with `metadata.taskSupport` (`"optional"` or `"required"`) can run as an MCP task. `@procedures/mcp` gives it in the tool definition as `execution.taskSupport`, and exports `taskSupportOf`.
|
|
10
|
+
- `createMcpHost` and `McpServerTransport` take the option `tasks`: a store (`McpTaskStore`), or the options of a new store (`maxRunning`, `ttl`). The host shares one store with each face, and `host.tasks` gives it. A task holds its place in the limit until its procedure returns, also after a cancel. A task above the limit starts and then fails at once with the reason, and the store keeps it for 1 minute. The time to keep a task starts when the task ends, and each session keeps at most 100 tasks. A cancel aborts `ctx.signal` of the procedure. The close of a session and the stop of the host cancel their tasks. Without the option `tasks`, the tools do not change.
|
|
11
|
+
- The checks of a request to the Streamable HTTP face are in one function, `guardMcpRequest`, with the browser checks and `tokenMatches` of the core. A 401 now has a `WWW-Authenticate` header. The package also exports `assertLoopbackBind`, for the owner of a listener.
|
|
12
|
+
- The HTTP face takes `allowedHosts`, `maxSessions` and `maxBodyBytes`. `createMcpHost` and `mcpFace` give the face `browser.allowedHosts` of the policy, so a host of that list can reach the endpoint. Before, the face refused it. Thus a policy with `allowedHosts: "*"` now also turns off the DNS-rebinding check of the face, as it does for the other faces.
|
|
13
|
+
- `maxSessions` has no default: the sessions have no limit, as before. With it, a new session above the limit closes the session that was idle longest (no task in progress and no open response), and when each session is busy, the new session gets 503 with `Retry-After`.
|
|
14
|
+
- `maxBodyBytes` (4 MiB by default, the limit of the SDK) applies to each request of the face.
|
|
15
|
+
- The state of an HTTP face (`getState()`, and `host.state().faces`) gives `sessions`, the count of its open sessions.
|
|
16
|
+
- `@procedures/client/node` exports `readJsonBody` and `BodyError`: the procedure handler and the MCP face read a JSON body with this one function.
|
|
17
|
+
|
|
18
|
+
One default of the Streamable HTTP face changes: only an `initialize` request starts a session. Before, a POST without a session id made a new MCP server, and then the SDK refused the request with 400 ("Server not initialized"). Now the face refuses it with 400 before it makes a server, so a stray request uses no memory. This agrees with the MCP specification, and a caller sees the same status. When the SDK refuses an `initialize` (for example 406), the face now closes the server of that request.
|
|
19
|
+
- fc968f6: Fixed: `@procedures/geo`, `@procedures/ics` and `@procedures/splay` import `@procedures/client/browser`, not the root of `@procedures/client` (CLI-39). The root also exports `HttpServerTransport`, which imports `http`. Thus a browser build with Vite found `http` and gave a warning. The exports of the packages do not change.
|
|
20
|
+
|
|
21
|
+
New: each package that operates in a browser names its browser entries in the field `client.browser` of its `package.json`. A CI check bundles each of these entries for a browser with esbuild. The check fails when an import reaches a Node built-in, with or without the prefix `node:`. The root of `@procedures/client` joins the check after CLI-6. `@procedures/splay` joins it when `splay.bridge.info` reads its version without `node:fs/promises`.
|
|
22
|
+
- dc7a462: New: the rules of the rows of a served collection (roadmap CLI-41). Before, the collection procedures checked only the partition of a call. A right that depends on the document, for example a `when` condition of an access list, had no place in a read or a write. The new option `admission` of `createCollectionProcedures()` gives two rules. `admit` examines each row `{ id, value }` of each read, and it has the shape of `AdmitItem`. `guard` examines each write `{ op, id, doc, prev }` before the storage changes, and a refused write gets `FORBIDDEN` with the reason `write-not-allowed`. The procedures apply the two rules in one place, the view of the storage of each call (`admittedStorage()`). A refused row is absent from `get`, `has`, `getAll`, `entries`, `ids`, `size`, `getBatch`, `find` and `changes`, and a delta of `changes` puts its id in `deleted`. The change events with values apply `admit` for each subscriber. The context of a call has its invocation (`ctx.invocation`). `@procedures/access` gets `accessWriteGuard()`, and `accessAdmitItem()` gets the option `docOf`. Without the option `admission`, nothing changes.
|
|
23
|
+
- e091108: New: credentialed CORS for the auth routes, from the trusted origins of the host (CLI-49). The handler of Better Auth sends no CORS headers, so a page on another origin got no session and failed POST requests. `betterAuthHandler(auth, { allowedOrigins })` gives the Node handler of the auth routes with credentialed CORS. `betterAuthFace(auth)` gives it as a face of a procedures host, with `browser.allowedOrigins` of the host policy. Thus one list of trusted origins drives `procedureHandler` and the auth routes. A response for a trusted origin names that one origin, with `Access-Control-Allow-Credentials: true` and `Vary: Origin`. The handler answers each preflight. An origin that is not trusted gets no CORS header. The CORS is `credentialedCors()` of `@procedures/client/node`, on the CORS code of `procedureHandler`. It refuses `"*"` (CSRF). The new option `crossSiteCookies` of the configuration (`AUTH_CROSS_SITE_COOKIES=1`) gives the cookies `SameSite=None` and `Secure` for a page on another site. Without the new functions and options, nothing changes.
|
|
24
|
+
- 073e4c3: Changed: `procedureHandler` sends no CORS header to an origin that its `cors` option does not permit (CLI-56). Before, the response for such an origin had no `Access-Control-Allow-Origin`, but it had `Access-Control-Allow-Methods`, `Access-Control-Allow-Headers`, `Access-Control-Allow-Credentials` and `Access-Control-Expose-Headers`, and a preflight also had `Access-Control-Max-Age`. A browser ignores these headers without `Access-Control-Allow-Origin`, so no client uses them. Now the response for that origin, and for a request without an `Origin` header, has none of them. With a list or a function of origins, each response still has `Vary: Origin`, so a shared cache keeps one answer for each origin. A permitted origin and the origin `"*"` get the same headers as before. A preflight still gets 204. `HttpServerTransport` does not change.
|
|
25
|
+
- 6969637: The server transports are in the Node entry (CLI-6 step 1). `@procedures/client/node` now exports `HttpServerTransport`, `HttpServerTransportOptions` and `HttpUrlStrategy`. It already exported `WebSocketServerTransport` and its types.
|
|
26
|
+
|
|
27
|
+
The root `@procedures/client` and the entry `@procedures/client/server` still export these names, but each export is now a deprecated alias with the tag `@deprecated`. The deprecated names are `HttpServerTransport`, `HttpServerTransportOptions`, `HttpUrlStrategy`, `WebSocketServerTransport`, `WebSocketServerTransportOptions`, `WebSocketAuthHandler`, `WebSocketConnectionHandler` and `WebSocketMessage`. Each alias is the same class or type as the export of `./node`, so `new`, `instanceof` and `extends` work as before.
|
|
28
|
+
|
|
29
|
+
The next MINOR removes them from the root (CLI-6 step 2). It also removes them from `./server`. Then the root imports no `http` and no `ws`. Migration: import them from `@procedures/client/node`.
|
|
30
|
+
|
|
31
|
+
The migration steps of the known consumers:
|
|
32
|
+
|
|
33
|
+
- The site: no change. It imports none of these names.
|
|
34
|
+
- MiniMongo: no change. It imports none of these names. The server stub in `vite.config.ts` names `HttpServerTransport` and `WebSocketServerTransport`, and it can stay.
|
|
35
|
+
- Graph: no change. It imports none of these names.
|
|
36
|
+
- jarvis: no change. It imports none of these names.
|
|
37
|
+
- The procedures image of the harness of `systems` (`packages/harness/image/procedures/server-ws.mjs`) imports `WebSocketServerTransport` from the root. It pins `@procedures/client` 0.7.0. When it moves to a version after the next MINOR, import `WebSocketServerTransport` from `@procedures/client/node`.
|
|
38
|
+
|
|
3
39
|
## 0.14.0
|
|
4
40
|
|
|
5
41
|
### Minor Changes
|
package/README.md
CHANGED
|
@@ -297,6 +297,9 @@ interface WebSocketTransportOptions {
|
|
|
297
297
|
// dead peer, its socket stays open until the kernel stops it (924.6 s in the cells of R36).
|
|
298
298
|
import { WebSocketTransport } from "@procedures/client/node";
|
|
299
299
|
|
|
300
|
+
// The server transports are in the Node entry too (CLI-6)
|
|
301
|
+
import { WebSocketServerTransport } from "@procedures/client/node";
|
|
302
|
+
|
|
300
303
|
// The server pings each connection, and closes one that misses 2 pongs (option heartbeat)
|
|
301
304
|
new WebSocketServerTransport(server, { server: http, heartbeat: { interval: seconds(30), misses: 2 } });
|
|
302
305
|
|
|
@@ -591,6 +594,8 @@ await server.stop()
|
|
|
591
594
|
|
|
592
595
|
#### HTTP Server Transport
|
|
593
596
|
```typescript
|
|
597
|
+
import { HttpServerTransport, type HttpServerTransportOptions } from "@procedures/client/node";
|
|
598
|
+
|
|
594
599
|
new HttpServerTransport(server: Server, options: HttpServerTransportOptions)
|
|
595
600
|
|
|
596
601
|
interface HttpServerTransportOptions {
|
|
@@ -668,6 +673,7 @@ http.listen(4820);
|
|
|
668
673
|
- The error codes are the codes of wire v1. A stopped handler answers `UNAVAILABLE` (503, retryable). A refused browser request answers `FORBIDDEN` (403) with a reason: `origin-not-allowed`, `host-header-not-allowed`, `method-not-allowed` or `media-type-not-allowed`.
|
|
669
674
|
- An `OPTIONS` request gets 204 and starts no procedure.
|
|
670
675
|
- `cors: { origin: ["https://app.example"], credentials: true }` lets a page of that origin call with its cookies. A list or a function of origins sends `Access-Control-Allow-Credentials: true` by default.
|
|
676
|
+
- An origin that the CORS does not permit gets no `Access-Control-*` header. With a list or a function of origins, each response gets `Vary: Origin`.
|
|
671
677
|
- `secretHeaders` names more headers that carry a secret, for example `X-Jarvis-Token`. `secretQuery` names the query parameters that carry a secret. Its default is `["token"]`. These values go into the credentials of the request, not into its metadata.
|
|
672
678
|
- `handler.middleware` mounts the handler in Connect or Express. A request outside `basePath` goes to `next`.
|
|
673
679
|
- The handler has the stop parts of a service transport: `start()`, `stopIntake()`, `drain(deadline, signal)`, `inFlight()` and `close()`. It does not make a server and does not listen.
|
|
@@ -676,6 +682,8 @@ http.listen(4820);
|
|
|
676
682
|
|
|
677
683
|
#### WebSocket Server Transport
|
|
678
684
|
```typescript
|
|
685
|
+
import { WebSocketServerTransport, type WebSocketServerTransportOptions } from "@procedures/client/node";
|
|
686
|
+
|
|
679
687
|
new WebSocketServerTransport(server: Server, options?: WebSocketServerTransportOptions)
|
|
680
688
|
|
|
681
689
|
interface WebSocketServerTransportOptions {
|
|
@@ -783,9 +791,9 @@ import { ... } from "@procedures/client/events";
|
|
|
783
791
|
|
|
784
792
|
| Entry | Use |
|
|
785
793
|
|---|---|
|
|
786
|
-
| `@procedures/client` | Node. The browser entry
|
|
794
|
+
| `@procedures/client` | Node. The browser entry. Its `WebSocketTransport` uses the global `WebSocket`. It also exports the server transports, but these exports are deprecated. The next MINOR removes them (CLI-6). |
|
|
787
795
|
| `@procedures/client/browser` | A browser bundle. It does not import `http` or `ws`. |
|
|
788
|
-
| `@procedures/client/node` | Node. A `WebSocketTransport` whose sockets are of the `ws` package: a drop ends a socket at once. `writeNdjsonStream`: the NDJSON stream response of `HttpServerTransport`, for a `ServerResponse` of `node:http`. `procedureHandler` and `upgradeHandler`: the procedure faces of HTTP and WebSocket, without a framework. |
|
|
796
|
+
| `@procedures/client/node` | Node. A `WebSocketTransport` whose sockets are of the `ws` package: a drop ends a socket at once. `writeNdjsonStream`: the NDJSON stream response of `HttpServerTransport`, for a `ServerResponse` of `node:http`. `procedureHandler` and `upgradeHandler`: the procedure faces of HTTP and WebSocket, without a framework. `HttpServerTransport` and `WebSocketServerTransport`: the server transports. |
|
|
789
797
|
| `@procedures/client/register` | It registers the core procedures in the global registry. |
|
|
790
798
|
|
|
791
799
|
## Procedure Discovery
|
|
@@ -848,7 +856,8 @@ for await (const event of bus.stream("user:*")) {
|
|
|
848
856
|
## Server
|
|
849
857
|
|
|
850
858
|
```typescript
|
|
851
|
-
import { Server
|
|
859
|
+
import { Server } from "@procedures/client";
|
|
860
|
+
import { HttpServerTransport } from "@procedures/client/node";
|
|
852
861
|
|
|
853
862
|
const server = new Server({
|
|
854
863
|
transports: [new HttpServerTransport({ port: 3000 })],
|