@procedures/client 0.8.1 → 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/CHANGELOG.md +60 -0
- package/dist/.tsbuildinfo +1 -1
- package/dist/adapters/http/server/addressing.d.ts +78 -0
- package/dist/adapters/http/server/addressing.d.ts.map +1 -0
- package/dist/adapters/http/server/addressing.js +62 -0
- package/dist/adapters/http/server/addressing.js.map +1 -0
- package/dist/adapters/http/server/cors.d.ts.map +1 -1
- package/dist/adapters/http/server/cors.js +3 -0
- package/dist/adapters/http/server/cors.js.map +1 -1
- package/dist/adapters/http/server/handler.d.ts +9 -1
- package/dist/adapters/http/server/handler.d.ts.map +1 -1
- package/dist/adapters/http/server/handler.js +49 -23
- package/dist/adapters/http/server/handler.js.map +1 -1
- package/dist/adapters/http/server/strategies.d.ts +1 -0
- package/dist/adapters/http/server/strategies.d.ts.map +1 -1
- package/dist/adapters/http/server/strategies.js +6 -0
- package/dist/adapters/http/server/strategies.js.map +1 -1
- package/dist/adapters/http/server/transport.d.ts.map +1 -1
- package/dist/adapters/http/server/transport.js +7 -2
- package/dist/adapters/http/server/transport.js.map +1 -1
- package/dist/adapters/http/server/types.d.ts +7 -0
- package/dist/adapters/http/server/types.d.ts.map +1 -1
- package/dist/adapters/http/shared/strategies.d.ts +7 -0
- package/dist/adapters/http/shared/strategies.d.ts.map +1 -1
- package/dist/adapters/http/shared/strategies.js +26 -7
- package/dist/adapters/http/shared/strategies.js.map +1 -1
- package/dist/adapters/local/client/types.d.ts.map +1 -1
- package/dist/adapters/local/client/types.js +3 -1
- package/dist/adapters/local/client/types.js.map +1 -1
- package/dist/adapters/websocket/client/transport.d.ts.map +1 -1
- package/dist/adapters/websocket/client/transport.js +4 -12
- package/dist/adapters/websocket/client/transport.js.map +1 -1
- package/dist/browser.d.ts +6 -3
- package/dist/browser.d.ts.map +1 -1
- package/dist/browser.js +5 -1
- package/dist/browser.js.map +1 -1
- package/dist/client/client.d.ts +6 -0
- package/dist/client/client.d.ts.map +1 -1
- package/dist/client/client.js +3 -1
- package/dist/client/client.js.map +1 -1
- package/dist/client/errors/factory.d.ts.map +1 -1
- package/dist/client/errors/factory.js +2 -3
- package/dist/client/errors/factory.js.map +1 -1
- package/dist/client/middleware/cache.d.ts.map +1 -1
- package/dist/client/middleware/cache.js +2 -1
- package/dist/client/middleware/cache.js.map +1 -1
- package/dist/events/publisher.d.ts +25 -2
- package/dist/events/publisher.d.ts.map +1 -1
- package/dist/events/publisher.js +42 -9
- package/dist/events/publisher.js.map +1 -1
- package/dist/node.d.ts +6 -0
- package/dist/node.d.ts.map +1 -1
- package/dist/node.js +6 -0
- package/dist/node.js.map +1 -1
- package/dist/procedures/collection/changes.d.ts +3 -3
- package/dist/procedures/collection/changes.d.ts.map +1 -1
- package/dist/procedures/collection/changes.js +4 -4
- 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/partition.d.ts +86 -0
- package/dist/procedures/collection/partition.d.ts.map +1 -0
- package/dist/procedures/collection/partition.js +100 -0
- package/dist/procedures/collection/partition.js.map +1 -0
- package/dist/procedures/collection/procedures.d.ts +4 -4
- package/dist/procedures/collection/procedures.d.ts.map +1 -1
- package/dist/procedures/collection/procedures.js +55 -55
- package/dist/procedures/collection/procedures.js.map +1 -1
- package/dist/procedures/index.d.ts +4 -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 +17 -2
- package/dist/procedures/invoke.d.ts.map +1 -1
- package/dist/procedures/invoke.js +30 -1
- package/dist/procedures/invoke.js.map +1 -1
- package/dist/procedures/narrowing.d.ts +93 -0
- package/dist/procedures/narrowing.d.ts.map +1 -0
- package/dist/procedures/narrowing.js +328 -0
- package/dist/procedures/narrowing.js.map +1 -0
- package/dist/procedures/types.d.ts +19 -0
- package/dist/procedures/types.d.ts.map +1 -1
- package/dist/procedures/types.js.map +1 -1
- package/dist/server/index.d.ts +2 -2
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +1 -1
- package/dist/server/index.js.map +1 -1
- package/dist/server/method.d.ts +8 -2
- package/dist/server/method.d.ts.map +1 -1
- package/dist/server/method.js +16 -5
- package/dist/server/method.js.map +1 -1
- package/dist/server/procedure-server.d.ts +47 -1
- package/dist/server/procedure-server.d.ts.map +1 -1
- package/dist/server/procedure-server.js +89 -12
- package/dist/server/procedure-server.js.map +1 -1
- package/dist/server/types.d.ts +16 -0
- package/dist/server/types.d.ts.map +1 -1
- package/dist/server/types.js +2 -1
- package/dist/server/types.js.map +1 -1
- package/package.json +3 -3
- package/src/adapters/http/server/addressing.ts +118 -0
- package/src/adapters/http/server/cors.ts +3 -0
- package/src/adapters/http/server/handler.ts +57 -23
- package/src/adapters/http/server/strategies.ts +7 -0
- package/src/adapters/http/server/transport.ts +8 -3
- package/src/adapters/http/server/types.ts +8 -0
- package/src/adapters/http/shared/strategies.ts +25 -7
- package/src/adapters/local/client/types.ts +3 -1
- package/src/adapters/websocket/client/transport.ts +4 -12
- package/src/browser.ts +12 -1
- package/src/client/client.ts +8 -1
- package/src/client/errors/factory.ts +2 -3
- package/src/client/middleware/cache.ts +2 -1
- package/src/events/publisher.ts +50 -11
- package/src/node.ts +7 -0
- package/src/procedures/collection/changes.ts +4 -4
- package/src/procedures/collection/index.ts +4 -0
- package/src/procedures/collection/partition.ts +145 -0
- package/src/procedures/collection/procedures.ts +72 -73
- package/src/procedures/index.ts +9 -0
- package/src/procedures/invoke.ts +42 -2
- package/src/procedures/narrowing.ts +357 -0
- package/src/procedures/types.ts +23 -0
- package/src/server/index.ts +2 -1
- package/src/server/method.ts +17 -5
- package/src/server/procedure-server.ts +106 -13
- package/src/server/types.ts +19 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,65 @@
|
|
|
1
1
|
# @procedures/client
|
|
2
2
|
|
|
3
|
+
## 0.9.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 61d60c6: Procedure paths of each length on each face (server stack CLI-28). A path has one segment or more. Each change is additive: each path of two segments or more keeps its method, its URL and its tool name.
|
|
8
|
+
|
|
9
|
+
- `pathToMethod()` takes a path of one segment, for example `["morning"]`: its method has the empty service, `{ service: "", operation: "morning" }`. An empty path still throws. New `methodName(method)` gives the name with dots (`morning`, `docker.compose.up`).
|
|
10
|
+
- HTTP: the URL of a path of one segment is `{base}/{operation}`, for example `/api/morning`. `procedureHandler`, `HttpServerTransport` and `rpcServerUrlStrategy` (`/rpc/morning`) read it, and `bodyPathAddressing()` takes a path of one segment too. A URL with one segment under the base path names a procedure now: an unknown one gets `NOT_FOUND`, not `INVALID_REQUEST`.
|
|
11
|
+
- The version of the URL keeps its old form `{base}/{version}/{service}/{operation}`. Only the version makes three URL segments, so the forms do not collide. A path of one segment has no version in the URL, because `{base}/{version}/{operation}` reads as a service and an operation. The server ignores the version (wire protocol v1).
|
|
12
|
+
- `defaultUrlPattern` URI-encodes each URL segment and decodes it again. Thus a segment with `/`, `?` or a space round-trips, and a segment never makes a URL separator. A segment of letters, digits, `-`, `.`, `_` and `~` keeps its URL.
|
|
13
|
+
- `methodToPath()` keeps each empty segment but the empty service. Thus a method with `..` or a stray dot names no procedure and gets `NOT_FOUND`. Before, the empty segments fell away, so `/api/notes/..` could reach the procedure `notes`.
|
|
14
|
+
- WebSocket, the message port and `LocalTransport` call a path of one segment. A handler of `LocalTransport` with the key `morning` answers it.
|
|
15
|
+
- MCP: a path of one segment has a tool name, for example `morning`. When two procedures have one tool name after the join of the segments (`["a_b", "c"]` and `["a", "b_c"]` with `path.join("_")`), the face leaves out the two tools and writes the reason to stderr. Before, the face kept the last one, so a call could reach the wrong procedure. `host.tools()` gives the same list.
|
|
16
|
+
- `WIRE-PROTOCOL.md` states the rule.
|
|
17
|
+
- 79f750a: A narrowing key on the wire, and an addressing hook for HTTP (server stack CLI-30 and CLI-31). Each change is additive: without the new key or the new option, the behavior stays the same.
|
|
18
|
+
|
|
19
|
+
- A call can ask for a narrower capability than its principal holds, with the narrowing key `procedure-narrowing`. Its value is a `CapabilityRequest` as JSON (`clearance`, `effects` and `timeoutMs`), or a list of them.
|
|
20
|
+
- Each face carries the key. HTTP has each line of the header `Procedure-Narrowing` (raw or URI-encoded JSON), the key in `X-Metadata` and a query parameter. WebSocket has the key in the metadata of a `request` frame. MCP has the key in the `_meta` of `tools/call` and the header of Streamable HTTP. In the process, the key of the metadata of `ProcedureServer.handle()`, `LocalTransport`, `invokeProcedure()` and `Client.exec()` applies.
|
|
21
|
+
- No source replaces another: a gateway's header and the client's key of `X-Metadata` both apply. `invokeProcedure()` is the one place that applies the sources, for the call of a host, with the narrowing of `principalOf` and the new option `narrow`. The clearance is the meet of the clearance order, the effects are the intersection, and the deadline is the earliest. Each source can only narrow, in each sequence.
|
|
22
|
+
- A valid part that asks for more has no effect: the meet removes it. A part that is not valid refuses the call, so a typo of a gateway does not leave the call wider. A part that is not well formed (not JSON, an unknown field, a time that is not a number) gives `INVALID_REQUEST`. A clearance outside the order, or two different clearances without a clearance order, give `FORBIDDEN` (reason `clearance`).
|
|
23
|
+
- New option `debug` of `ProcedureServer`: `true` writes each report with `console.debug`, and a function gets each `ServerDebugReport`. The server reports each part of the narrowing that has no effect, and each refusal.
|
|
24
|
+
- New options of `invokeProcedure()` and `invokePath()`: `narrow` (one more source) and `onNarrowingNotes` (the notes of the narrowing). New option `metadata` of `Client.exec()` and `Client.execStream()`: a local procedure gets it as `ctx.metadata`, and a remote call sends it.
|
|
25
|
+
- New exports: `NARROWING_METADATA_KEY`, `NARROWING_HEADER`, `narrowingOf()` (the decoder of the key), `addNarrowing()` (adds a source to the key) and `narrowWithin()` (a narrowing of many sources that does not throw and gives notes). New types: `NarrowingNote`, `WireNarrowing`, `NarrowedCapability` and `ServerDebugReport`.
|
|
26
|
+
- The default CORS headers include `Procedure-Narrowing`.
|
|
27
|
+
- `procedureHandler` and `HttpServerTransport` copy each key of the query as an own property, so a `__proto__` key changes no prototype.
|
|
28
|
+
- `@procedures/client/node`: new option `addressing` of `procedureHandler`. The hook gets the request and its body, and it gives `{ method, payload }`. `urlAddressing()` is the default, the URL format of `HttpTransport`. `bodyPathAddressing()` reads the path and the input from the body of a single endpoint, for example `POST /api/proc` with `{"path": ["notes", "list"], "input": {}}`. With it, the handler also takes the base path itself.
|
|
29
|
+
- `HttpServerTransport` takes the same option `addressing`. With `bodyPathAddressing()`, its route also takes the base path itself.
|
|
30
|
+
- New types of `@procedures/client/node`: `Addressing`, `CallAddress`, `UrlAddressingOptions` and `BodyPathAddressingOptions`.
|
|
31
|
+
- `WIRE-PROTOCOL.md` specifies the narrowing key and its sources, the addressing hook, `procedureHandler`, the credentials of a request and the reasons of `FORBIDDEN`, with the four reasons of the browser checks.
|
|
32
|
+
- d0c9856: The partitions of a collection (roadmap CLI-17), two follow-ups of the review. A collection without partitions can have a dot in its name, and its topic `collections.<name>` stays a plain topic. `usePartitions` refuses a name with a dot, because the topic names the partition after the first dot. The documentation of `PartitionResolver` gives its contract: a partition of the caller or `null`, and not the partition of another tenant. One rule, `collectionTopicTarget(topic, repository)`, gives the collection of a topic to the read check and to the listener of the publisher. So a reader of `a` does not hear the collection `a.b`.
|
|
33
|
+
- b5db4d8: Under the root of the files of a host, the `git.*` procedures are confined, not refused (roadmap R33, tracker item O35). Without a root, nothing changes. PATCH: a procedure that the root refused now works in the root.
|
|
34
|
+
|
|
35
|
+
- The core: `ProcedureContext.fsRoot` is the root of a confined call. `confineToRoot()` of `@procedures/fs` gives it to the handler of each confined procedure and of each program procedure.
|
|
36
|
+
- The working folder `cwd` of each `git.*` procedure must be in the root, and its default is the root. The pathspecs, the `path` of `git.blame` and of the worktree procedures, and the `dest` of `git.clone` must be in the root too.
|
|
37
|
+
- Under a root, git runs with `GIT_CEILING_DIRECTORIES` at the parent of the root, so it finds no repository above the root. The configuration of the system does not apply. The global configuration has only `user.name`, `user.email` and `init.defaultBranch` of the host.
|
|
38
|
+
- The `-c` options turn off the hooks (an empty `core.hooksPath`) and `core.fsmonitor`. Only the transports https, http, ssh and git are permitted. Git does not go into a submodule.
|
|
39
|
+
- Before the first command in a folder, git examines the repository. A repository outside the root (through a `.git` file or an alternate object folder), a repository with submodules, and a configuration key that starts a program are refused: `filter.*`, `diff.external`, `core.sshCommand`, `credential.helper`, `include.path` and the others. The error names each key.
|
|
40
|
+
- `git.clone` and `git.remote.set` refuse a URL with `::` under a root.
|
|
41
|
+
- `@procedures/git` now depends on `@procedures/fs` (for the rules of `@procedures/fs/root`).
|
|
42
|
+
|
|
43
|
+
## 0.9.0
|
|
44
|
+
|
|
45
|
+
### Minor Changes
|
|
46
|
+
|
|
47
|
+
- dc03903: The WebSocket client ignores a raw frame of the type `event`, as a frame of an unknown type. Before, it gave such a frame to `onEvent`, for a server outside this repository. No side of wire protocol v1 sends that frame (the type is reserved). `onEvent` now gets only the events of the subscriptions of the transport (`events.subscribe`). MINOR: a breaking change of behavior (the API is before 1.0.0).
|
|
48
|
+
|
|
49
|
+
Migration: a server that sends raw `event` frames sends its events through `events.subscribe` instead (EVENTS.md). The client then gets them in `onEvent`, with the id of the subscription.
|
|
50
|
+
|
|
51
|
+
### Patch Changes
|
|
52
|
+
|
|
53
|
+
- 8bb469c: The partitions of a collection (roadmap CLI-17). One `collections.<name>.*` surface serves several partitions, for example one for each tenant. `ProcedureServer.usePartitions(name, { storageOf, resolve })` registers the storage of each partition and the resolver. The resolver gives the partition of each call from its context, so the tenant comes from `ctx.principal`. The input can ask for a partition, and the resolver can refuse the call (`FORBIDDEN`, reason `partition-not-allowed`).
|
|
54
|
+
|
|
55
|
+
`RepositoryProvider` has the new optional methods `getPartitionStorage`, `hasPartitions` and `resolvePartition`. A repository without them refuses a partition. The events of a partition go to `collections.<name>.<partition>`.
|
|
56
|
+
|
|
57
|
+
A subscriber of `EventPublisher` names the partition that it asks for, and the publisher resolves it with the same resolver. So a subscriber cannot name the topic of another tenant. A change of behavior for safety: a topic `collections.<name>.<partition>` of a collection without partitions is refused. Before, each subscriber with the read of the collection got it. New exports: `PARTITION_PATTERN`, `collectionTopicPartition`, `CollectionPartitions`, `PartitionInput` and `PartitionResolver`.
|
|
58
|
+
- dca28c1: The packages accept `@mark1russell7/service` 0.5.1 and later 0.5 versions, and `@procedures/client` accepts `@mark1russell7/algebra` 0.7.1. Before, the range `^0.4.1` stopped below 0.5. An application on service 0.5 then got a second copy of service inside the client.
|
|
59
|
+
|
|
60
|
+
- The client uses only the `/backoff`, `/heartbeat` and `/testing` entries of service. The code of `/backoff`, `/heartbeat` and the clock is the same in 0.4.1 and 0.5.1. `/testing` only gets new exports.
|
|
61
|
+
- The public API of the client does not change.
|
|
62
|
+
|
|
3
63
|
## 0.8.1
|
|
4
64
|
|
|
5
65
|
### Patch Changes
|