@replit/river 0.10.0 → 0.10.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{router/builder.d.ts → builder-3c4485f0.d.ts} +76 -21
- package/dist/chunk-7WJ6YLE5.js +683 -0
- package/dist/chunk-AJQU4AZG.js +284 -0
- package/dist/chunk-ORAG7IAU.js +0 -0
- package/dist/chunk-PC65ZFWJ.js +29 -0
- package/dist/chunk-R6H2BIMC.js +49 -0
- package/dist/chunk-RGMHF6PF.js +65 -0
- package/dist/chunk-SLUSVGQH.js +30 -0
- package/dist/chunk-UU2Z7LDR.js +113 -0
- package/dist/chunk-WVT5QXMZ.js +20 -0
- package/dist/chunk-ZE4MX7DF.js +75 -0
- package/dist/codec/index.cjs +94 -0
- package/dist/codec/index.d.cts +15 -0
- package/dist/codec/index.d.ts +15 -4
- package/dist/codec/index.js +10 -2
- package/dist/connection-8e19874c.d.ts +11 -0
- package/dist/connection-f7688cc1.d.ts +11 -0
- package/dist/logging/index.cjs +56 -0
- package/dist/logging/index.d.cts +28 -0
- package/dist/logging/index.d.ts +6 -6
- package/dist/logging/index.js +9 -40
- package/dist/router/index.cjs +770 -0
- package/dist/router/index.d.cts +114 -0
- package/dist/router/index.d.ts +114 -12
- package/dist/router/index.js +24 -5
- package/dist/transport/impls/ws/client.cjs +505 -0
- package/dist/transport/impls/ws/client.d.cts +42 -0
- package/dist/transport/impls/ws/client.d.ts +8 -8
- package/dist/transport/impls/ws/client.js +10 -100
- package/dist/transport/impls/ws/server.cjs +457 -0
- package/dist/transport/impls/ws/server.d.cts +21 -0
- package/dist/transport/impls/ws/server.d.ts +11 -10
- package/dist/transport/impls/ws/server.js +11 -52
- package/dist/transport/index.cjs +362 -0
- package/dist/transport/{transport.d.ts → index.d.cts} +119 -7
- package/dist/transport/index.d.ts +273 -4
- package/dist/transport/index.js +20 -2
- package/dist/{codec/types.d.ts → types-3e5768ec.d.ts} +3 -2
- package/dist/util/testHelpers.cjs +731 -0
- package/dist/util/testHelpers.d.cts +79 -0
- package/dist/util/testHelpers.d.ts +22 -19
- package/dist/util/testHelpers.js +135 -163
- package/package.json +41 -13
- package/dist/__tests__/bandwidth.bench.d.ts +0 -2
- package/dist/__tests__/bandwidth.bench.d.ts.map +0 -1
- package/dist/__tests__/bandwidth.bench.js +0 -90
- package/dist/__tests__/cleanup.test.d.ts +0 -2
- package/dist/__tests__/cleanup.test.d.ts.map +0 -1
- package/dist/__tests__/cleanup.test.js +0 -165
- package/dist/__tests__/disconnects.test.d.ts +0 -2
- package/dist/__tests__/disconnects.test.d.ts.map +0 -1
- package/dist/__tests__/disconnects.test.js +0 -163
- package/dist/__tests__/e2e.test.d.ts +0 -2
- package/dist/__tests__/e2e.test.d.ts.map +0 -1
- package/dist/__tests__/e2e.test.js +0 -317
- package/dist/__tests__/fixtures/cleanup.d.ts +0 -12
- package/dist/__tests__/fixtures/cleanup.d.ts.map +0 -1
- package/dist/__tests__/fixtures/cleanup.js +0 -36
- package/dist/__tests__/fixtures/largePayload.json +0 -33
- package/dist/__tests__/fixtures/observable.d.ts +0 -26
- package/dist/__tests__/fixtures/observable.d.ts.map +0 -1
- package/dist/__tests__/fixtures/observable.js +0 -38
- package/dist/__tests__/fixtures/observable.test.d.ts +0 -2
- package/dist/__tests__/fixtures/observable.test.d.ts.map +0 -1
- package/dist/__tests__/fixtures/observable.test.js +0 -39
- package/dist/__tests__/fixtures/services.d.ts +0 -288
- package/dist/__tests__/fixtures/services.d.ts.map +0 -1
- package/dist/__tests__/fixtures/services.js +0 -207
- package/dist/__tests__/handler.test.d.ts +0 -2
- package/dist/__tests__/handler.test.d.ts.map +0 -1
- package/dist/__tests__/handler.test.js +0 -120
- package/dist/__tests__/serialize.test.d.ts +0 -2
- package/dist/__tests__/serialize.test.d.ts.map +0 -1
- package/dist/__tests__/serialize.test.js +0 -208
- package/dist/__tests__/typescript-stress.test.d.ts +0 -1583
- package/dist/__tests__/typescript-stress.test.d.ts.map +0 -1
- package/dist/__tests__/typescript-stress.test.js +0 -123
- package/dist/codec/binary.d.ts +0 -7
- package/dist/codec/binary.d.ts.map +0 -1
- package/dist/codec/binary.js +0 -20
- package/dist/codec/codec.test.d.ts +0 -5
- package/dist/codec/codec.test.d.ts.map +0 -1
- package/dist/codec/codec.test.js +0 -41
- package/dist/codec/index.d.ts.map +0 -1
- package/dist/codec/json.d.ts +0 -7
- package/dist/codec/json.d.ts.map +0 -1
- package/dist/codec/json.js +0 -51
- package/dist/codec/types.d.ts.map +0 -1
- package/dist/codec/types.js +0 -1
- package/dist/logging/index.d.ts.map +0 -1
- package/dist/router/builder.d.ts.map +0 -1
- package/dist/router/builder.js +0 -91
- package/dist/router/client.d.ts +0 -72
- package/dist/router/client.d.ts.map +0 -1
- package/dist/router/client.js +0 -257
- package/dist/router/context.d.ts +0 -30
- package/dist/router/context.d.ts.map +0 -1
- package/dist/router/context.js +0 -1
- package/dist/router/defs.d.ts +0 -16
- package/dist/router/defs.d.ts.map +0 -1
- package/dist/router/defs.js +0 -11
- package/dist/router/index.d.ts.map +0 -1
- package/dist/router/result.d.ts +0 -26
- package/dist/router/result.d.ts.map +0 -1
- package/dist/router/result.js +0 -22
- package/dist/router/server.d.ts +0 -39
- package/dist/router/server.d.ts.map +0 -1
- package/dist/router/server.js +0 -260
- package/dist/transport/events.d.ts +0 -19
- package/dist/transport/events.d.ts.map +0 -1
- package/dist/transport/events.js +0 -26
- package/dist/transport/impls/stdio/stdio.d.ts +0 -33
- package/dist/transport/impls/stdio/stdio.d.ts.map +0 -1
- package/dist/transport/impls/stdio/stdio.js +0 -75
- package/dist/transport/impls/stdio/stdio.test.d.ts +0 -2
- package/dist/transport/impls/stdio/stdio.test.d.ts.map +0 -1
- package/dist/transport/impls/stdio/stdio.test.js +0 -24
- package/dist/transport/impls/ws/client.d.ts.map +0 -1
- package/dist/transport/impls/ws/connection.d.ts +0 -11
- package/dist/transport/impls/ws/connection.d.ts.map +0 -1
- package/dist/transport/impls/ws/connection.js +0 -23
- package/dist/transport/impls/ws/server.d.ts.map +0 -1
- package/dist/transport/impls/ws/ws.test.d.ts +0 -2
- package/dist/transport/impls/ws/ws.test.d.ts.map +0 -1
- package/dist/transport/impls/ws/ws.test.js +0 -185
- package/dist/transport/index.d.ts.map +0 -1
- package/dist/transport/message.d.ts +0 -142
- package/dist/transport/message.d.ts.map +0 -1
- package/dist/transport/message.js +0 -113
- package/dist/transport/message.test.d.ts +0 -2
- package/dist/transport/message.test.d.ts.map +0 -1
- package/dist/transport/message.test.js +0 -52
- package/dist/transport/transport.d.ts.map +0 -1
- package/dist/transport/transport.js +0 -281
- package/dist/util/testHelpers.d.ts.map +0 -1
package/dist/router/server.js
DELETED
|
@@ -1,260 +0,0 @@
|
|
|
1
|
-
import { pushable } from 'it-pushable';
|
|
2
|
-
import { ControlMessagePayloadSchema, isStreamClose, isStreamOpen, reply, closeStream, } from '../transport/message';
|
|
3
|
-
import { log } from '../logging';
|
|
4
|
-
import { Value } from '@sinclair/typebox/value';
|
|
5
|
-
import { Err, UNCAUGHT_ERROR, } from './result';
|
|
6
|
-
class RiverServer {
|
|
7
|
-
transport;
|
|
8
|
-
services;
|
|
9
|
-
contextMap;
|
|
10
|
-
// map of streamId to ProcStream
|
|
11
|
-
streamMap;
|
|
12
|
-
// map of client to their open streams by streamId
|
|
13
|
-
clientStreams;
|
|
14
|
-
constructor(transport, services, extendedContext) {
|
|
15
|
-
this.transport = transport;
|
|
16
|
-
this.services = services;
|
|
17
|
-
this.contextMap = new Map();
|
|
18
|
-
for (const service of Object.values(services)) {
|
|
19
|
-
this.contextMap.set(service, {
|
|
20
|
-
...extendedContext,
|
|
21
|
-
state: service.state,
|
|
22
|
-
});
|
|
23
|
-
}
|
|
24
|
-
this.streamMap = new Map();
|
|
25
|
-
this.clientStreams = new Map();
|
|
26
|
-
this.transport.addEventListener('message', this.handler);
|
|
27
|
-
this.transport.addEventListener('connectionStatus', this.onDisconnect);
|
|
28
|
-
}
|
|
29
|
-
get streams() {
|
|
30
|
-
return this.streamMap;
|
|
31
|
-
}
|
|
32
|
-
handler = async (message) => {
|
|
33
|
-
if (message.to !== this.transport.clientId) {
|
|
34
|
-
log?.info(`${this.transport.clientId} -- got msg with destination that isn't the server, ignoring`);
|
|
35
|
-
return;
|
|
36
|
-
}
|
|
37
|
-
let procStream = this.streamMap.get(message.streamId);
|
|
38
|
-
const isInitMessage = !procStream;
|
|
39
|
-
// create a proc stream if it doesnt exist
|
|
40
|
-
procStream ||= this.createNewProcStream(message);
|
|
41
|
-
if (!procStream) {
|
|
42
|
-
// if we fail to create a proc stream, just abort
|
|
43
|
-
return;
|
|
44
|
-
}
|
|
45
|
-
await this.pushToStream(procStream, message, isInitMessage);
|
|
46
|
-
};
|
|
47
|
-
// cleanup streams on unexpected disconnections
|
|
48
|
-
onDisconnect = async (evt) => {
|
|
49
|
-
if (evt.status !== 'disconnect') {
|
|
50
|
-
return;
|
|
51
|
-
}
|
|
52
|
-
const disconnectedClientId = evt.conn.connectedTo;
|
|
53
|
-
log?.info(`${this.transport.clientId} -- got unexpected disconnect from ${disconnectedClientId}, cleaning up streams`);
|
|
54
|
-
const streamsFromThisClient = this.clientStreams.get(disconnectedClientId);
|
|
55
|
-
if (!streamsFromThisClient) {
|
|
56
|
-
return;
|
|
57
|
-
}
|
|
58
|
-
await Promise.all(Array.from(streamsFromThisClient).map(this.cleanupStream));
|
|
59
|
-
this.clientStreams.delete(disconnectedClientId);
|
|
60
|
-
};
|
|
61
|
-
async close() {
|
|
62
|
-
this.transport.removeEventListener('message', this.handler);
|
|
63
|
-
this.transport.removeEventListener('connectionStatus', this.onDisconnect);
|
|
64
|
-
await Promise.all([...this.streamMap.keys()].map(this.cleanupStream));
|
|
65
|
-
}
|
|
66
|
-
createNewProcStream(message) {
|
|
67
|
-
if (!isStreamOpen(message.controlFlags)) {
|
|
68
|
-
log?.warn(`${this.transport.clientId} -- couldn't find a matching procedure stream for ${message.serviceName}.${message.procedureName}:${message.streamId}`);
|
|
69
|
-
return;
|
|
70
|
-
}
|
|
71
|
-
if (!message.serviceName || !(message.serviceName in this.services)) {
|
|
72
|
-
log?.warn(`${this.transport.clientId} -- couldn't find service ${message.serviceName}`);
|
|
73
|
-
return;
|
|
74
|
-
}
|
|
75
|
-
const service = this.services[message.serviceName];
|
|
76
|
-
const serviceContext = this.getContext(service);
|
|
77
|
-
if (!message.procedureName ||
|
|
78
|
-
!(message.procedureName in service.procedures)) {
|
|
79
|
-
log?.warn(`${this.transport.clientId} -- couldn't find a matching procedure for ${message.serviceName}.${message.procedureName}`);
|
|
80
|
-
return;
|
|
81
|
-
}
|
|
82
|
-
const procedure = service.procedures[message.procedureName];
|
|
83
|
-
const incoming = pushable({ objectMode: true });
|
|
84
|
-
const outgoing = pushable({ objectMode: true });
|
|
85
|
-
const outputHandler =
|
|
86
|
-
// sending outgoing messages back to client
|
|
87
|
-
(async () => {
|
|
88
|
-
for await (const response of outgoing) {
|
|
89
|
-
this.transport.send(reply(message, response));
|
|
90
|
-
}
|
|
91
|
-
// we ended, send a close bit back to the client
|
|
92
|
-
// only subscriptions and streams have streams the
|
|
93
|
-
// handler can close
|
|
94
|
-
if (procedure.type === 'subscription' || procedure.type === 'stream') {
|
|
95
|
-
this.transport.send(closeStream(this.transport.clientId, message.from, message.streamId));
|
|
96
|
-
}
|
|
97
|
-
})();
|
|
98
|
-
const errorHandler = (err) => {
|
|
99
|
-
const errorMsg = err instanceof Error ? err.message : `[coerced to error] ${err}`;
|
|
100
|
-
log?.error(`${this.transport.clientId} -- procedure ${message.serviceName}.${message.procedureName}:${message.streamId} threw an error: ${errorMsg}`);
|
|
101
|
-
outgoing.push(Err({
|
|
102
|
-
code: UNCAUGHT_ERROR,
|
|
103
|
-
message: errorMsg,
|
|
104
|
-
}));
|
|
105
|
-
};
|
|
106
|
-
// pump incoming message stream -> handler -> outgoing message stream
|
|
107
|
-
let inputHandler;
|
|
108
|
-
const procHasInitMessage = 'init' in procedure;
|
|
109
|
-
if (procedure.type === 'stream') {
|
|
110
|
-
if (procHasInitMessage) {
|
|
111
|
-
inputHandler = (async () => {
|
|
112
|
-
const initMessage = await incoming.next();
|
|
113
|
-
if (initMessage.done) {
|
|
114
|
-
return;
|
|
115
|
-
}
|
|
116
|
-
return procedure
|
|
117
|
-
.handler(serviceContext, initMessage.value, incoming, outgoing)
|
|
118
|
-
.catch(errorHandler);
|
|
119
|
-
})();
|
|
120
|
-
}
|
|
121
|
-
else {
|
|
122
|
-
inputHandler = procedure
|
|
123
|
-
.handler(serviceContext, incoming, outgoing)
|
|
124
|
-
.catch(errorHandler);
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
else if (procedure.type === 'rpc') {
|
|
128
|
-
inputHandler = (async () => {
|
|
129
|
-
const inputMessage = await incoming.next();
|
|
130
|
-
if (inputMessage.done) {
|
|
131
|
-
return;
|
|
132
|
-
}
|
|
133
|
-
try {
|
|
134
|
-
const outputMessage = await procedure.handler(serviceContext, inputMessage.value);
|
|
135
|
-
outgoing.push(outputMessage);
|
|
136
|
-
}
|
|
137
|
-
catch (err) {
|
|
138
|
-
errorHandler(err);
|
|
139
|
-
}
|
|
140
|
-
})();
|
|
141
|
-
}
|
|
142
|
-
else if (procedure.type === 'subscription') {
|
|
143
|
-
inputHandler = (async () => {
|
|
144
|
-
const inputMessage = await incoming.next();
|
|
145
|
-
if (inputMessage.done) {
|
|
146
|
-
return;
|
|
147
|
-
}
|
|
148
|
-
try {
|
|
149
|
-
await procedure.handler(serviceContext, inputMessage.value, outgoing);
|
|
150
|
-
}
|
|
151
|
-
catch (err) {
|
|
152
|
-
errorHandler(err);
|
|
153
|
-
}
|
|
154
|
-
})();
|
|
155
|
-
}
|
|
156
|
-
else if (procedure.type === 'upload') {
|
|
157
|
-
if (procHasInitMessage) {
|
|
158
|
-
inputHandler = (async () => {
|
|
159
|
-
const initMessage = await incoming.next();
|
|
160
|
-
if (initMessage.done) {
|
|
161
|
-
return;
|
|
162
|
-
}
|
|
163
|
-
try {
|
|
164
|
-
const outputMessage = await procedure.handler(serviceContext, initMessage.value, incoming);
|
|
165
|
-
outgoing.push(outputMessage);
|
|
166
|
-
}
|
|
167
|
-
catch (err) {
|
|
168
|
-
errorHandler(err);
|
|
169
|
-
}
|
|
170
|
-
})();
|
|
171
|
-
}
|
|
172
|
-
else {
|
|
173
|
-
inputHandler = (async () => {
|
|
174
|
-
try {
|
|
175
|
-
const outputMessage = await procedure.handler(serviceContext, incoming);
|
|
176
|
-
outgoing.push(outputMessage);
|
|
177
|
-
}
|
|
178
|
-
catch (err) {
|
|
179
|
-
errorHandler(err);
|
|
180
|
-
}
|
|
181
|
-
})();
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
else {
|
|
185
|
-
// procedure is inferred to be never here as this is not a valid procedure type
|
|
186
|
-
// we cast just to log
|
|
187
|
-
log?.warn(`${this.transport.clientId} -- got request for invalid procedure type ${procedure.type} at ${message.serviceName}.${message.procedureName}`);
|
|
188
|
-
return;
|
|
189
|
-
}
|
|
190
|
-
const procStream = {
|
|
191
|
-
id: message.streamId,
|
|
192
|
-
incoming,
|
|
193
|
-
outgoing,
|
|
194
|
-
serviceName: message.serviceName,
|
|
195
|
-
procedureName: message.procedureName,
|
|
196
|
-
procedure,
|
|
197
|
-
promises: { inputHandler, outputHandler },
|
|
198
|
-
};
|
|
199
|
-
this.streamMap.set(message.streamId, procStream);
|
|
200
|
-
// add this stream to ones from that client so we can clean it up in the case of a disconnect without close
|
|
201
|
-
const streamsFromThisClient = this.clientStreams.get(message.from) ?? new Set();
|
|
202
|
-
streamsFromThisClient.add(message.streamId);
|
|
203
|
-
this.clientStreams.set(message.from, streamsFromThisClient);
|
|
204
|
-
return procStream;
|
|
205
|
-
}
|
|
206
|
-
async pushToStream(procStream, message, isInit) {
|
|
207
|
-
const procedure = procStream.procedure;
|
|
208
|
-
const procHasInitMessage = 'init' in procedure;
|
|
209
|
-
if ((isInit &&
|
|
210
|
-
procHasInitMessage &&
|
|
211
|
-
Value.Check(procedure.init, message.payload)) ||
|
|
212
|
-
Value.Check(procedure.input, message.payload)) {
|
|
213
|
-
procStream.incoming.push(message.payload);
|
|
214
|
-
}
|
|
215
|
-
else if (!Value.Check(ControlMessagePayloadSchema, message.payload)) {
|
|
216
|
-
log?.error(`${this.transport.clientId} -- procedure ${procStream.serviceName}.${procStream.procedureName} received invalid payload: ${JSON.stringify(message.payload)}`);
|
|
217
|
-
}
|
|
218
|
-
if (isStreamClose(message.controlFlags)) {
|
|
219
|
-
await this.cleanupStream(message.streamId);
|
|
220
|
-
const streamsFromThisClient = this.clientStreams.get(message.from);
|
|
221
|
-
if (streamsFromThisClient) {
|
|
222
|
-
streamsFromThisClient.delete(message.streamId);
|
|
223
|
-
if (streamsFromThisClient.size === 0) {
|
|
224
|
-
this.clientStreams.delete(message.from);
|
|
225
|
-
}
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
getContext(service) {
|
|
230
|
-
const context = this.contextMap.get(service);
|
|
231
|
-
if (!context) {
|
|
232
|
-
const err = `${this.transport.clientId} -- no context found for ${service.name}`;
|
|
233
|
-
log?.error(err);
|
|
234
|
-
throw new Error(err);
|
|
235
|
-
}
|
|
236
|
-
return context;
|
|
237
|
-
}
|
|
238
|
-
cleanupStream = async (id) => {
|
|
239
|
-
const stream = this.streamMap.get(id);
|
|
240
|
-
if (!stream) {
|
|
241
|
-
return;
|
|
242
|
-
}
|
|
243
|
-
stream.incoming.end();
|
|
244
|
-
await stream.promises.inputHandler;
|
|
245
|
-
stream.outgoing.end();
|
|
246
|
-
await stream.promises.outputHandler;
|
|
247
|
-
this.streamMap.delete(id);
|
|
248
|
-
};
|
|
249
|
-
}
|
|
250
|
-
/**
|
|
251
|
-
* Creates a server instance that listens for incoming messages from a transport and routes them to the appropriate service and procedure.
|
|
252
|
-
* The server tracks the state of each service along with open streams and the extended context object.
|
|
253
|
-
* @param transport - The transport to listen to.
|
|
254
|
-
* @param services - An object containing all the services to be registered on the server.
|
|
255
|
-
* @param extendedContext - An optional object containing additional context to be passed to all services.
|
|
256
|
-
* @returns A promise that resolves to a server instance with the registered services.
|
|
257
|
-
*/
|
|
258
|
-
export function createServer(transport, services, extendedContext) {
|
|
259
|
-
return new RiverServer(transport, services, extendedContext);
|
|
260
|
-
}
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import { OpaqueTransportMessage } from './message';
|
|
2
|
-
import { Connection } from './transport';
|
|
3
|
-
export interface EventMap {
|
|
4
|
-
message: OpaqueTransportMessage;
|
|
5
|
-
connectionStatus: {
|
|
6
|
-
status: 'connect' | 'disconnect';
|
|
7
|
-
conn: Connection;
|
|
8
|
-
};
|
|
9
|
-
}
|
|
10
|
-
export type EventTypes = keyof EventMap;
|
|
11
|
-
export type EventHandler<K extends EventTypes> = (event: EventMap[K]) => void;
|
|
12
|
-
export declare class EventDispatcher<T extends EventTypes> {
|
|
13
|
-
private eventListeners;
|
|
14
|
-
numberOfListeners<K extends T>(eventType: K): number;
|
|
15
|
-
addEventListener<K extends T>(eventType: K, handler: EventHandler<K>): void;
|
|
16
|
-
removeEventListener<K extends T>(eventType: K, handler: EventHandler<K>): void;
|
|
17
|
-
dispatchEvent<K extends T>(eventType: K, event: EventMap[K]): void;
|
|
18
|
-
}
|
|
19
|
-
//# sourceMappingURL=events.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../../transport/events.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,WAAW,CAAC;AACnD,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,MAAM,WAAW,QAAQ;IACvB,OAAO,EAAE,sBAAsB,CAAC;IAChC,gBAAgB,EAAE;QAChB,MAAM,EAAE,SAAS,GAAG,YAAY,CAAC;QACjC,IAAI,EAAE,UAAU,CAAC;KAClB,CAAC;CACH;AAED,MAAM,MAAM,UAAU,GAAG,MAAM,QAAQ,CAAC;AACxC,MAAM,MAAM,YAAY,CAAC,CAAC,SAAS,UAAU,IAAI,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC;AAE9E,qBAAa,eAAe,CAAC,CAAC,SAAS,UAAU;IAC/C,OAAO,CAAC,cAAc,CAA2C;IAEjE,iBAAiB,CAAC,CAAC,SAAS,CAAC,EAAE,SAAS,EAAE,CAAC;IAI3C,gBAAgB,CAAC,CAAC,SAAS,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC;IAQpE,mBAAmB,CAAC,CAAC,SAAS,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC;IAOvE,aAAa,CAAC,CAAC,SAAS,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC;CAQ5D"}
|
package/dist/transport/events.js
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
export class EventDispatcher {
|
|
2
|
-
eventListeners = {};
|
|
3
|
-
numberOfListeners(eventType) {
|
|
4
|
-
return this.eventListeners[eventType]?.size ?? 0;
|
|
5
|
-
}
|
|
6
|
-
addEventListener(eventType, handler) {
|
|
7
|
-
if (!this.eventListeners[eventType]) {
|
|
8
|
-
this.eventListeners[eventType] = new Set();
|
|
9
|
-
}
|
|
10
|
-
this.eventListeners[eventType]?.add(handler);
|
|
11
|
-
}
|
|
12
|
-
removeEventListener(eventType, handler) {
|
|
13
|
-
const handlers = this.eventListeners[eventType];
|
|
14
|
-
if (handlers) {
|
|
15
|
-
this.eventListeners[eventType]?.delete(handler);
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
dispatchEvent(eventType, event) {
|
|
19
|
-
const handlers = this.eventListeners[eventType];
|
|
20
|
-
if (handlers) {
|
|
21
|
-
for (const handler of handlers) {
|
|
22
|
-
handler(event);
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
}
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
/// <reference types="node" />
|
|
2
|
-
import { Codec } from '../../../codec';
|
|
3
|
-
import { TransportClientId } from '../../message';
|
|
4
|
-
import { Connection, Transport } from '../../transport';
|
|
5
|
-
export declare class StdioConnection extends Connection {
|
|
6
|
-
output: NodeJS.WritableStream;
|
|
7
|
-
constructor(transport: Transport<StdioConnection>, connectedTo: TransportClientId, output: NodeJS.WritableStream);
|
|
8
|
-
send(payload: Uint8Array): boolean;
|
|
9
|
-
close(): Promise<void>;
|
|
10
|
-
}
|
|
11
|
-
interface Options {
|
|
12
|
-
codec: Codec;
|
|
13
|
-
}
|
|
14
|
-
/**
|
|
15
|
-
* A transport implementation that uses standard input and output streams.
|
|
16
|
-
* @extends Transport
|
|
17
|
-
*/
|
|
18
|
-
export declare class StdioTransport extends Transport<StdioConnection> {
|
|
19
|
-
clientId: TransportClientId;
|
|
20
|
-
input: NodeJS.ReadableStream;
|
|
21
|
-
output: NodeJS.WritableStream;
|
|
22
|
-
/**
|
|
23
|
-
* Constructs a new StdioTransport instance.
|
|
24
|
-
* @param clientId - The ID of the client associated with this transport.
|
|
25
|
-
* @param input - The readable stream to use as input. Defaults to process.stdin.
|
|
26
|
-
* @param output - The writable stream to use as output. Defaults to process.stdout.
|
|
27
|
-
*/
|
|
28
|
-
constructor(clientId: TransportClientId, input?: NodeJS.ReadableStream, output?: NodeJS.WritableStream, providedOptions?: Partial<Options>);
|
|
29
|
-
setupConnectionStatusListeners(): void;
|
|
30
|
-
createNewConnection(to: TransportClientId): Promise<void>;
|
|
31
|
-
}
|
|
32
|
-
export {};
|
|
33
|
-
//# sourceMappingURL=stdio.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"stdio.d.ts","sourceRoot":"","sources":["../../../../transport/impls/stdio/stdio.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAGvC,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAKxD,qBAAa,eAAgB,SAAQ,UAAU;IAC7C,MAAM,EAAE,MAAM,CAAC,cAAc,CAAC;gBAG5B,SAAS,EAAE,SAAS,CAAC,eAAe,CAAC,EACrC,WAAW,EAAE,iBAAiB,EAC9B,MAAM,EAAE,MAAM,CAAC,cAAc;IAM/B,IAAI,CAAC,OAAO,EAAE,UAAU;IAOlB,KAAK;CAGZ;AAED,UAAU,OAAO;IACf,KAAK,EAAE,KAAK,CAAC;CACd;AAMD;;;GAGG;AACH,qBAAa,cAAe,SAAQ,SAAS,CAAC,eAAe,CAAC;IAC5D,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,KAAK,EAAE,MAAM,CAAC,cAAc,CAAiB;IAC7C,MAAM,EAAE,MAAM,CAAC,cAAc,CAAkB;IAE/C;;;;;OAKG;gBAED,QAAQ,EAAE,iBAAiB,EAC3B,KAAK,GAAE,MAAM,CAAC,cAA8B,EAC5C,MAAM,GAAE,MAAM,CAAC,cAA+B,EAC9C,eAAe,CAAC,EAAE,OAAO,CAAC,OAAO,CAAC;IAUpC,8BAA8B,IAAI,IAAI;IAwBhC,mBAAmB,CAAC,EAAE,EAAE,iBAAiB;CAShD"}
|
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
import { NaiveJsonCodec } from '../../../codec/json';
|
|
2
|
-
import { log } from '../../../logging';
|
|
3
|
-
import { Connection, Transport } from '../../transport';
|
|
4
|
-
import readline from 'readline';
|
|
5
|
-
const newlineBuff = new TextEncoder().encode('\n');
|
|
6
|
-
export class StdioConnection extends Connection {
|
|
7
|
-
output;
|
|
8
|
-
constructor(transport, connectedTo, output) {
|
|
9
|
-
super(transport, connectedTo);
|
|
10
|
-
this.output = output;
|
|
11
|
-
}
|
|
12
|
-
send(payload) {
|
|
13
|
-
const out = new Uint8Array(payload.length + newlineBuff.length);
|
|
14
|
-
out.set(payload, 0);
|
|
15
|
-
out.set(newlineBuff, payload.length);
|
|
16
|
-
return this.output.write(out);
|
|
17
|
-
}
|
|
18
|
-
async close() {
|
|
19
|
-
this.output.end();
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
const defaultOptions = {
|
|
23
|
-
codec: NaiveJsonCodec,
|
|
24
|
-
};
|
|
25
|
-
/**
|
|
26
|
-
* A transport implementation that uses standard input and output streams.
|
|
27
|
-
* @extends Transport
|
|
28
|
-
*/
|
|
29
|
-
export class StdioTransport extends Transport {
|
|
30
|
-
clientId;
|
|
31
|
-
input = process.stdin;
|
|
32
|
-
output = process.stdout;
|
|
33
|
-
/**
|
|
34
|
-
* Constructs a new StdioTransport instance.
|
|
35
|
-
* @param clientId - The ID of the client associated with this transport.
|
|
36
|
-
* @param input - The readable stream to use as input. Defaults to process.stdin.
|
|
37
|
-
* @param output - The writable stream to use as output. Defaults to process.stdout.
|
|
38
|
-
*/
|
|
39
|
-
constructor(clientId, input = process.stdin, output = process.stdout, providedOptions) {
|
|
40
|
-
const options = { ...defaultOptions, ...providedOptions };
|
|
41
|
-
super(options.codec, clientId);
|
|
42
|
-
this.clientId = clientId;
|
|
43
|
-
this.input = input;
|
|
44
|
-
this.output = output;
|
|
45
|
-
this.setupConnectionStatusListeners();
|
|
46
|
-
}
|
|
47
|
-
setupConnectionStatusListeners() {
|
|
48
|
-
let conn = undefined;
|
|
49
|
-
const rl = readline.createInterface({
|
|
50
|
-
input: this.input,
|
|
51
|
-
});
|
|
52
|
-
const encoder = new TextEncoder();
|
|
53
|
-
rl.on('line', (msg) => {
|
|
54
|
-
const parsedMsg = this.parseMsg(encoder.encode(msg));
|
|
55
|
-
if (parsedMsg && !this.connections.has(parsedMsg.from)) {
|
|
56
|
-
conn = new StdioConnection(this, parsedMsg.from, this.output);
|
|
57
|
-
this.onConnect(conn);
|
|
58
|
-
}
|
|
59
|
-
this.handleMsg(parsedMsg);
|
|
60
|
-
});
|
|
61
|
-
rl.on('close', () => {
|
|
62
|
-
if (conn) {
|
|
63
|
-
this.onDisconnect(conn);
|
|
64
|
-
}
|
|
65
|
-
});
|
|
66
|
-
}
|
|
67
|
-
async createNewConnection(to) {
|
|
68
|
-
if (this.state === 'destroyed') {
|
|
69
|
-
throw new Error('cant reopen a destroyed connection');
|
|
70
|
-
}
|
|
71
|
-
log?.info(`${this.clientId} -- establishing a new stream to ${to}`);
|
|
72
|
-
const conn = new StdioConnection(this, to, this.output);
|
|
73
|
-
this.onConnect(conn);
|
|
74
|
-
}
|
|
75
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"stdio.test.d.ts","sourceRoot":"","sources":["../../../../transport/impls/stdio/stdio.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import { describe, test, expect } from 'vitest';
|
|
2
|
-
import stream from 'node:stream';
|
|
3
|
-
import { StdioTransport } from './stdio';
|
|
4
|
-
import { payloadToTransportMessage, waitForMessage, } from '../../../util/testHelpers';
|
|
5
|
-
import { ensureTransportIsClean } from '../../../__tests__/fixtures/cleanup';
|
|
6
|
-
describe('sending and receiving across node streams works', () => {
|
|
7
|
-
test('basic send/receive', async () => {
|
|
8
|
-
const clientToServer = new stream.PassThrough();
|
|
9
|
-
const serverToClient = new stream.PassThrough();
|
|
10
|
-
const serverTransport = new StdioTransport('abc', clientToServer, serverToClient);
|
|
11
|
-
const clientTransport = new StdioTransport('def', serverToClient, clientToServer);
|
|
12
|
-
const msg = {
|
|
13
|
-
msg: 'cool',
|
|
14
|
-
test: 123,
|
|
15
|
-
};
|
|
16
|
-
const p = waitForMessage(serverTransport);
|
|
17
|
-
clientTransport.send(payloadToTransportMessage(msg, 'stream', clientTransport.clientId, serverTransport.clientId));
|
|
18
|
-
await expect(p).resolves.toStrictEqual(msg);
|
|
19
|
-
await clientTransport.close();
|
|
20
|
-
await serverTransport.close();
|
|
21
|
-
await ensureTransportIsClean(clientTransport);
|
|
22
|
-
await ensureTransportIsClean(serverTransport);
|
|
23
|
-
});
|
|
24
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../../../transport/impls/ws/client.ts"],"names":[],"mappings":";AAAA,OAAO,SAAS,MAAM,eAAe,CAAC;AACtC,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAElD,OAAO,EAAE,KAAK,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAC5C,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAEnD,UAAU,OAAO;IACf,eAAe,EAAE,MAAM,CAAC;IACxB,gBAAgB,EAAE,MAAM,CAAC;IACzB,KAAK,EAAE,KAAK,CAAC;CACd;AAQD,KAAK,eAAe,GAAG;IAAE,EAAE,EAAE,SAAS,CAAA;CAAE,GAAG;IAAE,GAAG,EAAE,MAAM,CAAA;CAAE,CAAC;AAE3D;;;;GAIG;AACH,qBAAa,wBAAyB,SAAQ,SAAS,CAAC,mBAAmB,CAAC;IAC1E;;OAEG;IACH,QAAQ,EAAE,CAAC,EAAE,EAAE,iBAAiB,KAAK,OAAO,CAAC,SAAS,CAAC,CAAC;IACxD,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,iBAAiB,EAAE,GAAG,CAAC,iBAAiB,EAAE,OAAO,CAAC,eAAe,CAAC,CAAC,CAAC;IACpE,eAAe,EAAE,OAAO,CAAQ;IAEhC;;;;;OAKG;gBAED,QAAQ,EAAE,MAAM,OAAO,CAAC,SAAS,CAAC,EAClC,QAAQ,EAAE,iBAAiB,EAC3B,QAAQ,EAAE,iBAAiB,EAC3B,eAAe,CAAC,EAAE,OAAO,CAAC,OAAO,CAAC;IAWpC,8BAA8B,IAAI,IAAI;IAIhC,mBAAmB,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,SAAI;CA6ElD"}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
/// <reference types="ws" />
|
|
2
|
-
import { TransportClientId } from '../../message';
|
|
3
|
-
import { Connection, Transport } from '../../transport';
|
|
4
|
-
import WebSocket from 'isomorphic-ws';
|
|
5
|
-
export declare class WebSocketConnection extends Connection {
|
|
6
|
-
ws: WebSocket;
|
|
7
|
-
constructor(transport: Transport<WebSocketConnection>, connectedTo: TransportClientId, ws: WebSocket);
|
|
8
|
-
send(payload: Uint8Array): boolean;
|
|
9
|
-
close(): Promise<void>;
|
|
10
|
-
}
|
|
11
|
-
//# sourceMappingURL=connection.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"connection.d.ts","sourceRoot":"","sources":["../../../../transport/impls/ws/connection.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACxD,OAAO,SAAS,MAAM,eAAe,CAAC;AAEtC,qBAAa,mBAAoB,SAAQ,UAAU;IACjD,EAAE,EAAE,SAAS,CAAC;gBAGZ,SAAS,EAAE,SAAS,CAAC,mBAAmB,CAAC,EACzC,WAAW,EAAE,iBAAiB,EAC9B,EAAE,EAAE,SAAS;IAUf,IAAI,CAAC,OAAO,EAAE,UAAU;IASlB,KAAK;CAGZ"}
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import { Connection } from '../../transport';
|
|
2
|
-
export class WebSocketConnection extends Connection {
|
|
3
|
-
ws;
|
|
4
|
-
constructor(transport, connectedTo, ws) {
|
|
5
|
-
super(transport, connectedTo);
|
|
6
|
-
this.ws = ws;
|
|
7
|
-
ws.binaryType = 'arraybuffer';
|
|
8
|
-
// take over the onmessage for this websocket
|
|
9
|
-
this.ws.onmessage = (msg) => transport.onMessage(msg.data);
|
|
10
|
-
}
|
|
11
|
-
send(payload) {
|
|
12
|
-
if (this.ws.readyState === this.ws.OPEN) {
|
|
13
|
-
this.ws.send(payload);
|
|
14
|
-
return true;
|
|
15
|
-
}
|
|
16
|
-
else {
|
|
17
|
-
return false;
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
async close() {
|
|
21
|
-
this.ws.close();
|
|
22
|
-
}
|
|
23
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../../../transport/impls/ws/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAkB,MAAM,gBAAgB,CAAC;AAEvD,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,MAAM,EAAE,MAAM,IAAI,CAAC;AAC5B,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC1C,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAEnD,UAAU,OAAO;IACf,KAAK,EAAE,KAAK,CAAC;CACd;AAMD,qBAAa,wBAAyB,SAAQ,SAAS,CAAC,mBAAmB,CAAC;IAC1E,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,iBAAiB,CAAC;gBAG1B,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,iBAAiB,EAC3B,eAAe,CAAC,EAAE,OAAO,CAAC,OAAO,CAAC;IASpC,iBAAiB,OAAQ,SAAS,UA6BhC;IAEF,8BAA8B,IAAI,IAAI;IAIhC,mBAAmB,CAAC,EAAE,EAAE,MAAM;IAM9B,KAAK;CAIZ"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ws.test.d.ts","sourceRoot":"","sources":["../../../../transport/impls/ws/ws.test.ts"],"names":[],"mappings":""}
|