@procedures/client 0.47.1 → 0.48.0
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 +92 -68
- package/README.md +3 -3
- package/dist/.tsbuildinfo +1 -1
- package/dist/adapters/http/client/batch.d.ts.map +1 -1
- package/dist/adapters/http/client/batch.js.map +1 -1
- package/dist/adapters/http/server/body.d.ts.map +1 -1
- package/dist/adapters/http/server/body.js.map +1 -1
- package/dist/adapters/http/shared/constants.d.ts +82 -78
- package/dist/adapters/http/shared/constants.d.ts.map +1 -1
- package/dist/adapters/http/shared/constants.js +78 -80
- package/dist/adapters/http/shared/constants.js.map +1 -1
- package/dist/adapters/http/shared/errors.d.ts +15 -13
- package/dist/adapters/http/shared/errors.d.ts.map +1 -1
- package/dist/adapters/http/shared/errors.js +13 -14
- package/dist/adapters/http/shared/errors.js.map +1 -1
- package/dist/adapters/port/transport.d.ts.map +1 -1
- package/dist/adapters/port/transport.js.map +1 -1
- package/dist/adapters/sequence.d.ts.map +1 -1
- package/dist/adapters/sequence.js.map +1 -1
- package/dist/adapters/websocket/client/types.d.ts +16 -6
- package/dist/adapters/websocket/client/types.d.ts.map +1 -1
- package/dist/adapters/websocket/client/types.js +7 -8
- package/dist/adapters/websocket/client/types.js.map +1 -1
- package/dist/adapters/websocket/shared/rpc.d.ts.map +1 -1
- package/dist/adapters/websocket/shared/rpc.js.map +1 -1
- package/dist/browser.d.ts +1 -1
- package/dist/browser.d.ts.map +1 -1
- package/dist/browser.js.map +1 -1
- package/dist/client/batch-executor.d.ts.map +1 -1
- package/dist/client/batch-executor.js.map +1 -1
- package/dist/client/client.d.ts.map +1 -1
- package/dist/client/client.js +3 -4
- package/dist/client/client.js.map +1 -1
- package/dist/client/errors/codes.d.ts +66 -64
- package/dist/client/errors/codes.d.ts.map +1 -1
- package/dist/client/errors/codes.js +64 -65
- package/dist/client/errors/codes.js.map +1 -1
- package/dist/client/errors/http-status.d.ts +69 -67
- package/dist/client/errors/http-status.d.ts.map +1 -1
- package/dist/client/errors/http-status.js +67 -68
- package/dist/client/errors/http-status.js.map +1 -1
- package/dist/client/errors/types.d.ts +38 -15
- package/dist/client/errors/types.d.ts.map +1 -1
- package/dist/client/errors/types.js +17 -19
- package/dist/client/errors/types.js.map +1 -1
- package/dist/client/middleware/circuit-breaker.d.ts.map +1 -1
- package/dist/client/middleware/circuit-breaker.js.map +1 -1
- package/dist/client/middleware/lru.d.ts +1 -1
- package/dist/client/middleware/lru.d.ts.map +1 -1
- package/dist/client/middleware/lru.js.map +1 -1
- package/dist/client/middleware/rate-limit.d.ts.map +1 -1
- package/dist/client/middleware/rate-limit.js.map +1 -1
- package/dist/client/middleware/resilience.d.ts.map +1 -1
- package/dist/client/middleware/resilience.js +2 -1
- package/dist/client/middleware/resilience.js.map +1 -1
- package/dist/client/route-resolver.d.ts.map +1 -1
- package/dist/client/route-resolver.js.map +1 -1
- package/dist/client/types.d.ts.map +1 -1
- package/dist/client/types.js.map +1 -1
- package/dist/client/validation/types.d.ts +1 -7
- package/dist/client/validation/types.d.ts.map +1 -1
- package/dist/client/validation/types.js +4 -7
- package/dist/client/validation/types.js.map +1 -1
- package/dist/events/bus.d.ts +35 -0
- package/dist/events/bus.d.ts.map +1 -1
- package/dist/events/bus.js +135 -22
- package/dist/events/bus.js.map +1 -1
- package/dist/events/index.d.ts +1 -1
- package/dist/events/index.d.ts.map +1 -1
- package/dist/events/index.js.map +1 -1
- package/dist/events/publisher.d.ts.map +1 -1
- package/dist/events/publisher.js +4 -7
- package/dist/events/publisher.js.map +1 -1
- package/dist/events/recheck.d.ts.map +1 -1
- package/dist/events/recheck.js.map +1 -1
- package/dist/events/remote.d.ts +1 -7
- package/dist/events/remote.d.ts.map +1 -1
- package/dist/events/remote.js +4 -7
- package/dist/events/remote.js.map +1 -1
- package/dist/events/types.d.ts +30 -0
- package/dist/events/types.d.ts.map +1 -1
- package/dist/middleware/compose.d.ts.map +1 -1
- package/dist/middleware/compose.js +6 -10
- package/dist/middleware/compose.js.map +1 -1
- package/dist/procedures/caller.d.ts +1 -1
- package/dist/procedures/caller.js +1 -1
- package/dist/procedures/collection/admission.d.ts +1 -1
- package/dist/procedures/collection/admission.js +1 -1
- package/dist/procedures/collection/hint-filter.d.ts +1 -7
- package/dist/procedures/collection/hint-filter.d.ts.map +1 -1
- package/dist/procedures/collection/hint-filter.js +4 -7
- package/dist/procedures/collection/hint-filter.js.map +1 -1
- package/dist/server/face-rules.d.ts +1 -1
- package/dist/server/face-rules.js +1 -1
- package/dist/server/procedure-server.d.ts +7 -5
- package/dist/server/procedure-server.d.ts.map +1 -1
- package/dist/server/procedure-server.js +10 -8
- package/dist/server/procedure-server.js.map +1 -1
- package/dist/server/types.d.ts.map +1 -1
- package/dist/server/types.js.map +1 -1
- package/dist/testing/transport-contract.d.ts +1 -1
- package/dist/testing/transport-contract.js +1 -1
- package/package.json +8 -4
- package/src/adapters/http/client/batch.ts +4 -1
- package/src/adapters/http/server/body.ts +4 -1
- package/src/adapters/http/shared/constants.ts +84 -78
- package/src/adapters/http/shared/errors.ts +16 -13
- package/src/adapters/port/transport.ts +4 -1
- package/src/adapters/sequence.ts +5 -1
- package/src/adapters/websocket/client/types.ts +19 -6
- package/src/adapters/websocket/shared/rpc.ts +15 -3
- package/src/browser.ts +1 -0
- package/src/client/batch-executor.ts +5 -1
- package/src/client/client.ts +3 -4
- package/src/client/errors/README.md +12 -12
- package/src/client/errors/codes.ts +67 -64
- package/src/client/errors/http-status.ts +70 -67
- package/src/client/errors/types.ts +44 -15
- package/src/client/middleware/circuit-breaker.ts +7 -2
- package/src/client/middleware/lru.ts +7 -2
- package/src/client/middleware/rate-limit.ts +4 -1
- package/src/client/middleware/resilience.ts +2 -1
- package/src/client/route-resolver.ts +5 -1
- package/src/client/types.ts +7 -2
- package/src/client/validation/types.ts +13 -6
- package/src/events/bus.ts +152 -23
- package/src/events/index.ts +1 -0
- package/src/events/publisher.ts +22 -9
- package/src/events/recheck.ts +4 -1
- package/src/events/remote.ts +33 -12
- package/src/events/types.ts +34 -0
- package/src/middleware/compose.ts +6 -22
- package/src/procedures/caller.ts +1 -1
- package/src/procedures/collection/admission.ts +1 -1
- package/src/procedures/collection/hint-filter.ts +13 -6
- package/src/server/face-rules.ts +1 -1
- package/src/server/procedure-server.ts +11 -8
- package/src/server/types.ts +7 -2
- package/src/testing/transport-contract.ts +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,29 @@
|
|
|
1
1
|
# @procedures/client
|
|
2
2
|
|
|
3
|
+
## 0.48.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 17a18ec: The source now uses only syntax that a type stripper erases, so the setting `erasableSyntaxOnly` of `@mark1russell7/cue` 2.1.1 stays on. Each enum is now a constant object with a type of the same name. Each parameter property is now a field and an assignment in the constructor.
|
|
8
|
+
|
|
9
|
+
**Breaking.** MINOR before 1.0.0: `ErrorCategory`, `ErrorSeverity` and `WebSocketState` are now constant objects. Their names and values stay the same, and each member stays usable as a type. A member is no longer a constant expression: `enum E { A = ErrorSeverity.WARNING }` gives TS18033, and a `const enum` gives TS2474. Also, a string with the value of a member now fits the type of the set.
|
|
10
|
+
|
|
11
|
+
**Migration.** In an enum initializer, write the value in place of the member, for example `"warning"`, or use a constant object. Other uses need no change. The site and the known apps need no change.
|
|
12
|
+
- c839add: The release train: the ranges of @mark1russell7/coeval, @mark1russell7/quantity, @mark1russell7/collections, @mark1russell7/cue change to a version outside the old range.
|
|
13
|
+
|
|
14
|
+
### Patch Changes
|
|
15
|
+
|
|
16
|
+
- 06088f9: `EventBusOptions` has a new option `fanOut`. With it, a channel with more handlers than `fanOut.sliceSize` delivers after `emit()` returns, in slices, so one event does not hold the event loop. Without it, nothing changes. `DefaultEventBus` has a new method `drained()`.
|
|
17
|
+
- 71f9c6e: The middleware folds use `compose` of `@mark1russell7/collections/layers`. The order of the middleware does not change, and the public API does not change. `@procedures/client` has a new dependency on `@mark1russell7/collections`.
|
|
18
|
+
|
|
19
|
+
## 0.47.2
|
|
20
|
+
|
|
21
|
+
### Patch Changes
|
|
22
|
+
|
|
23
|
+
- 0650616: Security fix. `tokenMatches` accepted an empty presented token when the expected token was empty, so a server with `token: ""` admitted a request with an empty bearer. An empty expected token now matches nothing, so `token: ""` means "refuse each network request". The comparison now loops over the presented token, so its time depends only on what the caller sent, as its doc comment says. `MCP_HTTP_TOKEN` set and empty is now an error at the start of the HTTP face, because the server otherwise started with no token. PATCH: the change affects only a server that is open by mistake.
|
|
24
|
+
- ae1e3fd: Shorter doc comments.
|
|
25
|
+
- f1ece74: Neutral names in comments.
|
|
26
|
+
|
|
3
27
|
## 0.47.1
|
|
4
28
|
|
|
5
29
|
### Patch Changes
|
|
@@ -113,9 +137,9 @@ No changes in this release.
|
|
|
113
137
|
- Each app: examine each retry rule that reads the `retryable` flag of an error. Such a rule sees the new flags of the tables. To retry a 500 of a proxy, give the retry middleware a `shouldRetry` function that matches the code `INTERNAL_ERROR`.
|
|
114
138
|
- Each app with `HybridStorage` over HTTP: to make a 500 of a proxy offline again, give an `isUnavailable` option that also matches the code `INTERNAL_ERROR`.
|
|
115
139
|
- The site (`packages/site`): no step. It does not match on the three old codes, and it has no retry rule for a status.
|
|
116
|
-
-
|
|
117
|
-
-
|
|
118
|
-
-
|
|
140
|
+
- An app: do the steps of each app in its dev host and in its client code. Then examine the retry rules of its HTTP requests to the procedures server.
|
|
141
|
+
- An app: do the steps of each app.
|
|
142
|
+
- An app: do the steps of each app in each client of `@procedures/client` that it has.
|
|
119
143
|
- e4cb0cf: The release train: the ranges of @mark1russell7/algebra, @mark1russell7/service change to a version outside the old range.
|
|
120
144
|
|
|
121
145
|
### Patch Changes
|
|
@@ -173,7 +197,7 @@ No changes in this release.
|
|
|
173
197
|
|
|
174
198
|
- A caller that reads the code of a 413 from the HTTP handler compares it with `PAYLOAD_TOO_LARGE`, not `INVALID_REQUEST`.
|
|
175
199
|
- A caller of `WebSocketTransport` that retries each failed call stops at `retryable: false`. A call above the limit of the server fails the same way each time.
|
|
176
|
-
-
|
|
200
|
+
- Apps: no step, unless one of them compares the code of a refused large request with `INVALID_REQUEST`.
|
|
177
201
|
|
|
178
202
|
## 0.38.0
|
|
179
203
|
|
|
@@ -199,7 +223,7 @@ No changes in this release.
|
|
|
199
223
|
|
|
200
224
|
- A caller of `cli-kit` with a `format` hook for a path with a dotted segment writes the key in the encoded form, for example `a.b%2Ec`.
|
|
201
225
|
- A reader of the ecosystem scan that splits a `key` on `.` uses `keyToPath(key)`.
|
|
202
|
-
-
|
|
226
|
+
- Apps: no step, if their procedure paths have no segment with `.` or `%`.
|
|
203
227
|
|
|
204
228
|
## 0.37.0
|
|
205
229
|
|
|
@@ -235,8 +259,8 @@ No changes in this release.
|
|
|
235
259
|
- A reader of `changes` with a rule of the rows: apply a full answer as a replacement of the copy. The sync of `@procedures/client-store` does this. A full answer comes after each delete, so give `admitsAll` to the principals with full rights.
|
|
236
260
|
- A host whose `allow` of `events.subscribe` refused a principal with a rule of the rows can admit it.
|
|
237
261
|
- A host with full rights for some principals: give `admission.admitsAll`. Without it, the publisher examines each row of each event for each subscriber. Also, each write reads its rows before the change while such a subscriber is open.
|
|
238
|
-
-
|
|
239
|
-
-
|
|
262
|
+
- An app: give `admitsAll` for the principals that read a whole partition. Then admit the principals with a `when` condition in `allow`.
|
|
263
|
+
- Other apps: no change, if their collections have no `admission.admit`. Then their events do not change.
|
|
240
264
|
|
|
241
265
|
## 0.35.1
|
|
242
266
|
|
|
@@ -308,8 +332,8 @@ No changes in this release.
|
|
|
308
332
|
- A host whose `expose`, policy or limit pattern names such a path in text uses the encoded form, for example `collections.e2e%2Etabs.*`.
|
|
309
333
|
- An `mcpExclude` entry, an `expose` deny entry or a limit entry in the old raw form, for example `collections.e2e.tabs.drop`, does not match. The check compares the encoded key, so the procedure becomes visible, or the limit does not apply. Write each such entry in the encoded form, for example `collections.e2e%2Etabs.drop`.
|
|
310
334
|
- A subscriber of a dotted collection uses `collectionChangeTopic(name)`. The raw topic `collections.a.b` is the topic of the partition `b` of `a`.
|
|
311
|
-
-
|
|
312
|
-
-
|
|
335
|
+
- An app: read the collection of a topic with `collectionTopicPartition(topic)`, not with a pattern, for example `/^collections\.([^.]+)\./`.
|
|
336
|
+
- Other apps: no change, if their collection names have no `.` and no `%`.
|
|
313
337
|
|
|
314
338
|
### Patch Changes
|
|
315
339
|
|
|
@@ -326,7 +350,7 @@ No changes in this release.
|
|
|
326
350
|
|
|
327
351
|
Migration:
|
|
328
352
|
|
|
329
|
-
-
|
|
353
|
+
- Apps: no change at this time. The deprecated names work until the next MINOR.
|
|
330
354
|
- Before the next MINOR, replace `zodAdapter<T>(schema)` with `schema`. To keep the check of a schema against a type, write `const schema: z.ZodType<T> = ...`.
|
|
331
355
|
- Before the next MINOR, replace `typedAnySchema<T>()` and `outputSchema<T>()` with `typed<T>()`.
|
|
332
356
|
- A parse-only object (`{ parse }`) in `zodAdapter` becomes a Standard Schema with a `~standard` property.
|
|
@@ -367,7 +391,7 @@ No changes in this release.
|
|
|
367
391
|
|
|
368
392
|
Now each repetition multiplies the ways of the part inside it. The guard refuses `((a|a){9}){9}` and `((a?){9}){9}`. A pattern with few ways still passes, for example `((?:a|b){3}){3}` and `(\d{1,3}\.){3}\d{1,3}`.
|
|
369
393
|
|
|
370
|
-
Migration: the
|
|
394
|
+
Migration: the apps do not turn `$regex` on, so they need no change.
|
|
371
395
|
- 21dc858: Fixes for the security findings of the second code audit (roadmap O55).
|
|
372
396
|
|
|
373
397
|
PATCH: bug fixes and additive options. Each fix refuses only an input that the documentation does not give. A caller that uses the documented behavior sees no change. A request to a loopback, private or link-local host still works, with a deprecation notice. Version 0.29.0 refuses it (decision D35).
|
|
@@ -399,7 +423,7 @@ No changes in this release.
|
|
|
399
423
|
|
|
400
424
|
A bounded repetition with at most 1000 ways to match passes, for example `(\d{1,3}\.){3}`. Alternatives that start with different characters pass, for example `(?:foo|bar)+` and `(?:[a-z]|-)+`.
|
|
401
425
|
|
|
402
|
-
Migration: the
|
|
426
|
+
Migration: the apps do not turn `$regex` on, so they need no change. A host that turns it on and gets the new `VALIDATION_ERROR` writes the pattern without the ambiguity. For example, write `(?:a|b)+` for `(a|ab|b)+`, and write the repetitions out, `\w+\s\w+\s` for `(\w+\s){2}`.
|
|
403
427
|
|
|
404
428
|
## 0.27.8
|
|
405
429
|
|
|
@@ -549,13 +573,13 @@ No changes in this release.
|
|
|
549
573
|
- A face of your own that gives `mcpFace()` a handler of its own: give the handler `admission: (credentials) => server.admission(credentials)`.
|
|
550
574
|
- An MCP client that a request hook refuses gets 401 at `initialize`. Give it valid credentials for each HTTP request.
|
|
551
575
|
- The site: no change. It has no MCP host, and it used no function of `peer/security.ts`.
|
|
552
|
-
-
|
|
553
|
-
-
|
|
554
|
-
-
|
|
555
|
-
-
|
|
556
|
-
-
|
|
557
|
-
-
|
|
558
|
-
-
|
|
576
|
+
- An app: no change. Its dev host has only the HTTP and WebSocket faces of `createProcedureHost()`. Each request of these faces had one check before.
|
|
577
|
+
- An app: its `mcpFace()` on the procedures host uses a session hook for each HTTP request. In the accounts mode, a request without a session gets `ANONYMOUS`. Thus an MCP client without a session gets no 401 at `initialize`.
|
|
578
|
+
- An app: in the mode `on` (`AUTH_MODE=on`), a request without a tenant token gets 401 at `initialize`. Before, the client opened a session and listed the tools, and each tool call got `UNAUTHORIZED`.
|
|
579
|
+
- An app: accounts that are not ready (the error `UNAVAILABLE` of the hook) give 401 at `initialize`, with `WWW-Authenticate: Bearer`. Before, `initialize` passed, and each tool call got `UNAUTHORIZED`. An MCP client can start its OAuth discovery on this 401.
|
|
580
|
+
- An app: outside the accounts mode, the policy has `allowedOrigins: "*"`. The MCP face takes it, as the HTTP face does. A request with a cookie still needs a named origin. With the default `ambientCredentials: "always"` of its request hook, `"*"` permits no other origin.
|
|
581
|
+
- An app: to keep only the own origin on the MCP face, give `mcpFace({ allowedOrigins: [] })`. Its MCP host over stdio has no change.
|
|
582
|
+
- An app: no change. Its procedures host has only the HTTP face, and its MCP host has only stdio and SDK faces.
|
|
559
583
|
- `mark mcp --http --token` and `@procedures/mcp-dev-tools`: no change for a client. The token is the token of the server, and the server checks each HTTP request one time.
|
|
560
584
|
|
|
561
585
|
## 0.26.2
|
|
@@ -643,9 +667,9 @@ No changes in this release.
|
|
|
643
667
|
- A test that expects `retryable: false` for such an end before the first item: expect the flag of the code.
|
|
644
668
|
- A custom `errorOf` of `writeNdjsonStream`: read its second parameter to give the same rule.
|
|
645
669
|
- The site: no change is necessary. The lab simulates its server with explicit flags. The streams of the journey do not fail.
|
|
646
|
-
-
|
|
647
|
-
-
|
|
648
|
-
-
|
|
670
|
+
- An app: no change is necessary. Its browser client has the retry middleware, but its procedures throw no `UNAVAILABLE`, `CONNECTION_CLOSED` or `RATE_LIMITED` without a flag.
|
|
671
|
+
- An app: no change is necessary. Its handlers give `UNAVAILABLE` with an explicit flag, and it serves no stream procedure of its own.
|
|
672
|
+
- An app: no change is necessary. The cuts of its host have their own flag, and it uses no retry middleware.
|
|
649
673
|
|
|
650
674
|
### Patch Changes
|
|
651
675
|
|
|
@@ -674,7 +698,7 @@ No changes in this release.
|
|
|
674
698
|
|
|
675
699
|
`WIRE-PROTOCOL.md` (section "Error codes") and the doc comments of `errorResponse`, `defaultNdjsonError`, `errorStatus` and `streamErrorMeta` have the deprecation notes.
|
|
676
700
|
|
|
677
|
-
|
|
701
|
+
Apps: no change in this release.
|
|
678
702
|
|
|
679
703
|
## 0.24.0
|
|
680
704
|
|
|
@@ -705,9 +729,9 @@ No changes in this release.
|
|
|
705
729
|
|
|
706
730
|
Migration:
|
|
707
731
|
|
|
708
|
-
- The site and
|
|
709
|
-
-
|
|
710
|
-
-
|
|
732
|
+
- The site and an app: no change. They have no MCP host.
|
|
733
|
+
- An app: no change. Its MCP hosts have no task store.
|
|
734
|
+
- An app: no change. Its MCP host has no tasks.
|
|
711
735
|
- polite-crawler-mcp: no change. Each request has the host token, so each session is one client. A session with 100 tasks gets fewer tasks only when ten or more sessions are near the limit. To keep the rule of CLI-51, give `new McpTaskStore({ reserve: 0 })`.
|
|
712
736
|
- A host whose clients each have many sessions under one principal: each client keeps at most `maxStored - reserve` tasks. To keep the rule of CLI-51, give `reserve: 0` in `tasks` of the host or in `new McpTaskStore()`.
|
|
713
737
|
- 71091a5: Added: the envelope form of a program (coeval, decisions D6, D9 and D10, roadmap item M7). A call is `{ "type": ["client", "add"], "value": input }`, and a reference is `{ "type": "ref", "value": ["names", "sum"] }`. The `$proc` form does not change.
|
|
@@ -737,9 +761,9 @@ No changes in this release.
|
|
|
737
761
|
|
|
738
762
|
- Does a subscriber of `a.b` get `FORBIDDEN` with the reason `partition-not-allowed`? Then make the resolver of `a.b` give a partition. Or rename `a.b` to a name without a dot, for example `a_b`.
|
|
739
763
|
- The site: no change is necessary. It serves no collection.
|
|
740
|
-
-
|
|
741
|
-
-
|
|
742
|
-
-
|
|
764
|
+
- An app: no change is necessary. Its server serves no collection.
|
|
765
|
+
- An app: no change is necessary. Its one served collection, `examples`, has no dot in its name.
|
|
766
|
+
- An app: no change is necessary. Its host serves no collection.
|
|
743
767
|
|
|
744
768
|
## 0.22.0
|
|
745
769
|
|
|
@@ -774,9 +798,9 @@ No changes in this release.
|
|
|
774
798
|
The migration steps of the known consumers:
|
|
775
799
|
|
|
776
800
|
- The site: no change. It imports none of these names. It names `HttpServerTransport` and `WebSocketServerTransport` only in the text of its journey.
|
|
777
|
-
-
|
|
778
|
-
-
|
|
779
|
-
-
|
|
801
|
+
- An app: no change. It imports none of these names, and its host uses `runProcedureHost`. Its `vite.config.ts` maps the root to `@procedures/client/browser`. The map can stay, because the root is also a browser entry.
|
|
802
|
+
- An app: no change. It imports none of these names.
|
|
803
|
+
- An app: no change. It imports none of these names.
|
|
780
804
|
- 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 this MINOR or a later version, import `WebSocketServerTransport` from `@procedures/client/node`.
|
|
781
805
|
- `headroom` (`packages/daemon/src/gateway.ts`) gives `checkBrowserRequest` of the root a request of `node:http`: no change.
|
|
782
806
|
|
|
@@ -805,9 +829,9 @@ No changes in this release.
|
|
|
805
829
|
- A custom transport or face that sends no credentials to a server with a token or a request hook now gets `UNAUTHORIZED`. Set the credentials of its request (`requestCredentials()`), or `LOCAL_CREDENTIALS` for a face in this process.
|
|
806
830
|
- Code that calls `server.handle()` of a server with a token or a request hook gives `credentials: LOCAL_CREDENTIALS`.
|
|
807
831
|
- The site: no change. Its servers have no token and no request hook, and its workers serve over `PortTransport`, which sets the marker.
|
|
808
|
-
-
|
|
809
|
-
-
|
|
810
|
-
-
|
|
832
|
+
- An app: no change. `scripts/dev.ts` starts a server without a token and without a request hook. Its HTTP and WebSocket faces set the credentials of each request.
|
|
833
|
+
- An app: no change. Its procedure host has a request hook and no token. All its faces send credentials: HTTP, WebSocket and MCP over Streamable HTTP (`mcpFace`). No code of the app calls `handle()` directly. Its MCP host operates over stdio, which is local.
|
|
834
|
+
- An app: no change. Its loopback server and its remote server have a request hook (`principalOf`), and the remote server has a token. `makeProcedureHandler` mounts `procedureHandler`, which sends the credentials of each request. A test that calls `handle()` of such a server gives `LOCAL_CREDENTIALS`, or credentials with the token.
|
|
811
835
|
|
|
812
836
|
## 0.18.1
|
|
813
837
|
|
|
@@ -827,9 +851,9 @@ No changes in this release.
|
|
|
827
851
|
|
|
828
852
|
- When a host fails with `CollectionTopicCollisionError`, rename the plain collection, for example `a.b` to `a_b`. A name without a dot has no topic of a partition.
|
|
829
853
|
- The site: no change is necessary. It serves no collection.
|
|
830
|
-
-
|
|
831
|
-
-
|
|
832
|
-
-
|
|
854
|
+
- An app: no change is necessary. Its server serves no collection.
|
|
855
|
+
- An app: no change is necessary. Its host gives partitions to each served collection (`examples`), and no collection has a plain storage.
|
|
856
|
+
- An app: no change is necessary. Its host serves no collection.
|
|
833
857
|
- 0379278: Docs and tests: the rule of the retryable flag of an in-band end (CLI-58). The behavior does not change, thus this change is a PATCH of the client group (decision D13).
|
|
834
858
|
|
|
835
859
|
- Before the stream starts, an error of a handler without a retryable flag gets the flag of its code in `ERROR_CODES` (CLI-48). Thus `UNAVAILABLE` without a flag is retryable, and the HTTP face answers 503.
|
|
@@ -840,7 +864,7 @@ No changes in this release.
|
|
|
840
864
|
- This rule agrees with the rule of a cut (CLI-48): the flag is false when the call can have had its effect.
|
|
841
865
|
- `WIRE-PROTOCOL.md` gives the rule in the section "Error codes". Tests pin it on the wire of HTTP and WebSocket, and on the HTTP, WebSocket and MCP faces of the procedures host.
|
|
842
866
|
|
|
843
|
-
|
|
867
|
+
Apps: no change.
|
|
844
868
|
|
|
845
869
|
## 0.18.0
|
|
846
870
|
|
|
@@ -882,9 +906,9 @@ No changes in this release.
|
|
|
882
906
|
- Code that matches the status 405 or 415 of a procedure server: match the status 403 and the reasons `method-not-allowed` and `media-type-not-allowed`.
|
|
883
907
|
- Code that reads `GuardResult.code` of `checkBrowserRequest()`: read `reason`.
|
|
884
908
|
- Code that matches the code `"500"` or the default code of `ServerError`: match `INTERNAL_ERROR`.
|
|
885
|
-
-
|
|
886
|
-
-
|
|
887
|
-
-
|
|
909
|
+
- Apps: no code of theirs matches a former code, so no change is necessary.
|
|
910
|
+
- An app: its dev server uses `HttpServerTransport`, and its answers change only as the table says.
|
|
911
|
+
- An app: its host uses `procedureHandler`, which gave the codes of wire v1 already.
|
|
888
912
|
|
|
889
913
|
## 0.17.4
|
|
890
914
|
|
|
@@ -945,9 +969,9 @@ No changes in this release.
|
|
|
945
969
|
- For each collection with partitions whose name has `%` or `.`, upgrade the publishers and the subscribers together.
|
|
946
970
|
- Build each topic rule of a collection with `collectionTopicRule()`. Do not join the parts yourself.
|
|
947
971
|
- The site: no change is necessary. It has no collection with partitions.
|
|
948
|
-
-
|
|
949
|
-
-
|
|
950
|
-
-
|
|
972
|
+
- An app: no change is necessary. It has no collection with partitions.
|
|
973
|
+
- An app: no change is necessary. The app has dotted names of collections, but no dotted name has partitions yet. When a dotted name gets partitions, build the rule of its host with `collectionTopicRule()`, not `collections.${c}.*`.
|
|
974
|
+
- An app: no change is necessary. It has no collection with partitions.
|
|
951
975
|
|
|
952
976
|
## 0.15.1
|
|
953
977
|
|
|
@@ -977,7 +1001,7 @@ No changes in this release.
|
|
|
977
1001
|
principalOf,
|
|
978
1002
|
limits: [
|
|
979
1003
|
{
|
|
980
|
-
name: "
|
|
1004
|
+
name: "app.writes",
|
|
981
1005
|
key: { claim: "tenant" },
|
|
982
1006
|
covers: { writes: true },
|
|
983
1007
|
policy: { type: "sliding-window", limit: { value: 120, unit: "count" }, window: { value: 1, unit: "min" } },
|
|
@@ -1037,9 +1061,9 @@ No changes in this release.
|
|
|
1037
1061
|
Migration:
|
|
1038
1062
|
|
|
1039
1063
|
- **Site.** No change. The site does not write collections.
|
|
1040
|
-
- **
|
|
1041
|
-
- **
|
|
1042
|
-
- **
|
|
1064
|
+
- **An app with `HybridStorage`.** No change for a storage or a `HybridStorage` without `versionOf`. A `HybridStorage` with `versionOf` over `ApiStorage` needs a server storage with the same `versionOf` (for example `new InMemoryStorage({ versionOf })`), or the option `sendBaseVersions: false`.
|
|
1065
|
+
- **An app with last-write-wins.** It gives no expected version, so nothing changes. Its own storage must refuse a write with an expected version until it tests one. Add the guard to its `set`, `delete` and `setBatch`, and run the contract suite: its first case tests the refusal. To adopt the version later, stamp a version field on the server, give the storage a `versionOf` that tests it in the write, and give the same `versionOf` to the `HybridStorage` of the client. Then add `createWithVersions` to the contract run.
|
|
1066
|
+
- **An app without versions.** No change: it gives no expected version. A storage of the app that implements `CollectionStorage` must refuse a write with an expected version, as above.
|
|
1043
1067
|
- **Other storages.** Each class that implements `CollectionStorage` reads the new options of `set`, `delete` and `setBatch`. It tests them in the write, or it rejects the write with `preconditionNotSupported()`. It never ignores them.
|
|
1044
1068
|
|
|
1045
1069
|
## 0.14.1
|
|
@@ -1073,9 +1097,9 @@ No changes in this release.
|
|
|
1073
1097
|
The migration steps of the known consumers:
|
|
1074
1098
|
|
|
1075
1099
|
- The site: no change. It imports none of these names.
|
|
1076
|
-
-
|
|
1077
|
-
-
|
|
1078
|
-
-
|
|
1100
|
+
- An app: no change. It imports none of these names. The server stub in `vite.config.ts` names `HttpServerTransport` and `WebSocketServerTransport`, and it can stay.
|
|
1101
|
+
- An app: no change. It imports none of these names.
|
|
1102
|
+
- An app: no change. It imports none of these names.
|
|
1079
1103
|
- 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`.
|
|
1080
1104
|
|
|
1081
1105
|
## 0.14.0
|
|
@@ -1108,16 +1132,16 @@ No changes in this release.
|
|
|
1108
1132
|
- A caller that finds a cut by the code `INTERNAL_ERROR`: look for `UNAVAILABLE` in its place. Do not retry the call when `retryable` is false.
|
|
1109
1133
|
- A handler that throws `UNAVAILABLE` with `retryable: false`: its HTTP status is 500 in place of 503. Without the flag, the error is retryable and gets 503. A retry middleware then sends the call again, so give `retryable: false` when the call can have had its effect.
|
|
1110
1134
|
- The site: no change is necessary. Its code does not read the code of a cut, or the HTTP status 503.
|
|
1111
|
-
-
|
|
1112
|
-
- The procedures host of
|
|
1113
|
-
-
|
|
1135
|
+
- An app: no change is necessary. Its code does not read `INTERNAL_ERROR`, `UNAVAILABLE` or the severity of an error.
|
|
1136
|
+
- The procedures host of an app (APP-11): no change is necessary. Its code does not read `INTERNAL_ERROR`. Its error "the server has no AGENT_TOKEN" is `UNAVAILABLE` with `retryable: false`, so its HTTP status is 500 in place of 503. No code of the app reads that status.
|
|
1137
|
+
- An app: no change is necessary. Its drain test already expects `UNAVAILABLE` with `retryable: false` for a cut procedure call (S6 A12). Its code reads only `NOT_FOUND` and `FORBIDDEN`.
|
|
1114
1138
|
- The `mark` CLI and `procedure-server`: no change is necessary. The lifecycle test of CI-2 expects `UNAVAILABLE` for the cut of `lifecycle.ticksOnce`.
|
|
1115
1139
|
|
|
1116
1140
|
## 0.13.2
|
|
1117
1141
|
|
|
1118
1142
|
### Patch Changes
|
|
1119
1143
|
|
|
1120
|
-
- 3a235b9: New: the patch operations `$remove` and `$insert
|
|
1144
|
+
- 3a235b9: New: the patch operations `$remove` and `$insert`. `$remove` takes an element out of an array, and the next elements move down by one, as the operation `remove` of JSON Patch (RFC 6902). For a field of an object, it is the same as `$unset`. `$insert` adds an element to an array at an index, as the operation `add` of JSON Patch. Each index of one patch refers to the item before the patch. A patch that removes and inserts elements of the same array is refused, and so is an `$insert` past the end of an array. `$unset` keeps the rule of MongoDB: an element of an array becomes `null`. The storage contract has a case for the two operations, so each storage gets them through `applyPatch`.
|
|
1121
1145
|
|
|
1122
1146
|
## 0.13.1
|
|
1123
1147
|
|
|
@@ -1148,10 +1172,10 @@ No changes in this release.
|
|
|
1148
1172
|
- A host with an `expose` rule must list the collection procedures that it serves, for example `collections.notes.*`. `host.*` and `events.subscribe` stay always on.
|
|
1149
1173
|
- An app that pins its own procedures with `registerProcedures()` on a server with an expose rule: list them in the rule. Give `{ alwaysOn: true }` only to a procedure of the host itself.
|
|
1150
1174
|
- The site: no change is necessary. Its servers have no expose rule.
|
|
1151
|
-
-
|
|
1175
|
+
- An app: no change is necessary. Its server has an expose rule, but it pins no procedure and serves no collection.
|
|
1152
1176
|
- The `mark` CLI and `procedure-server`: no change is necessary. They serve no collection, and `--expose` keeps `host.*` and `events.subscribe` on.
|
|
1153
|
-
-
|
|
1154
|
-
- The procedures host of
|
|
1177
|
+
- An app: no change is necessary. Its host has no expose rule.
|
|
1178
|
+
- The procedures host of an app (APP-11): no change is necessary. Its rule `["collections.*", "app.*"]` lists the collection procedures. To hide `clear`, an `exclude` of the policy now has an effect.
|
|
1155
1179
|
|
|
1156
1180
|
## 0.12.2
|
|
1157
1181
|
|
|
@@ -1200,9 +1224,9 @@ No changes in this release.
|
|
|
1200
1224
|
|
|
1201
1225
|
Migration steps:
|
|
1202
1226
|
|
|
1203
|
-
- The site and
|
|
1204
|
-
- The MCP host of
|
|
1205
|
-
-
|
|
1227
|
+
- The site and an app: no change is necessary, unless they read `/health` of a peer. Then call `host.info` with the token.
|
|
1228
|
+
- The MCP host of an app: no change is necessary. To share the port of its procedures host, mount `mcpFace()` on its listener.
|
|
1229
|
+
- Apps under `run()`: build the procedures with `createProcedureHost()`, and call `host.declare(svc)` in the service of the process. Give `listen` for a port of the host, or mount `host.handler` and `host.upgrade` on the listener of the app.
|
|
1206
1230
|
- A caller of `createPeer()` with a different token for each transport: give one token.
|
|
1207
1231
|
- A Docker `HEALTHCHECK` or a probe of Kubernetes that read `/health` of a peer: use the probes of the service. Give the service `probeServer({ port, server_retry_after })` on a port of its own, or mount `probeHandler(health, { prefix: "/health" })` on the port of the app. Both come from `@mark1russell7/service/http`, and they answer `/health/startup`, `/health/readiness` and `/health/liveness`. The lockfile check of a client calls `host.info` with the token of the lockfile.
|
|
1208
1232
|
- A test that read `/health` of a peer: call `host.info` with the token, or check the status 404.
|
|
@@ -1230,8 +1254,8 @@ No changes in this release.
|
|
|
1230
1254
|
|
|
1231
1255
|
Migration steps:
|
|
1232
1256
|
|
|
1233
|
-
- The site,
|
|
1234
|
-
-
|
|
1257
|
+
- The site, an app and the MCP host of another app: no change is necessary. `stop({ grace })` keeps its result. Change `server.callsInFlight` to `server.inFlight()`.
|
|
1258
|
+
- Apps under `run()`: declare the parts in the service of the process. Do not call `stop()`. Declare `svc.server("procedures", {}, server)`, and declare each handle of `server.storageHandles()` with `svc.dependency(handle.name, spec, handle)`. Give the server and `run()` the same clock, with the option `clock` of each.
|
|
1235
1259
|
- A test with a fake clock that calls `stop({ grace })` with calls in flight: advance the clock by the grace, or stop without a grace.
|
|
1236
1260
|
|
|
1237
1261
|
## 0.9.2
|
|
@@ -1344,14 +1368,14 @@ No changes in this release.
|
|
|
1344
1368
|
- The option `origin` of `HybridStorage` is the tag of the storage (a random `hybrid-…` tag by default). Each write of the storage to the local copy and to the remote has it. The write methods of `HybridStorage` and `ApiStorage` take `{ origin }`.
|
|
1345
1369
|
- `capture: "observe"`: the storage observes the local copy and queues each change with another origin. Thus an application can write to the local copy directly, for example with the synchronous writes of a SignalDB collection. In `write-through` and `remote-only` mode, the storage sends a captured change at once.
|
|
1346
1370
|
- The option `syncState` takes a `SyncStateStore`: `MemorySyncStateStore`, or `IndexedDbSyncStateStore` of `@procedures/store/indexeddb`. The store keeps the cursor and the base versions. A new storage with the same store and a durable local copy asks only for the changes since the cursor, and it finds the conflicts of the base versions. A failure of the store goes to the status (`operation: "store"`, `SyncStateError`), and the storage goes on.
|
|
1347
|
-
- The option `feed` takes a `RemoteChangeFeed`. A delta whose `since` is the cursor applies without a read of the remote. A gap, a lost event, a new subscription or another delta makes one pull. A delta that comes during a pull applies after the pull, so the pull does not erase it
|
|
1371
|
+
- The option `feed` takes a `RemoteChangeFeed`. A delta whose `since` is the cursor applies without a read of the remote. A gap, a lost event, a new subscription or another delta makes one pull. A delta that comes during a pull applies after the pull, so the pull does not erase it.
|
|
1348
1372
|
- In `write-through` mode, a pull or a delta does not write over an own write that waits for the remote, a set or a delete. The storage keeps the remote value of the id, and after the write it reads the id again: then the rules of a pull decide. A read of a missing id does not bring back an item whose own delete waits.
|
|
1349
|
-
- With `versionOf`, the storage keeps the versions of its own writes until their echoes come (option `echoWindow`, 30 seconds by default). The echo of an older own write does not write over a newer local write
|
|
1373
|
+
- With `versionOf`, the storage keeps the versions of its own writes until their echoes come (option `echoWindow`, 30 seconds by default). The echo of an older own write does not write over a newer local write.
|
|
1350
1374
|
- `EventsChangeFeed` of `@procedures/store` is the feed of the change events. Its source is a `Client`, a `WebSocketTransport` or another transport. It treats the events as hints: a gap of the numbers, a lost event, a hint and each confirmation of the subscription call `onGap()`.
|
|
1351
1375
|
- The core collection procedures publish `CollectionChangeEvent` `{ since, version, changed, deleted, origin }` on `ctx.bus`, under the topic `collections.<name>` (`collectionChangeTopic()`), while a subscriber listens. The changes come from `getChangesSince()` of the storage, and the events of one storage make a chain of versions. The option `changeEvents` of `createCollectionProcedures()` turns them off, or gives the topic of each call: the partition of CLI-17 goes there.
|
|
1352
1376
|
- A value reaches a subscriber only through the checks of a read. By default, an event has the ids and the versions only, and `EventsChangeFeed` gives it to `onHint()`: `HybridStorage` reads the values with `changes`, and a hint with only deletes applies without a read. With `changeEvents: { values: true }`, an event also has `values`: each row `{ id, value }` passes the output filter of the host (`admitItem`) for each subscriber, and a refused id goes in `withheld`, so the storage pulls it.
|
|
1353
1377
|
- `EventPublisher` refuses a topic whose reads the capability of the call does not permit (`FORBIDDEN`, `effects-exceeded`). Its new option `reads` gives the reads of a topic. The default, `collectionTopicReads()`, gives `collection:<name>` for `collections.<name>` and `collections.<name>.<partition>`. `ctx.admit` gives a procedure the output filter of its host for the data that it sends later.
|
|
1354
|
-
- The syncs of one `HybridStorage` run one at a time: the deltas and the hints of the feed, the pulls, the pushes, the reads after an own write and the mode switches. A remote delta and a full sync never run at the same time
|
|
1378
|
+
- The syncs of one `HybridStorage` run one at a time: the deltas and the hints of the feed, the pulls, the pushes, the reads after an own write and the mode switches. A remote delta and a full sync never run at the same time.
|
|
1355
1379
|
- The write inputs of the collection procedures take an optional `origin` (1 to 256 characters). The procedure gives it to the storage and to the event. A server before this change ignores the field.
|
|
1356
1380
|
- `Client.subscribe()` and `Client.events()` subscribe to the topics of the bus of the server through the middleware and the context of the client. A subscription has no deadline: the timeouts of the client do not apply to it, and only `metadata: { timeout }` in its options gives one.
|
|
1357
1381
|
- New exports: `collectionChangeTopic`, `CollectionChangeEvent` and `CollectionChangeEventsOptions` from `@procedures/client`, `./browser` and `./procedures`. `EventsChangeFeed`, `MemorySyncStateStore`, `SyncStateError` and the types `RemoteChangeFeed`, `RemoteChangeListener`, `RemoteChanges`, `EventSubscriber`, `ChangeEventSource`, `EventsChangeFeedOptions`, `SyncState`, `SyncStateChange` and `SyncStateStore` from `@procedures/store`. `IndexedDbSyncStateStore` and `MemorySyncStateStore` from `@procedures/store/indexeddb`.
|
|
@@ -1420,7 +1444,7 @@ No changes in this release.
|
|
|
1420
1444
|
|
|
1421
1445
|
### Patch Changes
|
|
1422
1446
|
|
|
1423
|
-
- 389b054: A token check no longer tells the length of the token through its time. The peer compares the SHA-256 digests of the two tokens with `timingSafeEqual`. The `tokenMatches` of the client, which runs in a browser too, compares each character of the expected token for each presented token. Before, a token of another length returned at once.
|
|
1447
|
+
- 389b054: A token check no longer tells the length of the token through its time. The peer compares the SHA-256 digests of the two tokens with `timingSafeEqual`. The `tokenMatches` of the client, which runs in a browser too, compares each character of the expected token for each presented token. Before, a token of another length returned at once. A re-audit found it.
|
|
1424
1448
|
|
|
1425
1449
|
## 0.6.0
|
|
1426
1450
|
|
package/README.md
CHANGED
|
@@ -693,7 +693,7 @@ http.listen(4820);
|
|
|
693
693
|
- An `OPTIONS` request gets 204 and starts no procedure.
|
|
694
694
|
- `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.
|
|
695
695
|
- 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`.
|
|
696
|
-
- `secretHeaders` names more headers that carry a secret, for example `X-
|
|
696
|
+
- `secretHeaders` names more headers that carry a secret, for example `X-App-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.
|
|
697
697
|
- `handler.middleware` mounts the handler in Connect or Express. A request outside `basePath` goes to `next`.
|
|
698
698
|
- 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.
|
|
699
699
|
|
|
@@ -743,9 +743,9 @@ const server = new ProcedureServer({
|
|
|
743
743
|
capability: { clearance: "intimate" },
|
|
744
744
|
principalOf: ({ cookies = {}, headers = {}, query = {} }) => ({
|
|
745
745
|
// The token of a cookie, of an application header or of the query
|
|
746
|
-
bearer: cookies["
|
|
746
|
+
bearer: cookies["app_token"] ?? headers["x-app-token"] ?? query["token"],
|
|
747
747
|
// A guest switch can only make the capability narrower
|
|
748
|
-
...(cookies["
|
|
748
|
+
...(cookies["app_audience"] ? { narrowing: { clearance: cookies["app_audience"] } } : {}),
|
|
749
749
|
}),
|
|
750
750
|
});
|
|
751
751
|
```
|