@procedures/client 0.6.0 → 0.7.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.
Files changed (47) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/README.md +43 -4
  3. package/dist/.tsbuildinfo +1 -1
  4. package/dist/adapters/http/client/transport.d.ts +5 -0
  5. package/dist/adapters/http/client/transport.d.ts.map +1 -1
  6. package/dist/adapters/http/client/transport.js +10 -4
  7. package/dist/adapters/http/client/transport.js.map +1 -1
  8. package/dist/adapters/http/server/ndjson.d.ts +73 -0
  9. package/dist/adapters/http/server/ndjson.d.ts.map +1 -0
  10. package/dist/adapters/http/server/ndjson.js +228 -0
  11. package/dist/adapters/http/server/ndjson.js.map +1 -0
  12. package/dist/adapters/http/server/transport.d.ts +9 -4
  13. package/dist/adapters/http/server/transport.d.ts.map +1 -1
  14. package/dist/adapters/http/server/transport.js +19 -68
  15. package/dist/adapters/http/server/transport.js.map +1 -1
  16. package/dist/adapters/http/server/types.d.ts +15 -0
  17. package/dist/adapters/http/server/types.d.ts.map +1 -1
  18. package/dist/adapters/sequence.d.ts +14 -0
  19. package/dist/adapters/sequence.d.ts.map +1 -1
  20. package/dist/adapters/sequence.js +16 -0
  21. package/dist/adapters/sequence.js.map +1 -1
  22. package/dist/browser.d.ts +1 -1
  23. package/dist/browser.d.ts.map +1 -1
  24. package/dist/browser.js +3 -2
  25. package/dist/browser.js.map +1 -1
  26. package/dist/node.d.ts +6 -0
  27. package/dist/node.d.ts.map +1 -1
  28. package/dist/node.js +5 -0
  29. package/dist/node.js.map +1 -1
  30. package/dist/server/procedure-server.d.ts +4 -2
  31. package/dist/server/procedure-server.d.ts.map +1 -1
  32. package/dist/server/procedure-server.js +8 -5
  33. package/dist/server/procedure-server.js.map +1 -1
  34. package/dist/timers.d.ts +4 -0
  35. package/dist/timers.d.ts.map +1 -1
  36. package/dist/timers.js +3 -0
  37. package/dist/timers.js.map +1 -1
  38. package/package.json +1 -1
  39. package/src/adapters/http/client/transport.ts +10 -4
  40. package/src/adapters/http/server/ndjson.ts +259 -0
  41. package/src/adapters/http/server/transport.ts +20 -68
  42. package/src/adapters/http/server/types.ts +17 -0
  43. package/src/adapters/sequence.ts +18 -0
  44. package/src/browser.ts +3 -2
  45. package/src/node.ts +6 -0
  46. package/src/server/procedure-server.ts +8 -5
  47. package/src/timers.ts +7 -0
package/CHANGELOG.md CHANGED
@@ -1,5 +1,22 @@
1
1
  # @procedures/client
2
2
 
3
+ ## 0.7.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 841d083: An NDJSON stream over HTTP gets keep-alive lines. Before, a proxy or a client with an idle timeout (for example 300 s) closed a long procedure that was quiet for that time.
8
+
9
+ - `HttpServerTransport` writes a keep-alive line, a blank line, after each quiet time of the new option `keepAlive` (default `seconds(15)`, `TIMER_DEFAULTS.httpServer.keepAliveMs`). Each line starts the time again. No keep-alive line comes after the `done` line, an `error` line, an abort or a closed connection. `keepAlive: false` turns it off.
10
+ - The new option `clock` of `HttpServerTransport` is the clock of the keep-alive timers. A test gives the `fakeClock` of `@mark1russell7/service/testing`.
11
+ - A keep-alive line has no `seq`, so the sequence check of the reader sees no gap. `WIRE-PROTOCOL.md` specifies the line: it is an additive change of protocol v1, because each reader skipped a blank line before.
12
+ - New `writeNdjsonStream(res, items, options?)` in `@procedures/client/node`. It writes the NDJSON stream response of protocol v1 for a `ServerResponse` of `node:http`, without Express. It writes the headers, the `item`, `done` and `error` lines with `seq`, and the keep-alive lines. It waits for `drain` when the buffer is full, and it stops when the connection closes or `signal` aborts. Its options are `signal`, `keepAlive`, `errorOf` and `clock`. `HttpServerTransport` uses it, so the two write the same bytes.
13
+ - `HttpTransport` gives each item of an NDJSON stream the metadata key `stream` with the value `true` (the new constant `STREAM_ITEM_METADATA_KEY`). The error item that ends the stream has it too. The key does not cross the wire, and the client removes a key `stream` that the peer sent.
14
+ - When the client goes away while the handler is quiet, the writer of the stream stops at once. Before, it waited for the next item of a handler that ignores its signal.
15
+
16
+ ### Patch Changes
17
+
18
+ - 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. The re-audit of jarvis found it.
19
+
3
20
  ## 0.6.0
4
21
 
5
22
  No changes in this release.
package/README.md CHANGED
@@ -567,13 +567,52 @@ await server.stop()
567
567
  new HttpServerTransport(server: Server, options: HttpServerTransportOptions)
568
568
 
569
569
  interface HttpServerTransportOptions {
570
- port: number;
571
- hostname?: string;
570
+ app: Express; // required
571
+ httpServer?: HttpServer; // an existing server: the transport does not listen
572
+ port?: number; // default: 3000
573
+ host?: string; // default: "127.0.0.1"
574
+ basePath?: string; // default: "/api"
572
575
  urlStrategy?: HttpUrlStrategy;
573
- cors?: boolean | CorsOptions;
576
+ cors?: boolean;
577
+ corsOptions?: { origin?: string | string[]; methods?: string[]; allowedHeaders?: string[]; credentials?: boolean };
578
+ bodyLimit?: number; // default: 1 MiB
579
+ keepAlive?: Duration | false; // default: seconds(15)
580
+ clock?: Clock; // the clock of the keep-alive timers
581
+ }
582
+ ```
583
+
584
+ A client that accepts `application/x-ndjson` gets a stream as NDJSON lines ([WIRE-PROTOCOL.md](../documentation/WIRE-PROTOCOL.md)).
585
+
586
+ - After each quiet time of `keepAlive`, the server writes a keep-alive line: a blank line. Thus a proxy or a client with an idle timeout does not close a long, quiet stream.
587
+ - Each line starts the quiet time again. No keep-alive line comes after the end, an error, an abort or a closed connection.
588
+ - `keepAlive: false` turns the keep-alive lines off.
589
+ - The HTTP client skips each blank line. Each item that it reads from an NDJSON stream has the metadata key `stream: true` (`STREAM_ITEM_METADATA_KEY`).
590
+
591
+ A server without Express writes the same lines with `writeNdjsonStream` of `@procedures/client/node`:
592
+
593
+ ```typescript
594
+ import { createServer } from "node:http";
595
+ import { seconds } from "@procedures/client";
596
+ import { writeNdjsonStream } from "@procedures/client/node";
597
+
598
+ async function* progress() {
599
+ for (let step = 1; step <= 3; step++) {
600
+ await new Promise((resolve) => setTimeout(resolve, 60_000)); // a quiet minute: 4 keep-alive lines
601
+ yield { step };
602
+ }
574
603
  }
604
+
605
+ createServer((req, res) => {
606
+ // The headers, the item, done and error lines with seq, the keep-alive lines and the backpressure
607
+ void writeNdjsonStream(res, progress(), {
608
+ keepAlive: seconds(15),
609
+ errorOf: (error) => ({ code: "UNAVAILABLE", message: String(error), retryable: true }),
610
+ });
611
+ }).listen(3000);
575
612
  ```
576
613
 
614
+ The promise of `writeNdjsonStream` resolves when the response ends. A closed connection or an abort of `signal` stops the stream, and the iterator of the items gets `return()`.
615
+
577
616
  #### WebSocket Server Transport
578
617
  ```typescript
579
618
  new WebSocketServerTransport(server: Server, options: WebSocketServerTransportOptions)
@@ -642,7 +681,7 @@ import { ... } from "@procedures/client/events";
642
681
  |---|---|
643
682
  | `@procedures/client` | Node. The browser entry and the server transports. Its `WebSocketTransport` uses the global `WebSocket`. |
644
683
  | `@procedures/client/browser` | A browser bundle. It does not import `http` or `ws`. |
645
- | `@procedures/client/node` | Node. A `WebSocketTransport` whose sockets are of the `ws` package: a drop ends a socket at once. |
684
+ | `@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`. |
646
685
  | `@procedures/client/register` | It registers the core procedures in the global registry. |
647
686
 
648
687
  ## Procedure Discovery