@replit/river 0.8.0 → 0.9.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/README.md +2 -0
- package/dist/__tests__/bandwidth.bench.js +1 -1
- package/dist/__tests__/e2e.test.js +119 -5
- package/dist/__tests__/fixtures/cleanup.d.ts +12 -0
- package/dist/__tests__/fixtures/cleanup.d.ts.map +1 -0
- package/dist/__tests__/fixtures/cleanup.js +39 -0
- package/dist/__tests__/fixtures/services.d.ts +72 -0
- package/dist/__tests__/fixtures/services.d.ts.map +1 -1
- package/dist/__tests__/fixtures/services.js +55 -0
- package/dist/__tests__/handler.test.js +35 -2
- package/dist/__tests__/invariants.test.d.ts +2 -0
- package/dist/__tests__/invariants.test.d.ts.map +1 -0
- package/dist/__tests__/invariants.test.js +136 -0
- package/dist/__tests__/serialize.test.js +40 -0
- package/dist/__tests__/typescript-stress.test.d.ts +392 -196
- package/dist/__tests__/typescript-stress.test.d.ts.map +1 -1
- package/dist/__tests__/typescript-stress.test.js +13 -3
- package/dist/router/builder.d.ts +49 -11
- package/dist/router/builder.d.ts.map +1 -1
- package/dist/router/builder.js +8 -2
- package/dist/router/client.d.ts +18 -2
- package/dist/router/client.d.ts.map +1 -1
- package/dist/router/client.js +52 -11
- package/dist/router/index.d.ts +1 -1
- package/dist/router/index.d.ts.map +1 -1
- package/dist/router/server.d.ts +15 -1
- package/dist/router/server.d.ts.map +1 -1
- package/dist/router/server.js +106 -44
- package/dist/transport/events.d.ts +19 -0
- package/dist/transport/events.d.ts.map +1 -0
- package/dist/transport/events.js +26 -0
- package/dist/transport/impls/stdio/stdio.d.ts +0 -4
- package/dist/transport/impls/stdio/stdio.d.ts.map +1 -1
- package/dist/transport/impls/stdio/stdio.js +0 -5
- package/dist/transport/impls/stdio/stdio.test.js +5 -0
- package/dist/transport/impls/ws/client.d.ts.map +1 -1
- package/dist/transport/impls/ws/client.js +2 -2
- package/dist/transport/impls/ws/connection.d.ts.map +1 -1
- package/dist/transport/impls/ws/connection.js +2 -1
- package/dist/transport/impls/ws/server.d.ts +0 -2
- package/dist/transport/impls/ws/server.d.ts.map +1 -1
- package/dist/transport/impls/ws/server.js +4 -9
- package/dist/transport/impls/ws/ws.test.js +30 -10
- package/dist/transport/index.d.ts +3 -3
- package/dist/transport/index.d.ts.map +1 -1
- package/dist/transport/index.js +3 -3
- package/dist/transport/message.d.ts +10 -0
- package/dist/transport/message.d.ts.map +1 -1
- package/dist/transport/message.js +15 -0
- package/dist/transport/transport.d.ts +48 -19
- package/dist/transport/transport.d.ts.map +1 -1
- package/dist/transport/transport.js +60 -27
- package/dist/util/testHelpers.d.ts +58 -7
- package/dist/util/testHelpers.d.ts.map +1 -1
- package/dist/util/testHelpers.js +133 -3
- package/package.json +12 -13
- /package/dist/__tests__/{largePayload.json → fixtures/largePayload.json} +0 -0
|
@@ -1,26 +1,53 @@
|
|
|
1
1
|
import { Codec } from '../codec/types';
|
|
2
2
|
import { MessageId, OpaqueTransportMessage, TransportClientId } from './message';
|
|
3
|
+
import { EventDispatcher, EventHandler, EventTypes } from './events';
|
|
3
4
|
/**
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* @
|
|
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.
|
|
9
14
|
*/
|
|
10
15
|
export declare abstract class Connection {
|
|
11
16
|
connectedTo: TransportClientId;
|
|
12
17
|
transport: Transport<Connection>;
|
|
13
18
|
constructor(transport: Transport<Connection>, connectedTo: TransportClientId);
|
|
14
|
-
onMessage(msg: Uint8Array): void;
|
|
15
19
|
abstract send(msg: Uint8Array): boolean;
|
|
16
|
-
abstract close():
|
|
20
|
+
abstract close(): void;
|
|
17
21
|
}
|
|
18
22
|
export type TransportStatus = 'open' | 'closed' | 'destroyed';
|
|
19
23
|
/**
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
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
|
+
* ```
|
|
24
51
|
* @abstract
|
|
25
52
|
*/
|
|
26
53
|
export declare abstract class Transport<ConnType extends Connection> {
|
|
@@ -37,10 +64,6 @@ export declare abstract class Transport<ConnType extends Connection> {
|
|
|
37
64
|
* The client ID of this transport.
|
|
38
65
|
*/
|
|
39
66
|
clientId: TransportClientId;
|
|
40
|
-
/**
|
|
41
|
-
* The set of message handlers registered with this transport.
|
|
42
|
-
*/
|
|
43
|
-
messageHandlers: Set<(msg: OpaqueTransportMessage) => void>;
|
|
44
67
|
/**
|
|
45
68
|
* An array of message IDs that are waiting to be sent over the WebSocket connection.
|
|
46
69
|
* This builds up if the WebSocket is down for a period of time.
|
|
@@ -54,6 +77,10 @@ export declare abstract class Transport<ConnType extends Connection> {
|
|
|
54
77
|
* The map of {@link Connection}s managed by this transport.
|
|
55
78
|
*/
|
|
56
79
|
connections: Map<TransportClientId, ConnType>;
|
|
80
|
+
/**
|
|
81
|
+
* The event dispatcher for handling events of type EventTypes.
|
|
82
|
+
*/
|
|
83
|
+
eventDispatcher: EventDispatcher<EventTypes>;
|
|
57
84
|
/**
|
|
58
85
|
* Creates a new Transport instance.
|
|
59
86
|
* @param codec The codec used to encode and decode messages.
|
|
@@ -100,15 +127,17 @@ export declare abstract class Transport<ConnType extends Connection> {
|
|
|
100
127
|
*/
|
|
101
128
|
protected handleMsg(msg: OpaqueTransportMessage | null): void;
|
|
102
129
|
/**
|
|
103
|
-
* Adds a
|
|
130
|
+
* Adds a listener to this transport.
|
|
131
|
+
* @param the type of event to listen for
|
|
104
132
|
* @param handler The message handler to add.
|
|
105
133
|
*/
|
|
106
|
-
|
|
134
|
+
addEventListener<K extends EventTypes, T extends EventHandler<K>>(type: K, handler: T): void;
|
|
107
135
|
/**
|
|
108
|
-
* Removes a
|
|
136
|
+
* Removes a listener from this transport.
|
|
137
|
+
* @param the type of event to unlisten on
|
|
109
138
|
* @param handler The message handler to remove.
|
|
110
139
|
*/
|
|
111
|
-
|
|
140
|
+
removeEventListener<K extends EventTypes, T extends EventHandler<K>>(type: K, handler: T): void;
|
|
112
141
|
/**
|
|
113
142
|
* Sends a message over this transport, delegating to the appropriate connection to actually
|
|
114
143
|
* send the message.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../../transport/transport.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAEvC,OAAO,EAEL,SAAS,EACT,sBAAsB,EAGtB,iBAAiB,EAGlB,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../../transport/transport.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAEvC,OAAO,EAEL,SAAS,EACT,sBAAsB,EAGtB,iBAAiB,EAGlB,MAAM,WAAW,CAAC;AAEnB,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAErE;;;;;;;;;;GAUG;AACH,8BAAsB,UAAU;IAC9B,WAAW,EAAE,iBAAiB,CAAC;IAC/B,SAAS,EAAE,SAAS,CAAC,UAAU,CAAC,CAAC;gBAG/B,SAAS,EAAE,SAAS,CAAC,UAAU,CAAC,EAChC,WAAW,EAAE,iBAAiB;IAMhC,QAAQ,CAAC,IAAI,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO;IACvC,QAAQ,CAAC,KAAK,IAAI,IAAI;CACvB;AAED,MAAM,MAAM,eAAe,GAAG,MAAM,GAAG,QAAQ,GAAG,WAAW,CAAC;AAE9D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,8BAAsB,SAAS,CAAC,QAAQ,SAAS,UAAU;IACzD;;;OAGG;IACH,KAAK,EAAE,eAAe,CAAC;IAEvB;;OAEG;IACH,KAAK,EAAE,KAAK,CAAC;IAEb;;OAEG;IACH,QAAQ,EAAE,iBAAiB,CAAC;IAE5B;;;OAGG;IACH,SAAS,EAAE,GAAG,CAAC,iBAAiB,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC;IAEpD;;OAEG;IACH,UAAU,EAAE,GAAG,CAAC,SAAS,EAAE,sBAAsB,CAAC,CAAC;IAEnD;;OAEG;IACH,WAAW,EAAE,GAAG,CAAC,iBAAiB,EAAE,QAAQ,CAAC,CAAC;IAE9C;;OAEG;IACH,eAAe,EAAE,eAAe,CAAC,UAAU,CAAC,CAAC;IAE7C;;;;OAIG;gBACS,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,iBAAiB;IAUrD;;;OAGG;IACH,QAAQ,CAAC,8BAA8B,IAAI,IAAI;IAE/C;;;;;OAKG;IACH,QAAQ,CAAC,mBAAmB,CAAC,EAAE,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;IAElE;;;OAGG;IACH,SAAS,CAAC,IAAI,EAAE,QAAQ;IA8BxB;;;OAGG;IACH,YAAY,CAAC,IAAI,EAAE,QAAQ;IAU3B;;;OAGG;IACH,SAAS,CAAC,GAAG,EAAE,UAAU;IAIzB;;;;OAIG;IACH,SAAS,CAAC,QAAQ,CAAC,GAAG,EAAE,UAAU,GAAG,sBAAsB,GAAG,IAAI;IAmBlE;;;;OAIG;IACH,SAAS,CAAC,SAAS,CAAC,GAAG,EAAE,sBAAsB,GAAG,IAAI;IA8BtD;;;;OAIG;IACH,gBAAgB,CAAC,CAAC,SAAS,UAAU,EAAE,CAAC,SAAS,YAAY,CAAC,CAAC,CAAC,EAC9D,IAAI,EAAE,CAAC,EACP,OAAO,EAAE,CAAC,GACT,IAAI;IAIP;;;;OAIG;IACH,mBAAmB,CAAC,CAAC,SAAS,UAAU,EAAE,CAAC,SAAS,YAAY,CAAC,CAAC,CAAC,EACjE,IAAI,EAAE,CAAC,EACP,OAAO,EAAE,CAAC,GACT,IAAI;IAIP;;;;;OAKG;IACH,IAAI,CAAC,GAAG,EAAE,sBAAsB,GAAG,SAAS;IA4C5C;;;;OAIG;IACG,KAAK;IAUX;;;;OAIG;IACG,OAAO;CASd"}
|
|
@@ -1,12 +1,17 @@
|
|
|
1
1
|
import { Value } from '@sinclair/typebox/value';
|
|
2
2
|
import { OpaqueTransportMessageSchema, TransportAckSchema, isAck, reply, } from './message';
|
|
3
3
|
import { log } from '../logging';
|
|
4
|
+
import { EventDispatcher } from './events';
|
|
4
5
|
/**
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* @
|
|
6
|
+
* A 1:1 connection between two transports. Once this is created,
|
|
7
|
+
* the {@link Connection} is expected to take over responsibility for
|
|
8
|
+
* reading and writing messages from the underlying connection.
|
|
9
|
+
*
|
|
10
|
+
* 1) Messages received on the {@link Connection} are dispatched back to the {@link Transport}
|
|
11
|
+
* via {@link Transport.onMessage}. The {@link Transport} then notifies any registered message listeners.
|
|
12
|
+
* 2) When {@link Transport.send}(msg) is called, the transport looks up the appropriate
|
|
13
|
+
* connection in the {@link connections} map via `msg.to` and calls {@link send}(bytes)
|
|
14
|
+
* so the connection can send it.
|
|
10
15
|
*/
|
|
11
16
|
export class Connection {
|
|
12
17
|
connectedTo;
|
|
@@ -15,15 +20,35 @@ export class Connection {
|
|
|
15
20
|
this.connectedTo = connectedTo;
|
|
16
21
|
this.transport = transport;
|
|
17
22
|
}
|
|
18
|
-
onMessage(msg) {
|
|
19
|
-
return this.transport.onMessage(msg);
|
|
20
|
-
}
|
|
21
23
|
}
|
|
22
24
|
/**
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
25
|
+
* Transports manage the lifecycle (creation/deletion) of connections. Its responsibilities include:
|
|
26
|
+
*
|
|
27
|
+
* 1) Constructing a new {@link Connection} on {@link TransportMessage}s from new clients.
|
|
28
|
+
* After constructing the {@link Connection}, {@link onConnect} is called which adds it to the connection map.
|
|
29
|
+
* 2) Delegating message listening of the connection to the newly created {@link Connection}.
|
|
30
|
+
* From this point on, the {@link Connection} is responsible for *reading* and *writing*
|
|
31
|
+
* messages from the connection.
|
|
32
|
+
* 3) When a connection is closed, the {@link Transport} calls {@link onDisconnect} which closes the
|
|
33
|
+
* connection via {@link Connection.close} and removes it from the {@link connections} map.
|
|
34
|
+
|
|
35
|
+
*
|
|
36
|
+
* ```plaintext
|
|
37
|
+
* ▲
|
|
38
|
+
* incoming │
|
|
39
|
+
* messages │
|
|
40
|
+
* ▼
|
|
41
|
+
* ┌─────────────┐ 1:N ┌────────────┐
|
|
42
|
+
* │ Transport │ ◄─────► │ Connection │
|
|
43
|
+
* └─────────────┘ └────────────┘
|
|
44
|
+
* ▲
|
|
45
|
+
* │
|
|
46
|
+
* ▼
|
|
47
|
+
* ┌───────────┐
|
|
48
|
+
* │ Message │
|
|
49
|
+
* │ Listeners │
|
|
50
|
+
* └───────────┘
|
|
51
|
+
* ```
|
|
27
52
|
* @abstract
|
|
28
53
|
*/
|
|
29
54
|
export class Transport {
|
|
@@ -40,10 +65,6 @@ export class Transport {
|
|
|
40
65
|
* The client ID of this transport.
|
|
41
66
|
*/
|
|
42
67
|
clientId;
|
|
43
|
-
/**
|
|
44
|
-
* The set of message handlers registered with this transport.
|
|
45
|
-
*/
|
|
46
|
-
messageHandlers;
|
|
47
68
|
/**
|
|
48
69
|
* An array of message IDs that are waiting to be sent over the WebSocket connection.
|
|
49
70
|
* This builds up if the WebSocket is down for a period of time.
|
|
@@ -57,13 +78,17 @@ export class Transport {
|
|
|
57
78
|
* The map of {@link Connection}s managed by this transport.
|
|
58
79
|
*/
|
|
59
80
|
connections;
|
|
81
|
+
/**
|
|
82
|
+
* The event dispatcher for handling events of type EventTypes.
|
|
83
|
+
*/
|
|
84
|
+
eventDispatcher;
|
|
60
85
|
/**
|
|
61
86
|
* Creates a new Transport instance.
|
|
62
87
|
* @param codec The codec used to encode and decode messages.
|
|
63
88
|
* @param clientId The client ID of this transport.
|
|
64
89
|
*/
|
|
65
90
|
constructor(codec, clientId) {
|
|
66
|
-
this.
|
|
91
|
+
this.eventDispatcher = new EventDispatcher();
|
|
67
92
|
this.sendBuffer = new Map();
|
|
68
93
|
this.sendQueue = new Map();
|
|
69
94
|
this.connections = new Map();
|
|
@@ -78,6 +103,10 @@ export class Transport {
|
|
|
78
103
|
onConnect(conn) {
|
|
79
104
|
log?.info(`${this.clientId} -- new connection to ${conn.connectedTo}`);
|
|
80
105
|
this.connections.set(conn.connectedTo, conn);
|
|
106
|
+
this.eventDispatcher.dispatchEvent('connectionStatus', {
|
|
107
|
+
status: 'connect',
|
|
108
|
+
conn,
|
|
109
|
+
});
|
|
81
110
|
// send outstanding
|
|
82
111
|
const outstanding = this.sendQueue.get(conn.connectedTo);
|
|
83
112
|
if (!outstanding) {
|
|
@@ -91,7 +120,7 @@ export class Transport {
|
|
|
91
120
|
}
|
|
92
121
|
this.send(msg);
|
|
93
122
|
}
|
|
94
|
-
this.sendQueue.
|
|
123
|
+
this.sendQueue.delete(conn.connectedTo);
|
|
95
124
|
}
|
|
96
125
|
/**
|
|
97
126
|
* The downstream implementation needs to call this when a connection is closed.
|
|
@@ -101,6 +130,10 @@ export class Transport {
|
|
|
101
130
|
log?.info(`${this.clientId} -- disconnect from ${conn.connectedTo}`);
|
|
102
131
|
conn.close();
|
|
103
132
|
this.connections.delete(conn.connectedTo);
|
|
133
|
+
this.eventDispatcher.dispatchEvent('connectionStatus', {
|
|
134
|
+
status: 'disconnect',
|
|
135
|
+
conn,
|
|
136
|
+
});
|
|
104
137
|
}
|
|
105
138
|
/**
|
|
106
139
|
* Handles a message received by this transport. Thin wrapper around {@link handleMsg} and {@link parseMsg}.
|
|
@@ -151,9 +184,7 @@ export class Transport {
|
|
|
151
184
|
if (msg.to !== this.clientId) {
|
|
152
185
|
return;
|
|
153
186
|
}
|
|
154
|
-
|
|
155
|
-
handler(msg);
|
|
156
|
-
}
|
|
187
|
+
this.eventDispatcher.dispatchEvent('message', msg);
|
|
157
188
|
if (!isAck(msg.controlFlags)) {
|
|
158
189
|
const ackMsg = reply(msg, { ack: msg.id });
|
|
159
190
|
ackMsg.controlFlags = 1 /* ControlFlags.AckBit */;
|
|
@@ -163,18 +194,20 @@ export class Transport {
|
|
|
163
194
|
}
|
|
164
195
|
}
|
|
165
196
|
/**
|
|
166
|
-
* Adds a
|
|
197
|
+
* Adds a listener to this transport.
|
|
198
|
+
* @param the type of event to listen for
|
|
167
199
|
* @param handler The message handler to add.
|
|
168
200
|
*/
|
|
169
|
-
|
|
170
|
-
this.
|
|
201
|
+
addEventListener(type, handler) {
|
|
202
|
+
this.eventDispatcher.addEventListener(type, handler);
|
|
171
203
|
}
|
|
172
204
|
/**
|
|
173
|
-
* Removes a
|
|
205
|
+
* Removes a listener from this transport.
|
|
206
|
+
* @param the type of event to unlisten on
|
|
174
207
|
* @param handler The message handler to remove.
|
|
175
208
|
*/
|
|
176
|
-
|
|
177
|
-
this.
|
|
209
|
+
removeEventListener(type, handler) {
|
|
210
|
+
this.eventDispatcher.removeEventListener(type, handler);
|
|
178
211
|
}
|
|
179
212
|
/**
|
|
180
213
|
* Sends a message over this transport, delegating to the appropriate connection to actually
|
|
@@ -3,13 +3,14 @@ import WebSocket from 'isomorphic-ws';
|
|
|
3
3
|
import { WebSocketServer } from 'ws';
|
|
4
4
|
import http from 'http';
|
|
5
5
|
import { WebSocketClientTransport } from '../transport/impls/ws/client';
|
|
6
|
-
import { Static
|
|
6
|
+
import { Static } from '@sinclair/typebox';
|
|
7
7
|
import { Procedure, ServiceContext } from '../router';
|
|
8
8
|
import { OpaqueTransportMessage, TransportClientId, TransportMessage } from '../transport';
|
|
9
9
|
import { Pushable } from 'it-pushable';
|
|
10
10
|
import { Result, RiverError, RiverUncaughtSchema } from '../router/result';
|
|
11
11
|
import { Codec } from '../codec';
|
|
12
12
|
import { WebSocketServerTransport } from '../transport/impls/ws/server';
|
|
13
|
+
import { PayloadType } from '../router/builder';
|
|
13
14
|
/**
|
|
14
15
|
* Creates a WebSocket server instance using the provided HTTP server.
|
|
15
16
|
* Only used as helper for testing.
|
|
@@ -46,11 +47,11 @@ export declare function createWsTransports(port: number, wss: WebSocketServer, c
|
|
|
46
47
|
* @template I - The type of the input message payload.
|
|
47
48
|
* @template O - The type of the output message payload.
|
|
48
49
|
* @param {State} state - The state object.
|
|
49
|
-
* @param {Procedure<State, 'rpc', I, O>} proc - The RPC procedure to invoke.
|
|
50
|
+
* @param {Procedure<State, 'rpc', I, O, E, null>} proc - The RPC procedure to invoke.
|
|
50
51
|
* @param {Omit<ServiceContext, 'state'>} [extendedContext] - Optional extended context.
|
|
51
52
|
* @returns A function that can be used to invoke the RPC procedure.
|
|
52
53
|
*/
|
|
53
|
-
export declare function asClientRpc<State extends object | unknown, I extends
|
|
54
|
+
export declare function asClientRpc<State extends object | unknown, I extends PayloadType, O extends PayloadType, E extends RiverError>(state: State, proc: Procedure<State, 'rpc', I, O, E, null>, extendedContext?: Omit<ServiceContext, 'state'>): (msg: Static<I>) => Promise<Result<Static<O>, Static<E> | Static<typeof RiverUncaughtSchema>>>;
|
|
54
55
|
/**
|
|
55
56
|
* Transforms a stream procedure definition into a pair of input and output streams.
|
|
56
57
|
* Input messages can be pushed into the input stream.
|
|
@@ -59,11 +60,27 @@ export declare function asClientRpc<State extends object | unknown, I extends TO
|
|
|
59
60
|
* @template I - The type of the input object.
|
|
60
61
|
* @template O - The type of the output object.
|
|
61
62
|
* @param {State} state - The state object.
|
|
62
|
-
* @param {Procedure<State, 'stream', I, O>} proc - The procedure to handle the stream.
|
|
63
|
+
* @param {Procedure<State, 'stream', I, O, E, null>} proc - The procedure to handle the stream.
|
|
63
64
|
* @param {Omit<ServiceContext, 'state'>} [extendedContext] - The extended context object.
|
|
64
65
|
* @returns Pair of input and output streams.
|
|
65
66
|
*/
|
|
66
|
-
export declare function asClientStream<State extends object | unknown, I extends
|
|
67
|
+
export declare function asClientStream<State extends object | unknown, I extends PayloadType, O extends PayloadType, E extends RiverError>(state: State, proc: Procedure<State, 'stream', I, O, E, null>, extendedContext?: Omit<ServiceContext, 'state'>): [
|
|
68
|
+
Pushable<Static<I>>,
|
|
69
|
+
Pushable<Result<Static<O>, Static<E> | Static<typeof RiverUncaughtSchema>>>
|
|
70
|
+
];
|
|
71
|
+
/**
|
|
72
|
+
* Transforms a stream procedure definition into a pair of input and output streams.
|
|
73
|
+
* Input messages can be pushed into the input stream.
|
|
74
|
+
* This should only be used for testing.
|
|
75
|
+
* @template State - The type of the state object.
|
|
76
|
+
* @template I - The type of the input object.
|
|
77
|
+
* @template O - The type of the output object.
|
|
78
|
+
* @param {State} state - The state object.
|
|
79
|
+
* @param {Procedure<State, 'stream', I, O, E, null>} proc - The procedure to handle the stream.
|
|
80
|
+
* @param {Omit<ServiceContext, 'state'>} [extendedContext] - The extended context object.
|
|
81
|
+
* @returns Pair of input and output streams.
|
|
82
|
+
*/
|
|
83
|
+
export declare function asClientStreamWithInitialization<State extends object | unknown, I extends PayloadType, O extends PayloadType, E extends RiverError, Init extends PayloadType>(state: State, proc: Procedure<State, 'stream', I, O, E, Init>, init: Static<PayloadType>, extendedContext?: Omit<ServiceContext, 'state'>): [
|
|
67
84
|
Pushable<Static<I>>,
|
|
68
85
|
Pushable<Result<Static<O>, Static<E> | Static<typeof RiverUncaughtSchema>>>
|
|
69
86
|
];
|
|
@@ -75,11 +92,45 @@ export declare function asClientStream<State extends object | unknown, I extends
|
|
|
75
92
|
* @template I - The type of the input object.
|
|
76
93
|
* @template O - The type of the output object.
|
|
77
94
|
* @param {State} state - The state object.
|
|
78
|
-
* @param {Procedure<State, 'stream', I, O>} proc - The procedure to handle the stream.
|
|
95
|
+
* @param {Procedure<State, 'stream', I, O, E, null>} proc - The procedure to handle the stream.
|
|
96
|
+
* @param {Omit<ServiceContext, 'state'>} [extendedContext] - The extended context object.
|
|
97
|
+
* @returns A function that when passed a message, returns the output stream.
|
|
98
|
+
*/
|
|
99
|
+
export declare function asClientSubscription<State extends object | unknown, I extends PayloadType, O extends PayloadType, E extends RiverError>(state: State, proc: Procedure<State, 'subscription', I, O, E, null>, extendedContext?: Omit<ServiceContext, 'state'>): (msg: Static<I>) => Promise<Pushable<Result<Static<O>, Static<E> | Static<typeof RiverUncaughtSchema>>>>;
|
|
100
|
+
/**
|
|
101
|
+
* Transforms an upload procedure definition into a procedure that returns an input stream.
|
|
102
|
+
* Input messages can be pushed into the input stream.
|
|
103
|
+
* This should only be used for testing.
|
|
104
|
+
* @template State - The type of the state object.
|
|
105
|
+
* @template I - The type of the input object.
|
|
106
|
+
* @template O - The type of the output object.
|
|
107
|
+
* @param {State} state - The state object.
|
|
108
|
+
* @param {Procedure<State, 'upload', I, O, E, null>} proc - The procedure to handle the stream.
|
|
79
109
|
* @param {Omit<ServiceContext, 'state'>} [extendedContext] - The extended context object.
|
|
80
110
|
* @returns A function that when passed a message, returns the output stream.
|
|
81
111
|
*/
|
|
82
|
-
export declare function
|
|
112
|
+
export declare function asClientUpload<State extends object | unknown, I extends PayloadType, O extends PayloadType, E extends RiverError>(state: State, proc: Procedure<State, 'upload', I, O, E, null>, extendedContext?: Omit<ServiceContext, 'state'>): [
|
|
113
|
+
Pushable<Static<I>>,
|
|
114
|
+
Promise<Result<Static<O>, Static<E> | Static<typeof RiverUncaughtSchema>>>
|
|
115
|
+
];
|
|
116
|
+
/**
|
|
117
|
+
* Transforms an upload with initialization procedure definition into a procedure that returns an
|
|
118
|
+
* input stream.
|
|
119
|
+
* Input messages can be pushed into the input stream.
|
|
120
|
+
* This should only be used for testing.
|
|
121
|
+
* @template State - The type of the state object.
|
|
122
|
+
* @template Init - The type of the init object.
|
|
123
|
+
* @template I - The type of the input object.
|
|
124
|
+
* @template O - The type of the output object.
|
|
125
|
+
* @param {State} state - The state object.
|
|
126
|
+
* @param {Procedure<State, 'upload', I, O, E, Init>} proc - The procedure to handle the stream.
|
|
127
|
+
* @param {Omit<ServiceContext, 'state'>} [extendedContext] - The extended context object.
|
|
128
|
+
* @returns A function that when passed a message, returns the output stream.
|
|
129
|
+
*/
|
|
130
|
+
export declare function asClientUploadWithInitialization<State extends object | unknown, I extends PayloadType, O extends PayloadType, E extends RiverError, Init extends PayloadType>(state: State, proc: Procedure<State, 'upload', I, O, E, Init>, init: Static<Init>, extendedContext?: Omit<ServiceContext, 'state'>): [
|
|
131
|
+
Pushable<Static<I>>,
|
|
132
|
+
Promise<Result<Static<O>, Static<E> | Static<typeof RiverUncaughtSchema>>>
|
|
133
|
+
];
|
|
83
134
|
/**
|
|
84
135
|
* Converts a payload object to a transport message with reasonable defaults.
|
|
85
136
|
* This should only be used for testing.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"testHelpers.d.ts","sourceRoot":"","sources":["../../util/testHelpers.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,8BAA8B,CAAC;AACxE,OAAO,EAAE,MAAM,EAAE,
|
|
1
|
+
{"version":3,"file":"testHelpers.d.ts","sourceRoot":"","sources":["../../util/testHelpers.ts"],"names":[],"mappings":"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"}
|
package/dist/util/testHelpers.js
CHANGED
|
@@ -65,7 +65,7 @@ export function createWsTransports(port, wss, codec) {
|
|
|
65
65
|
* @template I - The type of the input message payload.
|
|
66
66
|
* @template O - The type of the output message payload.
|
|
67
67
|
* @param {State} state - The state object.
|
|
68
|
-
* @param {Procedure<State, 'rpc', I, O>} proc - The RPC procedure to invoke.
|
|
68
|
+
* @param {Procedure<State, 'rpc', I, O, E, null>} proc - The RPC procedure to invoke.
|
|
69
69
|
* @param {Omit<ServiceContext, 'state'>} [extendedContext] - Optional extended context.
|
|
70
70
|
* @returns A function that can be used to invoke the RPC procedure.
|
|
71
71
|
*/
|
|
@@ -89,7 +89,7 @@ export function asClientRpc(state, proc, extendedContext) {
|
|
|
89
89
|
* @template I - The type of the input object.
|
|
90
90
|
* @template O - The type of the output object.
|
|
91
91
|
* @param {State} state - The state object.
|
|
92
|
-
* @param {Procedure<State, 'stream', I, O>} proc - The procedure to handle the stream.
|
|
92
|
+
* @param {Procedure<State, 'stream', I, O, E, null>} proc - The procedure to handle the stream.
|
|
93
93
|
* @param {Omit<ServiceContext, 'state'>} [extendedContext] - The extended context object.
|
|
94
94
|
* @returns Pair of input and output streams.
|
|
95
95
|
*/
|
|
@@ -133,6 +133,58 @@ export function asClientStream(state, proc, extendedContext) {
|
|
|
133
133
|
})();
|
|
134
134
|
return [rawInput, rawOutput];
|
|
135
135
|
}
|
|
136
|
+
/**
|
|
137
|
+
* Transforms a stream procedure definition into a pair of input and output streams.
|
|
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, E, null>} proc - The procedure to handle the stream.
|
|
145
|
+
* @param {Omit<ServiceContext, 'state'>} [extendedContext] - The extended context object.
|
|
146
|
+
* @returns Pair of input and output streams.
|
|
147
|
+
*/
|
|
148
|
+
export function asClientStreamWithInitialization(state, proc, init, extendedContext) {
|
|
149
|
+
const rawInput = pushable({ objectMode: true });
|
|
150
|
+
const rawOutput = pushable({
|
|
151
|
+
objectMode: true,
|
|
152
|
+
});
|
|
153
|
+
const transportInput = pushable({
|
|
154
|
+
objectMode: true,
|
|
155
|
+
});
|
|
156
|
+
const transportOutput = pushable({
|
|
157
|
+
objectMode: true,
|
|
158
|
+
});
|
|
159
|
+
// wrapping in transport
|
|
160
|
+
(async () => {
|
|
161
|
+
for await (const rawIn of rawInput) {
|
|
162
|
+
transportInput.push(payloadToTransportMessage(rawIn));
|
|
163
|
+
}
|
|
164
|
+
transportInput.end();
|
|
165
|
+
})();
|
|
166
|
+
// unwrap from transport
|
|
167
|
+
(async () => {
|
|
168
|
+
for await (const transportRes of transportOutput) {
|
|
169
|
+
rawOutput.push(transportRes.payload);
|
|
170
|
+
}
|
|
171
|
+
})();
|
|
172
|
+
// handle
|
|
173
|
+
(async () => {
|
|
174
|
+
try {
|
|
175
|
+
await proc.handler({ ...extendedContext, state }, payloadToTransportMessage(init), transportInput, transportOutput);
|
|
176
|
+
}
|
|
177
|
+
catch (err) {
|
|
178
|
+
const errorMsg = err instanceof Error ? err.message : `[coerced to error] ${err}`;
|
|
179
|
+
transportOutput.push(reply(payloadToTransportMessage({}), Err({
|
|
180
|
+
code: UNCAUGHT_ERROR,
|
|
181
|
+
message: errorMsg,
|
|
182
|
+
})));
|
|
183
|
+
}
|
|
184
|
+
transportOutput.end();
|
|
185
|
+
})();
|
|
186
|
+
return [rawInput, rawOutput];
|
|
187
|
+
}
|
|
136
188
|
/**
|
|
137
189
|
* Transforms a subscription procedure definition into a procedure that returns an output stream.
|
|
138
190
|
* Input messages can be pushed into the input stream.
|
|
@@ -141,7 +193,7 @@ export function asClientStream(state, proc, extendedContext) {
|
|
|
141
193
|
* @template I - The type of the input object.
|
|
142
194
|
* @template O - The type of the output object.
|
|
143
195
|
* @param {State} state - The state object.
|
|
144
|
-
* @param {Procedure<State, 'stream', I, O>} proc - The procedure to handle the stream.
|
|
196
|
+
* @param {Procedure<State, 'stream', I, O, E, null>} proc - The procedure to handle the stream.
|
|
145
197
|
* @param {Omit<ServiceContext, 'state'>} [extendedContext] - The extended context object.
|
|
146
198
|
* @returns A function that when passed a message, returns the output stream.
|
|
147
199
|
*/
|
|
@@ -171,6 +223,84 @@ export function asClientSubscription(state, proc, extendedContext) {
|
|
|
171
223
|
return rawOutput;
|
|
172
224
|
};
|
|
173
225
|
}
|
|
226
|
+
/**
|
|
227
|
+
* Transforms an upload procedure definition into a procedure that returns an input stream.
|
|
228
|
+
* Input messages can be pushed into the input stream.
|
|
229
|
+
* This should only be used for testing.
|
|
230
|
+
* @template State - The type of the state object.
|
|
231
|
+
* @template I - The type of the input object.
|
|
232
|
+
* @template O - The type of the output object.
|
|
233
|
+
* @param {State} state - The state object.
|
|
234
|
+
* @param {Procedure<State, 'upload', I, O, E, null>} proc - The procedure to handle the stream.
|
|
235
|
+
* @param {Omit<ServiceContext, 'state'>} [extendedContext] - The extended context object.
|
|
236
|
+
* @returns A function that when passed a message, returns the output stream.
|
|
237
|
+
*/
|
|
238
|
+
export function asClientUpload(state, proc, extendedContext) {
|
|
239
|
+
const rawInput = pushable({ objectMode: true });
|
|
240
|
+
const transportInput = pushable({
|
|
241
|
+
objectMode: true,
|
|
242
|
+
});
|
|
243
|
+
// wrapping in transport
|
|
244
|
+
(async () => {
|
|
245
|
+
for await (const rawIn of rawInput) {
|
|
246
|
+
transportInput.push(payloadToTransportMessage(rawIn));
|
|
247
|
+
}
|
|
248
|
+
transportInput.end();
|
|
249
|
+
})();
|
|
250
|
+
return [
|
|
251
|
+
rawInput,
|
|
252
|
+
proc
|
|
253
|
+
.handler({ ...extendedContext, state }, transportInput)
|
|
254
|
+
.then((res) => res.payload)
|
|
255
|
+
.catch((err) => {
|
|
256
|
+
const errorMsg = err instanceof Error ? err.message : `[coerced to error] ${err}`;
|
|
257
|
+
return Err({
|
|
258
|
+
code: UNCAUGHT_ERROR,
|
|
259
|
+
message: errorMsg,
|
|
260
|
+
});
|
|
261
|
+
}),
|
|
262
|
+
];
|
|
263
|
+
}
|
|
264
|
+
/**
|
|
265
|
+
* Transforms an upload with initialization procedure definition into a procedure that returns an
|
|
266
|
+
* input stream.
|
|
267
|
+
* Input messages can be pushed into the input stream.
|
|
268
|
+
* This should only be used for testing.
|
|
269
|
+
* @template State - The type of the state object.
|
|
270
|
+
* @template Init - The type of the init object.
|
|
271
|
+
* @template I - The type of the input object.
|
|
272
|
+
* @template O - The type of the output object.
|
|
273
|
+
* @param {State} state - The state object.
|
|
274
|
+
* @param {Procedure<State, 'upload', I, O, E, Init>} proc - The procedure to handle the stream.
|
|
275
|
+
* @param {Omit<ServiceContext, 'state'>} [extendedContext] - The extended context object.
|
|
276
|
+
* @returns A function that when passed a message, returns the output stream.
|
|
277
|
+
*/
|
|
278
|
+
export function asClientUploadWithInitialization(state, proc, init, extendedContext) {
|
|
279
|
+
const rawInput = pushable({ objectMode: true });
|
|
280
|
+
const transportInput = pushable({
|
|
281
|
+
objectMode: true,
|
|
282
|
+
});
|
|
283
|
+
// wrapping in transport
|
|
284
|
+
(async () => {
|
|
285
|
+
for await (const rawIn of rawInput) {
|
|
286
|
+
transportInput.push(payloadToTransportMessage(rawIn));
|
|
287
|
+
}
|
|
288
|
+
transportInput.end();
|
|
289
|
+
})();
|
|
290
|
+
return [
|
|
291
|
+
rawInput,
|
|
292
|
+
proc
|
|
293
|
+
.handler({ ...extendedContext, state }, payloadToTransportMessage(init), transportInput)
|
|
294
|
+
.then((res) => res.payload)
|
|
295
|
+
.catch((err) => {
|
|
296
|
+
const errorMsg = err instanceof Error ? err.message : `[coerced to error] ${err}`;
|
|
297
|
+
return Err({
|
|
298
|
+
code: UNCAUGHT_ERROR,
|
|
299
|
+
message: errorMsg,
|
|
300
|
+
});
|
|
301
|
+
}),
|
|
302
|
+
];
|
|
303
|
+
}
|
|
174
304
|
/**
|
|
175
305
|
* Converts a payload object to a transport message with reasonable defaults.
|
|
176
306
|
* This should only be used for testing.
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
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.
|
|
5
|
+
"version": "0.9.0",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"exports": {
|
|
8
8
|
".": "./dist/router/index.js",
|
|
@@ -33,16 +33,6 @@
|
|
|
33
33
|
"typescript": "^5.2.2",
|
|
34
34
|
"vitest": "^1.0.1"
|
|
35
35
|
},
|
|
36
|
-
"scripts": {
|
|
37
|
-
"check": "tsc --noEmit && npx prettier . --check",
|
|
38
|
-
"format": "npx prettier . --write",
|
|
39
|
-
"build": "rm -rf ./dist && tsc",
|
|
40
|
-
"prepack": "npm run build",
|
|
41
|
-
"release": "npm publish --access public",
|
|
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",
|
|
44
|
-
"bench": "vitest bench"
|
|
45
|
-
},
|
|
46
36
|
"engines": {
|
|
47
37
|
"node": ">=16"
|
|
48
38
|
},
|
|
@@ -52,5 +42,14 @@
|
|
|
52
42
|
"jsonschema"
|
|
53
43
|
],
|
|
54
44
|
"author": "Jacky Zhao",
|
|
55
|
-
"license": "MIT"
|
|
56
|
-
|
|
45
|
+
"license": "MIT",
|
|
46
|
+
"scripts": {
|
|
47
|
+
"check": "tsc --noEmit && npx prettier . --check",
|
|
48
|
+
"format": "npx prettier . --write",
|
|
49
|
+
"build": "rm -rf ./dist && tsc",
|
|
50
|
+
"release": "npm publish --access public",
|
|
51
|
+
"test:ui": "echo \"remember to go to /__vitest__ in the webview\" && vitest --ui --api.host 0.0.0.0 --api.port 3000",
|
|
52
|
+
"test": "vitest --test-timeout=500",
|
|
53
|
+
"bench": "vitest bench"
|
|
54
|
+
}
|
|
55
|
+
}
|
|
File without changes
|