@replit/river 0.7.2 → 0.8.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.
Files changed (56) hide show
  1. package/README.md +2 -0
  2. package/dist/__tests__/bandwidth.bench.js +6 -6
  3. package/dist/__tests__/e2e.test.js +112 -23
  4. package/dist/__tests__/fixtures/cleanup.d.ts +12 -0
  5. package/dist/__tests__/fixtures/cleanup.d.ts.map +1 -0
  6. package/dist/__tests__/fixtures/cleanup.js +39 -0
  7. package/dist/__tests__/fixtures/observable.d.ts +26 -0
  8. package/dist/__tests__/fixtures/observable.d.ts.map +1 -0
  9. package/dist/__tests__/fixtures/observable.js +38 -0
  10. package/dist/__tests__/fixtures/observable.test.d.ts +2 -0
  11. package/dist/__tests__/fixtures/observable.test.d.ts.map +1 -0
  12. package/dist/__tests__/fixtures/observable.test.js +39 -0
  13. package/dist/__tests__/{fixtures.d.ts → fixtures/services.d.ts} +61 -18
  14. package/dist/__tests__/fixtures/services.d.ts.map +1 -0
  15. package/dist/__tests__/{fixtures.js → fixtures/services.js} +35 -3
  16. package/dist/__tests__/handler.test.js +24 -7
  17. package/dist/__tests__/invariants.test.d.ts +2 -0
  18. package/dist/__tests__/invariants.test.d.ts.map +1 -0
  19. package/dist/__tests__/invariants.test.js +136 -0
  20. package/dist/__tests__/serialize.test.js +2 -1
  21. package/dist/router/builder.d.ts +10 -4
  22. package/dist/router/builder.d.ts.map +1 -1
  23. package/dist/router/client.d.ts +14 -5
  24. package/dist/router/client.d.ts.map +1 -1
  25. package/dist/router/client.js +42 -11
  26. package/dist/router/server.d.ts +14 -0
  27. package/dist/router/server.d.ts.map +1 -1
  28. package/dist/router/server.js +85 -48
  29. package/dist/transport/impls/stdio/stdio.d.ts +0 -4
  30. package/dist/transport/impls/stdio/stdio.d.ts.map +1 -1
  31. package/dist/transport/impls/stdio/stdio.js +0 -5
  32. package/dist/transport/impls/stdio/stdio.test.js +6 -1
  33. package/dist/transport/impls/ws/client.d.ts.map +1 -1
  34. package/dist/transport/impls/ws/client.js +2 -2
  35. package/dist/transport/impls/ws/connection.d.ts.map +1 -1
  36. package/dist/transport/impls/ws/connection.js +2 -1
  37. package/dist/transport/impls/ws/server.d.ts +0 -2
  38. package/dist/transport/impls/ws/server.d.ts.map +1 -1
  39. package/dist/transport/impls/ws/server.js +4 -9
  40. package/dist/transport/impls/ws/ws.test.js +31 -11
  41. package/dist/transport/index.d.ts +3 -3
  42. package/dist/transport/index.d.ts.map +1 -1
  43. package/dist/transport/index.js +1 -1
  44. package/dist/transport/message.d.ts +10 -0
  45. package/dist/transport/message.d.ts.map +1 -1
  46. package/dist/transport/message.js +15 -0
  47. package/dist/transport/transport.d.ts +37 -11
  48. package/dist/transport/transport.d.ts.map +1 -1
  49. package/dist/transport/transport.js +37 -13
  50. package/dist/{testUtils.d.ts → util/testHelpers.d.ts} +27 -8
  51. package/dist/util/testHelpers.d.ts.map +1 -0
  52. package/dist/{testUtils.js → util/testHelpers.js} +51 -5
  53. package/package.json +3 -3
  54. package/dist/__tests__/fixtures.d.ts.map +0 -1
  55. package/dist/testUtils.d.ts.map +0 -1
  56. /package/dist/__tests__/{largePayload.json → fixtures/largePayload.json} +0 -0
@@ -2,11 +2,15 @@ import { Value } from '@sinclair/typebox/value';
2
2
  import { OpaqueTransportMessageSchema, TransportAckSchema, isAck, reply, } from './message';
3
3
  import { log } from '../logging';
4
4
  /**
5
- * Abstract base for a connection between two nodes in a River network.
6
- * A connection is responsible for sending and receiving messages on a 1:1
7
- * basis between nodes.
8
- * Connections can be reused across different transports.
9
- * @abstract
5
+ * A 1:1 connection between two transports. Once this is created,
6
+ * the {@link Connection} is expected to take over responsibility for
7
+ * reading and writing messages from the underlying connection.
8
+ *
9
+ * 1) Messages received on the {@link Connection} are dispatched back to the {@link Transport}
10
+ * via {@link Transport.onMessage}. The {@link Transport} then notifies any registered message listeners.
11
+ * 2) When {@link Transport.send}(msg) is called, the transport looks up the appropriate
12
+ * connection in the {@link connections} map via `msg.to` and calls {@link send}(bytes)
13
+ * so the connection can send it.
10
14
  */
11
15
  export class Connection {
12
16
  connectedTo;
@@ -15,15 +19,35 @@ export class Connection {
15
19
  this.connectedTo = connectedTo;
16
20
  this.transport = transport;
17
21
  }
18
- onMessage(msg) {
19
- return this.transport.onMessage(msg);
20
- }
21
22
  }
22
23
  /**
23
- * Abstract base for a transport layer for communication between nodes in a River network.
24
- * A transport is responsible for handling the 1:n connection logic between nodes and
25
- * delegating sending/receiving to connections.
26
- * Any River transport methods need to implement this interface.
24
+ * Transports manage the lifecycle (creation/deletion) of connections. Its responsibilities include:
25
+ *
26
+ * 1) Constructing a new {@link Connection} on {@link TransportMessage}s from new clients.
27
+ * After constructing the {@link Connection}, {@link onConnect} is called which adds it to the connection map.
28
+ * 2) Delegating message listening of the connection to the newly created {@link Connection}.
29
+ * From this point on, the {@link Connection} is responsible for *reading* and *writing*
30
+ * messages from the connection.
31
+ * 3) When a connection is closed, the {@link Transport} calls {@link onDisconnect} which closes the
32
+ * connection via {@link Connection.close} and removes it from the {@link connections} map.
33
+
34
+ *
35
+ * ```plaintext
36
+ * ▲
37
+ * incoming │
38
+ * messages │
39
+ * ▼
40
+ * ┌─────────────┐ 1:N ┌────────────┐
41
+ * │ Transport │ ◄─────► │ Connection │
42
+ * └─────────────┘ └────────────┘
43
+ * ▲
44
+ * │
45
+ * ▼
46
+ * ┌───────────┐
47
+ * │ Message │
48
+ * │ Listeners │
49
+ * └───────────┘
50
+ * ```
27
51
  * @abstract
28
52
  */
29
53
  export class Transport {
@@ -91,7 +115,7 @@ export class Transport {
91
115
  }
92
116
  this.send(msg);
93
117
  }
94
- this.sendQueue.set(conn.connectedTo, []);
118
+ this.sendQueue.delete(conn.connectedTo);
95
119
  }
96
120
  /**
97
121
  * The downstream implementation needs to call this when a connection is closed.
@@ -2,14 +2,14 @@
2
2
  import WebSocket from 'isomorphic-ws';
3
3
  import { WebSocketServer } from 'ws';
4
4
  import http from 'http';
5
- import { WebSocketClientTransport } from './transport/impls/ws/client';
5
+ import { WebSocketClientTransport } from '../transport/impls/ws/client';
6
6
  import { Static, TObject } from '@sinclair/typebox';
7
- import { Procedure, ServiceContext } from './router';
8
- import { OpaqueTransportMessage, TransportClientId, TransportMessage } from './transport';
7
+ import { Procedure, ServiceContext } from '../router';
8
+ import { OpaqueTransportMessage, TransportClientId, TransportMessage } from '../transport';
9
9
  import { Pushable } from 'it-pushable';
10
- import { Result, RiverError, RiverUncaughtSchema } from './router/result';
11
- import { Codec } from './codec';
12
- import { WebSocketServerTransport } from './transport/impls/ws/server';
10
+ import { Result, RiverError, RiverUncaughtSchema } from '../router/result';
11
+ import { Codec } from '../codec';
12
+ import { WebSocketServerTransport } from '../transport/impls/ws/server';
13
13
  /**
14
14
  * Creates a WebSocket server instance using the provided HTTP server.
15
15
  * Only used as helper for testing.
@@ -61,12 +61,25 @@ export declare function asClientRpc<State extends object | unknown, I extends TO
61
61
  * @param {State} state - The state object.
62
62
  * @param {Procedure<State, 'stream', I, O>} proc - The procedure to handle the stream.
63
63
  * @param {Omit<ServiceContext, 'state'>} [extendedContext] - The extended context object.
64
- * @returns {[Pushable<Static<I>>, Pushable<Static<O>>]} - Pair of input and output streams.
64
+ * @returns Pair of input and output streams.
65
65
  */
66
66
  export declare function asClientStream<State extends object | unknown, I extends TObject, O extends TObject, E extends RiverError>(state: State, proc: Procedure<State, 'stream', I, O, E>, extendedContext?: Omit<ServiceContext, 'state'>): [
67
67
  Pushable<Static<I>>,
68
68
  Pushable<Result<Static<O>, Static<E> | Static<typeof RiverUncaughtSchema>>>
69
69
  ];
70
+ /**
71
+ * Transforms a subscription procedure definition into a procedure that returns an output stream.
72
+ * Input messages can be pushed into the input stream.
73
+ * This should only be used for testing.
74
+ * @template State - The type of the state object.
75
+ * @template I - The type of the input object.
76
+ * @template O - The type of the output object.
77
+ * @param {State} state - The state object.
78
+ * @param {Procedure<State, 'stream', I, O>} proc - The procedure to handle the stream.
79
+ * @param {Omit<ServiceContext, 'state'>} [extendedContext] - The extended context object.
80
+ * @returns A function that when passed a message, returns the output stream.
81
+ */
82
+ export declare function asClientSubscription<State extends object | unknown, I extends TObject, O extends TObject, E extends RiverError>(state: State, proc: Procedure<State, 'subscription', I, O, E>, extendedContext?: Omit<ServiceContext, 'state'>): (msg: Static<I>) => Promise<Pushable<Result<Static<O>, Static<E> | Static<typeof RiverUncaughtSchema>>>>;
70
83
  /**
71
84
  * Converts a payload object to a transport message with reasonable defaults.
72
85
  * This should only be used for testing.
@@ -80,4 +93,10 @@ export declare function payloadToTransportMessage<Payload extends object>(payloa
80
93
  * @returns The created opaque transport message.
81
94
  */
82
95
  export declare function createDummyTransportMessage(): OpaqueTransportMessage;
83
- //# sourceMappingURL=testUtils.d.ts.map
96
+ /**
97
+ * Retrieves the next value from an async iterable iterator.
98
+ * @param iter The async iterable iterator.
99
+ * @returns A promise that resolves to the next value from the iterator.
100
+ */
101
+ export declare function iterNext<T>(iter: AsyncIterableIterator<T>): Promise<any>;
102
+ //# sourceMappingURL=testHelpers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"testHelpers.d.ts","sourceRoot":"","sources":["../../util/testHelpers.ts"],"names":[],"mappings":"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"}
@@ -1,10 +1,10 @@
1
1
  import WebSocket from 'isomorphic-ws';
2
2
  import { WebSocketServer } from 'ws';
3
- import { WebSocketClientTransport } from './transport/impls/ws/client';
4
- import { msg, reply, } from './transport';
3
+ import { WebSocketClientTransport } from '../transport/impls/ws/client';
4
+ import { msg, reply, } from '../transport';
5
5
  import { pushable } from 'it-pushable';
6
- import { Err, UNCAUGHT_ERROR, } from './router/result';
7
- import { WebSocketServerTransport } from './transport/impls/ws/server';
6
+ import { Err, UNCAUGHT_ERROR, } from '../router/result';
7
+ import { WebSocketServerTransport } from '../transport/impls/ws/server';
8
8
  /**
9
9
  * Creates a WebSocket server instance using the provided HTTP server.
10
10
  * Only used as helper for testing.
@@ -91,7 +91,7 @@ export function asClientRpc(state, proc, extendedContext) {
91
91
  * @param {State} state - The state object.
92
92
  * @param {Procedure<State, 'stream', I, O>} proc - The procedure to handle the stream.
93
93
  * @param {Omit<ServiceContext, 'state'>} [extendedContext] - The extended context object.
94
- * @returns {[Pushable<Static<I>>, Pushable<Static<O>>]} - Pair of input and output streams.
94
+ * @returns Pair of input and output streams.
95
95
  */
96
96
  export function asClientStream(state, proc, extendedContext) {
97
97
  const rawInput = pushable({ objectMode: true });
@@ -133,6 +133,44 @@ export function asClientStream(state, proc, extendedContext) {
133
133
  })();
134
134
  return [rawInput, rawOutput];
135
135
  }
136
+ /**
137
+ * Transforms a subscription procedure definition into a procedure that returns an output stream.
138
+ * Input messages can be pushed into the input stream.
139
+ * This should only be used for testing.
140
+ * @template State - The type of the state object.
141
+ * @template I - The type of the input object.
142
+ * @template O - The type of the output object.
143
+ * @param {State} state - The state object.
144
+ * @param {Procedure<State, 'stream', I, O>} proc - The procedure to handle the stream.
145
+ * @param {Omit<ServiceContext, 'state'>} [extendedContext] - The extended context object.
146
+ * @returns A function that when passed a message, returns the output stream.
147
+ */
148
+ export function asClientSubscription(state, proc, extendedContext) {
149
+ const rawOutput = pushable({
150
+ objectMode: true,
151
+ });
152
+ const transportOutput = pushable({
153
+ objectMode: true,
154
+ });
155
+ // unwrap from transport
156
+ (async () => {
157
+ for await (const transportRes of transportOutput) {
158
+ rawOutput.push(transportRes.payload);
159
+ }
160
+ })();
161
+ return async (msg) => {
162
+ proc
163
+ .handler({ ...extendedContext, state }, payloadToTransportMessage(msg), transportOutput)
164
+ .catch((err) => {
165
+ const errorMsg = err instanceof Error ? err.message : `[coerced to error] ${err}`;
166
+ return Err({
167
+ code: UNCAUGHT_ERROR,
168
+ message: errorMsg,
169
+ });
170
+ });
171
+ return rawOutput;
172
+ };
173
+ }
136
174
  /**
137
175
  * Converts a payload object to a transport message with reasonable defaults.
138
176
  * This should only be used for testing.
@@ -153,3 +191,11 @@ export function createDummyTransportMessage() {
153
191
  test: Math.random(),
154
192
  });
155
193
  }
194
+ /**
195
+ * Retrieves the next value from an async iterable iterator.
196
+ * @param iter The async iterable iterator.
197
+ * @returns A promise that resolves to the next value from the iterator.
198
+ */
199
+ export function iterNext(iter) {
200
+ return iter.next().then((res) => res.value);
201
+ }
package/package.json CHANGED
@@ -2,13 +2,13 @@
2
2
  "name": "@replit/river",
3
3
  "sideEffects": false,
4
4
  "description": "It's like tRPC but... with JSON Schema Support, duplex streaming and support for service multiplexing. Transport agnostic!",
5
- "version": "0.7.2",
5
+ "version": "0.8.1",
6
6
  "type": "module",
7
7
  "exports": {
8
8
  ".": "./dist/router/index.js",
9
9
  "./logging": "./dist/logging/index.js",
10
10
  "./codec": "./dist/codec/index.js",
11
- "./test-util": "./dist/testUtils.js",
11
+ "./test-util": "./dist/util/testHelpers.js",
12
12
  "./transport": "./dist/transport/index.js",
13
13
  "./transport/ws/client": "./dist/transport/impls/ws/client.js",
14
14
  "./transport/ws/server": "./dist/transport/impls/ws/server.js",
@@ -40,7 +40,7 @@
40
40
  "prepack": "npm run build",
41
41
  "release": "npm publish --access public",
42
42
  "test:ui": "echo \"remember to go to /__vitest__ in the webview\" && vitest --ui --api.host 0.0.0.0 --api.port 3000",
43
- "test": "vitest",
43
+ "test": "vitest --test-timeout=500",
44
44
  "bench": "vitest bench"
45
45
  },
46
46
  "engines": {
@@ -1 +0,0 @@
1
- {"version":3,"file":"fixtures.d.ts","sourceRoot":"","sources":["../../__tests__/fixtures.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,WAAW;;;EAGtB,CAAC;AACH,eAAO,MAAM,YAAY;;EAA2C,CAAC;AAErE,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8BpB,CAAC;AAEhB,eAAO,MAAM,0BAA0B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAyBxB,CAAC;AAEhB,eAAO,MAAM,4BAA4B;;;;;;;;;;;;;;;;;;;;CAc1B,CAAC;AAEhB,eAAO,MAAM,WAAW,gBAAgB,CAAC;AACzC,eAAO,MAAM,YAAY,iBAAiB,CAAC;AAC3C,eAAO,MAAM,0BAA0B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAiExB,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"testUtils.d.ts","sourceRoot":"","sources":["../testUtils.ts"],"names":[],"mappings":";AAAA,OAAO,SAAS,MAAM,eAAe,CAAC;AACtC,OAAO,EAAE,eAAe,EAAE,MAAM,IAAI,CAAC;AACrC,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,wBAAwB,EAAE,MAAM,6BAA6B,CAAC;AACvE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AACrD,OAAO,EACL,sBAAsB,EACtB,iBAAiB,EACjB,gBAAgB,EAGjB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,QAAQ,EAAY,MAAM,aAAa,CAAC;AACjD,OAAO,EAEL,MAAM,EACN,UAAU,EACV,mBAAmB,EAEpB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,OAAO,EAAE,wBAAwB,EAAE,MAAM,6BAA6B,CAAC;AAEvE;;;;;GAKG;AACH,wBAAsB,qBAAqB,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,4EAE9D;AAED;;;;;;GAMG;AACH,wBAAsB,aAAa,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAWxE;AAED;;;;;GAKG;AACH,wBAAsB,0BAA0B,CAAC,IAAI,EAAE,MAAM,sBAI5D;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,eAAe,EACpB,KAAK,CAAC,EAAE,KAAK,GACZ,CAAC,wBAAwB,EAAE,wBAAwB,CAAC,CAWtD;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,WAAW,CACzB,KAAK,SAAS,MAAM,GAAG,OAAO,EAC9B,CAAC,SAAS,OAAO,EACjB,CAAC,SAAS,OAAO,EACjB,CAAC,SAAS,UAAU,EAEpB,KAAK,EAAE,KAAK,EACZ,IAAI,EAAE,SAAS,CAAC,KAAK,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EACtC,eAAe,CAAC,EAAE,IAAI,CAAC,cAAc,EAAE,OAAO,CAAC,SAGxC,OAAO,CAAC,CAAC,KACb,QACD,OAAO,OAAO,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,GAAG,OAAO,0BAA0B,CAAC,CAAC,CAClE,CAYF;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,cAAc,CAC5B,KAAK,SAAS,MAAM,GAAG,OAAO,EAC9B,CAAC,SAAS,OAAO,EACjB,CAAC,SAAS,OAAO,EACjB,CAAC,SAAS,UAAU,EAEpB,KAAK,EAAE,KAAK,EACZ,IAAI,EAAE,SAAS,CAAC,KAAK,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EACzC,eAAe,CAAC,EAAE,IAAI,CAAC,cAAc,EAAE,OAAO,CAAC,GAC9C;IACD,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IACnB,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,OAAO,mBAAmB,CAAC,CAAC,CAAC;CAC5E,CAuDA;AAED;;;;;;GAMG;AACH,wBAAgB,yBAAyB,CAAC,OAAO,SAAS,MAAM,EAC9D,OAAO,EAAE,OAAO,EAChB,QAAQ,CAAC,EAAE,MAAM,EACjB,IAAI,GAAE,iBAA4B,EAClC,EAAE,GAAE,iBAA4B,GAC/B,gBAAgB,CAAC,OAAO,CAAC,CAE3B;AAED;;;GAGG;AACH,wBAAgB,2BAA2B,IAAI,sBAAsB,CAKpE"}