@nmtjs/protocol 0.15.0-beta.37 → 0.15.0-beta.39
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/LICENSE.md +1 -1
- package/README.md +1 -1
- package/dist/client/format.d.ts +18 -13
- package/dist/client/format.js +1 -0
- package/dist/client/format.js.map +1 -0
- package/dist/client/index.d.ts +4 -1
- package/dist/client/index.js +7 -4
- package/dist/client/index.js.map +1 -0
- package/dist/client/protocol.d.ts +102 -138
- package/dist/client/protocol.js +7 -336
- package/dist/client/protocol.js.map +1 -0
- package/dist/client/stream.d.ts +34 -19
- package/dist/client/stream.js +138 -46
- package/dist/client/stream.js.map +1 -0
- package/dist/client/versions/v1.d.ts +108 -0
- package/dist/client/versions/v1.js +128 -0
- package/dist/client/versions/v1.js.map +1 -0
- package/dist/common/binary.d.ts +5 -6
- package/dist/common/binary.js +22 -9
- package/dist/common/binary.js.map +1 -0
- package/dist/common/blob.d.ts +14 -8
- package/dist/common/blob.js +55 -30
- package/dist/common/blob.js.map +1 -0
- package/dist/common/constants.d.ts +2 -0
- package/dist/common/constants.js +2 -0
- package/dist/common/constants.js.map +1 -0
- package/dist/common/enums.d.ts +17 -7
- package/dist/common/enums.js +34 -14
- package/dist/common/enums.js.map +1 -0
- package/dist/common/index.d.ts +2 -0
- package/dist/common/index.js +7 -4
- package/dist/common/index.js.map +1 -0
- package/dist/common/types.d.ts +5 -24
- package/dist/common/types.js +1 -0
- package/dist/common/types.js.map +1 -0
- package/dist/common/utils.d.ts +2 -0
- package/dist/common/utils.js +7 -0
- package/dist/common/utils.js.map +1 -0
- package/dist/server/format.d.ts +17 -23
- package/dist/server/format.js +13 -8
- package/dist/server/format.js.map +1 -0
- package/dist/server/index.d.ts +4 -6
- package/dist/server/index.js +9 -11
- package/dist/server/index.js.map +1 -0
- package/dist/server/protocol.d.ts +88 -114
- package/dist/server/protocol.js +5 -354
- package/dist/server/protocol.js.map +1 -0
- package/dist/server/stream.d.ts +5 -0
- package/dist/server/stream.js +31 -2
- package/dist/server/stream.js.map +1 -0
- package/dist/server/types.d.ts +29 -8
- package/dist/server/types.js +1 -0
- package/dist/server/types.js.map +1 -0
- package/dist/server/utils.d.ts +3 -6
- package/dist/server/utils.js +5 -4
- package/dist/server/utils.js.map +1 -0
- package/dist/server/versions/v1.d.ts +77 -0
- package/dist/server/versions/v1.js +119 -0
- package/dist/server/versions/v1.js.map +1 -0
- package/package.json +18 -24
- package/src/client/format.ts +49 -0
- package/src/client/index.ts +8 -0
- package/src/client/protocol.ts +107 -0
- package/src/client/stream.ts +222 -0
- package/src/client/versions/v1.ts +205 -0
- package/src/common/binary.ts +70 -0
- package/src/common/blob.ts +94 -0
- package/src/common/constants.ts +2 -0
- package/src/common/enums.ts +62 -0
- package/src/common/index.ts +6 -0
- package/src/common/types.ts +18 -0
- package/src/common/utils.ts +12 -0
- package/src/server/format.ts +117 -0
- package/src/server/index.ts +10 -0
- package/src/server/protocol.ts +97 -0
- package/src/server/stream.ts +72 -0
- package/src/server/types.ts +42 -0
- package/src/server/utils.ts +22 -0
- package/src/server/versions/v1.ts +198 -0
- package/dist/client/events.d.ts +0 -15
- package/dist/client/events.js +0 -28
- package/dist/server/api.d.ts +0 -33
- package/dist/server/api.js +0 -7
- package/dist/server/connection.d.ts +0 -25
- package/dist/server/connection.js +0 -22
- package/dist/server/constants.d.ts +0 -4
- package/dist/server/constants.js +0 -2
- package/dist/server/injectables.d.ts +0 -14
- package/dist/server/injectables.js +0 -22
- package/dist/server/registry.d.ts +0 -3
- package/dist/server/registry.js +0 -3
- package/dist/server/transport.d.ts +0 -23
- package/dist/server/transport.js +0 -3
package/dist/server/protocol.js
CHANGED
|
@@ -1,12 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { Hook, Scope } from '@nmtjs/core';
|
|
3
|
-
import { concat, decodeNumber, encodeNumber } from "../common/binary.js";
|
|
4
|
-
import { ErrorCode, ServerMessageType } from "../common/enums.js";
|
|
5
|
-
import { isIterableResult } from "./api.js";
|
|
6
|
-
import { Connection, ConnectionContext } from "./connection.js";
|
|
7
|
-
import { ProtocolInjectables } from "./injectables.js";
|
|
8
|
-
import { ProtocolClientStream, ProtocolServerStream } from "./stream.js";
|
|
9
|
-
import { getFormat } from "./utils.js";
|
|
1
|
+
import { concat } from '../common/binary.js';
|
|
10
2
|
export class ProtocolError extends Error {
|
|
11
3
|
code;
|
|
12
4
|
data;
|
|
@@ -25,350 +17,9 @@ export class ProtocolError extends Error {
|
|
|
25
17
|
return { code: this.code, message: this.message, data: this.data };
|
|
26
18
|
}
|
|
27
19
|
}
|
|
28
|
-
export class
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
constructor(application) {
|
|
32
|
-
this.application = application;
|
|
33
|
-
}
|
|
34
|
-
get(connectionId) {
|
|
35
|
-
const connection = this.#collection.get(connectionId);
|
|
36
|
-
if (!connection)
|
|
37
|
-
throwError('Connection not found');
|
|
38
|
-
return connection;
|
|
39
|
-
}
|
|
40
|
-
async add(transport, options, params) {
|
|
41
|
-
const connection = new Connection(options);
|
|
42
|
-
const format = getFormat(this.application.format, params);
|
|
43
|
-
const container = this.application.container.fork(Scope.Connection);
|
|
44
|
-
const context = new ConnectionContext(container, format);
|
|
45
|
-
container.provide(ProtocolInjectables.connection, connection);
|
|
46
|
-
try {
|
|
47
|
-
await this.initialize(connection);
|
|
48
|
-
this.#collection.set(connection.id, { connection, context, transport });
|
|
49
|
-
return { connection, context };
|
|
50
|
-
}
|
|
51
|
-
catch (error) {
|
|
52
|
-
container.dispose().catch((error) => {
|
|
53
|
-
this.application.logger.error({ error, connection }, 'Error during disposing connection');
|
|
54
|
-
});
|
|
55
|
-
throw error;
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
async remove(connectionId) {
|
|
59
|
-
const { connection, context } = this.get(connectionId);
|
|
60
|
-
this.application.registry.hooks.call(Hook.OnDisconnect, { concurrent: true }, connection);
|
|
61
|
-
this.#collection.delete(connectionId);
|
|
62
|
-
const { rpcs, serverStreams, clientStreams, rpcStreams, container } = context;
|
|
63
|
-
for (const call of rpcs.values()) {
|
|
64
|
-
call.abort(new Error('Connection closed'));
|
|
65
|
-
}
|
|
66
|
-
for (const stream of clientStreams.values()) {
|
|
67
|
-
stream.destroy(new Error('Connection closed'));
|
|
68
|
-
}
|
|
69
|
-
for (const stream of serverStreams.values()) {
|
|
70
|
-
stream.destroy(new Error('Connection closed'));
|
|
71
|
-
}
|
|
72
|
-
for (const stream of rpcStreams.values()) {
|
|
73
|
-
stream.abort(new Error('Connection closed'));
|
|
74
|
-
}
|
|
75
|
-
try {
|
|
76
|
-
await container.dispose();
|
|
77
|
-
}
|
|
78
|
-
catch (error) {
|
|
79
|
-
this.application.logger.error({ error, connection }, 'Error during closing connection');
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
async initialize(connection) {
|
|
83
|
-
await this.application.registry.hooks.call(Hook.OnConnect, { concurrent: false }, connection);
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
export class ProtocolClientStreams {
|
|
87
|
-
connections;
|
|
88
|
-
constructor(connections) {
|
|
89
|
-
this.connections = connections;
|
|
90
|
-
}
|
|
91
|
-
get(connectionId, streamId) {
|
|
92
|
-
const { context } = this.connections.get(connectionId);
|
|
93
|
-
const { clientStreams } = context;
|
|
94
|
-
const stream = clientStreams.get(streamId) ?? throwError('Stream not found');
|
|
95
|
-
return stream;
|
|
96
|
-
}
|
|
97
|
-
remove(connectionId, streamId) {
|
|
98
|
-
const { context } = this.connections.get(connectionId);
|
|
99
|
-
const { clientStreams } = context;
|
|
100
|
-
clientStreams.get(streamId) || throwError('Stream not found');
|
|
101
|
-
clientStreams.delete(streamId);
|
|
102
|
-
}
|
|
103
|
-
add(connectionId, streamId, metadata, read) {
|
|
104
|
-
const { context } = this.connections.get(connectionId);
|
|
105
|
-
const { clientStreams } = context;
|
|
106
|
-
const stream = new ProtocolClientStream(streamId, metadata, { read });
|
|
107
|
-
clientStreams.set(streamId, stream);
|
|
108
|
-
return stream;
|
|
109
|
-
}
|
|
110
|
-
push(connectionId, streamId, chunk) {
|
|
111
|
-
const stream = this.get(connectionId, streamId);
|
|
112
|
-
stream.write(Buffer.from(chunk));
|
|
113
|
-
}
|
|
114
|
-
end(connectionId, streamId) {
|
|
115
|
-
const stream = this.get(connectionId, streamId);
|
|
116
|
-
stream.end(null);
|
|
117
|
-
this.remove(connectionId, streamId);
|
|
118
|
-
}
|
|
119
|
-
abort(connectionId, streamId, error = new Error('Aborted')) {
|
|
120
|
-
const stream = this.get(connectionId, streamId);
|
|
121
|
-
stream.destroy(error);
|
|
122
|
-
this.remove(connectionId, streamId);
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
export class ProtocolServerStreams {
|
|
126
|
-
connections;
|
|
127
|
-
constructor(connections) {
|
|
128
|
-
this.connections = connections;
|
|
129
|
-
}
|
|
130
|
-
get(connectionId, streamId) {
|
|
131
|
-
const { context } = this.connections.get(connectionId);
|
|
132
|
-
const { serverStreams } = context;
|
|
133
|
-
const stream = serverStreams.get(streamId) ?? throwError('Stream not found');
|
|
134
|
-
return stream;
|
|
135
|
-
}
|
|
136
|
-
add(connectionId, streamId, blob) {
|
|
137
|
-
const { context } = this.connections.get(connectionId);
|
|
138
|
-
const { serverStreams } = context;
|
|
139
|
-
const stream = new ProtocolServerStream(streamId, blob);
|
|
140
|
-
serverStreams.set(streamId, stream);
|
|
141
|
-
return stream;
|
|
142
|
-
}
|
|
143
|
-
remove(connectionId, streamId) {
|
|
144
|
-
const { context } = this.connections.get(connectionId);
|
|
145
|
-
const { serverStreams } = context;
|
|
146
|
-
serverStreams.has(streamId) || throwError('Stream not found');
|
|
147
|
-
serverStreams.delete(streamId);
|
|
148
|
-
}
|
|
149
|
-
pull(connectionId, streamId) {
|
|
150
|
-
const stream = this.get(connectionId, streamId);
|
|
151
|
-
stream.resume();
|
|
152
|
-
}
|
|
153
|
-
abort(connectionId, streamId, error = new Error('Aborted')) {
|
|
154
|
-
const stream = this.get(connectionId, streamId);
|
|
155
|
-
stream.destroy(error);
|
|
156
|
-
this.remove(connectionId, streamId);
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
export class Protocol {
|
|
160
|
-
application;
|
|
161
|
-
options;
|
|
162
|
-
#connections;
|
|
163
|
-
#clientStreams;
|
|
164
|
-
#serverStreams;
|
|
165
|
-
constructor(application, options) {
|
|
166
|
-
this.application = application;
|
|
167
|
-
this.options = options;
|
|
168
|
-
this.#connections = new ProtocolConnections(this.application);
|
|
169
|
-
this.#clientStreams = new ProtocolClientStreams(this.#connections);
|
|
170
|
-
this.#serverStreams = new ProtocolServerStreams(this.#connections);
|
|
171
|
-
}
|
|
172
|
-
async call(options) {
|
|
173
|
-
const { container, connection } = options;
|
|
174
|
-
try {
|
|
175
|
-
return await this.application.api.call(options);
|
|
176
|
-
}
|
|
177
|
-
catch (error) {
|
|
178
|
-
if (error instanceof ProtocolError === false) {
|
|
179
|
-
this.application.logger.error({ error, connection }, 'Error during RPC call');
|
|
180
|
-
throw new ProtocolError(ErrorCode.InternalServerError, 'Internal server error');
|
|
181
|
-
}
|
|
182
|
-
throw error;
|
|
183
|
-
}
|
|
184
|
-
finally {
|
|
185
|
-
container.dispose().catch((error) => {
|
|
186
|
-
this.application.logger.error({ error, connection }, "Error during disposing connection's container");
|
|
187
|
-
});
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
async rpc(connectionId, rpc, params = {}) {
|
|
191
|
-
const { connection, context, transport } = this.#connections.get(connectionId);
|
|
192
|
-
const { rpcs, format } = context;
|
|
193
|
-
const { callId, procedure, payload } = rpc;
|
|
194
|
-
const abortController = new AbortController();
|
|
195
|
-
const signal = params.signal
|
|
196
|
-
? AbortSignal.any([params.signal, abortController.signal])
|
|
197
|
-
: abortController.signal;
|
|
198
|
-
rpcs.set(callId, abortController);
|
|
199
|
-
const callIdEncoded = encodeNumber(callId, 'Uint32');
|
|
200
|
-
const container = context.container.fork(Scope.Call);
|
|
201
|
-
if (params.provides) {
|
|
202
|
-
for (const [key, value] of params.provides) {
|
|
203
|
-
container.provide(key, value);
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
try {
|
|
207
|
-
const response = await this.call({
|
|
208
|
-
connection,
|
|
209
|
-
container,
|
|
210
|
-
payload,
|
|
211
|
-
procedure,
|
|
212
|
-
signal,
|
|
213
|
-
validateMetadata: params.validateMetadata,
|
|
214
|
-
});
|
|
215
|
-
const responseEncoded = format.encoder.encodeRPC({ callId, result: response.output }, {
|
|
216
|
-
addStream: (blob) => {
|
|
217
|
-
const streamId = context.streamId++;
|
|
218
|
-
const stream = this.#serverStreams.add(connectionId, streamId, blob);
|
|
219
|
-
stream.on('data', (chunk) => {
|
|
220
|
-
stream.pause();
|
|
221
|
-
const buf = Buffer.from(chunk);
|
|
222
|
-
transport.send(connection, ServerMessageType.ServerStreamPush, concat(encodeNumber(streamId, 'Uint32'), buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength)), { callId, streamId });
|
|
223
|
-
});
|
|
224
|
-
stream.on('error', () => {
|
|
225
|
-
transport.send(connection, ServerMessageType.ServerStreamAbort, encodeNumber(streamId, 'Uint32'), { callId, streamId });
|
|
226
|
-
});
|
|
227
|
-
stream.on('end', () => {
|
|
228
|
-
transport.send(connection, ServerMessageType.ServerStreamEnd, encodeNumber(streamId, 'Uint32'), { callId, streamId });
|
|
229
|
-
});
|
|
230
|
-
return stream;
|
|
231
|
-
},
|
|
232
|
-
getStream: (id) => {
|
|
233
|
-
return this.#serverStreams.get(connectionId, id);
|
|
234
|
-
},
|
|
235
|
-
});
|
|
236
|
-
if (isIterableResult(response)) {
|
|
237
|
-
transport.send(connection, ServerMessageType.RpcStreamResponse, responseEncoded, { callId });
|
|
238
|
-
try {
|
|
239
|
-
const controller = new AbortController();
|
|
240
|
-
context.rpcStreams.set(callId, controller);
|
|
241
|
-
const iterable = typeof response.iterable === 'function'
|
|
242
|
-
? await response.iterable(controller.signal)
|
|
243
|
-
: response.iterable;
|
|
244
|
-
try {
|
|
245
|
-
for await (const chunk of iterable) {
|
|
246
|
-
controller.signal.throwIfAborted();
|
|
247
|
-
const chunkEncoded = format.encoder.encode(chunk);
|
|
248
|
-
transport.send(connection, ServerMessageType.RpcStreamChunk, concat(callIdEncoded, chunkEncoded), { callId });
|
|
249
|
-
}
|
|
250
|
-
transport.send(connection, ServerMessageType.RpcStreamEnd, callIdEncoded, { callId });
|
|
251
|
-
}
|
|
252
|
-
catch (error) {
|
|
253
|
-
// do not re-throw AbortError errors, they are expected
|
|
254
|
-
if (!isAbortError(error)) {
|
|
255
|
-
throw error;
|
|
256
|
-
}
|
|
257
|
-
}
|
|
258
|
-
}
|
|
259
|
-
catch (error) {
|
|
260
|
-
this.application.logger.error(error);
|
|
261
|
-
transport.send(connection, ServerMessageType.RpcStreamAbort, callIdEncoded, { callId });
|
|
262
|
-
}
|
|
263
|
-
finally {
|
|
264
|
-
context.rpcStreams.delete(callId);
|
|
265
|
-
response.onFinish && defer(response.onFinish);
|
|
266
|
-
}
|
|
267
|
-
}
|
|
268
|
-
else {
|
|
269
|
-
transport.send(connection, ServerMessageType.RpcResponse, responseEncoded, { callId });
|
|
270
|
-
}
|
|
271
|
-
}
|
|
272
|
-
catch (error) {
|
|
273
|
-
const payload = format.encoder.encodeRPC({ callId, error }, {
|
|
274
|
-
addStream() {
|
|
275
|
-
throwError('Cannot handle stream for error response');
|
|
276
|
-
},
|
|
277
|
-
getStream() {
|
|
278
|
-
throwError('Cannot handle stream for error response');
|
|
279
|
-
},
|
|
280
|
-
});
|
|
281
|
-
transport.send(connection, ServerMessageType.RpcResponse, payload, {
|
|
282
|
-
error,
|
|
283
|
-
callId,
|
|
284
|
-
});
|
|
285
|
-
}
|
|
286
|
-
finally {
|
|
287
|
-
rpcs.delete(callId);
|
|
288
|
-
container.dispose().catch((error) => {
|
|
289
|
-
this.application.logger.error({ error, connection }, 'Error during disposing connection');
|
|
290
|
-
});
|
|
291
|
-
}
|
|
292
|
-
}
|
|
293
|
-
async rpcRaw(connectionId, buffer, params = {}) {
|
|
294
|
-
const { connection, context, transport } = this.#connections.get(connectionId);
|
|
295
|
-
const { format } = context;
|
|
296
|
-
const rpc = format.decoder.decodeRPC(buffer, {
|
|
297
|
-
addStream: (streamId, callId, metadata) => {
|
|
298
|
-
return this.#clientStreams.add(connectionId, streamId, metadata, (size) => {
|
|
299
|
-
transport.send(connection, ServerMessageType.ClientStreamPull, concat(encodeNumber(streamId, 'Uint32'), encodeNumber(size, 'Uint32')), { callId, streamId });
|
|
300
|
-
});
|
|
301
|
-
},
|
|
302
|
-
getStream: (id) => {
|
|
303
|
-
return this.#clientStreams.get(connectionId, id);
|
|
304
|
-
},
|
|
305
|
-
});
|
|
306
|
-
return await this.rpc(connectionId, rpc, params);
|
|
307
|
-
}
|
|
308
|
-
rpcAbort(connectionId, callId) {
|
|
309
|
-
const { context } = this.#connections.get(connectionId);
|
|
310
|
-
const call = context.rpcs.get(callId) ?? throwError('Call not found');
|
|
311
|
-
call.abort();
|
|
312
|
-
}
|
|
313
|
-
rpcAbortRaw(connectionId, buffer) {
|
|
314
|
-
const callId = decodeNumber(buffer, 'Uint32');
|
|
315
|
-
return this.rpcAbort(connectionId, callId);
|
|
316
|
-
}
|
|
317
|
-
rpcStreamAbort(connectionId, callId) {
|
|
318
|
-
const { context } = this.#connections.get(connectionId);
|
|
319
|
-
const ab = context.rpcStreams.get(callId) ?? throwError('Call stream not found');
|
|
320
|
-
ab.abort();
|
|
321
|
-
}
|
|
322
|
-
rpcStreamAbortRaw(connectionId, buffer) {
|
|
323
|
-
const callId = decodeNumber(buffer, 'Uint32');
|
|
324
|
-
return this.rpcStreamAbort(connectionId, callId);
|
|
325
|
-
}
|
|
326
|
-
notify() {
|
|
327
|
-
throw Error('Unimplemented');
|
|
328
|
-
}
|
|
329
|
-
addConnection(transport, options, params) {
|
|
330
|
-
return this.#connections.add(transport, options, params);
|
|
331
|
-
}
|
|
332
|
-
removeConnection(connectionId) {
|
|
333
|
-
return this.#connections.remove(connectionId);
|
|
334
|
-
}
|
|
335
|
-
getConnection(connectionId) {
|
|
336
|
-
return this.#connections.get(connectionId);
|
|
337
|
-
}
|
|
338
|
-
initializeConnection(connection) {
|
|
339
|
-
return this.#connections.initialize(connection);
|
|
340
|
-
}
|
|
341
|
-
getClientStream(connectionId, streamId) {
|
|
342
|
-
return this.#clientStreams.get(connectionId, streamId);
|
|
343
|
-
}
|
|
344
|
-
addClientStream(connectionId, streamId, metadata, read) {
|
|
345
|
-
return this.#clientStreams.add(connectionId, streamId, metadata, read);
|
|
346
|
-
}
|
|
347
|
-
removeClientStream(connectionId, streamId) {
|
|
348
|
-
return this.#clientStreams.remove(connectionId, streamId);
|
|
349
|
-
}
|
|
350
|
-
pushClientStream(connectionId, streamId, chunk) {
|
|
351
|
-
return this.#clientStreams.push(connectionId, streamId, chunk);
|
|
352
|
-
}
|
|
353
|
-
endClientStream(connectionId, streamId) {
|
|
354
|
-
return this.#clientStreams.end(connectionId, streamId);
|
|
355
|
-
}
|
|
356
|
-
abortClientStream(connectionId, streamId, error) {
|
|
357
|
-
return this.#clientStreams.abort(connectionId, streamId, error);
|
|
358
|
-
}
|
|
359
|
-
getServerStream(connectionId, streamId) {
|
|
360
|
-
return this.#serverStreams.get(connectionId, streamId);
|
|
361
|
-
}
|
|
362
|
-
addServerStream(connectionId, streamId, blob) {
|
|
363
|
-
return this.#serverStreams.add(connectionId, streamId, blob);
|
|
364
|
-
}
|
|
365
|
-
removeServerStream(connectionId, streamId) {
|
|
366
|
-
return this.#serverStreams.remove(connectionId, streamId);
|
|
367
|
-
}
|
|
368
|
-
pullServerStream(connectionId, streamId) {
|
|
369
|
-
return this.#serverStreams.pull(connectionId, streamId);
|
|
370
|
-
}
|
|
371
|
-
abortServerStream(connectionId, streamId, error) {
|
|
372
|
-
return this.#serverStreams.abort(connectionId, streamId, error);
|
|
20
|
+
export class ProtocolVersionInterface {
|
|
21
|
+
encode(...chunks) {
|
|
22
|
+
return concat(...chunks);
|
|
373
23
|
}
|
|
374
24
|
}
|
|
25
|
+
//# sourceMappingURL=protocol.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"protocol.js","sourceRoot":"","sources":["../../src/server/protocol.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAA;AAE5C,MAAM,OAAO,aAAc,SAAQ,KAAK;IACtC,IAAI,CAAQ;IACZ,IAAI,CAAM;IAEV,YAAY,IAAY,EAAE,OAAgB,EAAE,IAAU,EAAE;QACtD,KAAK,CAAC,OAAO,CAAC,CAAA;QACd,IAAI,CAAC,IAAI,GAAG,IAAI,CAAA;QAChB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAA;IAAA,CACjB;IAED,IAAI,OAAO,GAAG;QACZ,OAAO,GAAG,IAAI,CAAC,IAAI,IAAI,KAAK,CAAC,OAAO,EAAE,CAAA;IAAA,CACvC;IAED,QAAQ,GAAG;QACT,OAAO,GAAG,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,OAAO,EAAE,CAAA;IAAA,CACtC;IAED,MAAM,GAAG;QACP,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAA;IAAA,CACnE;CACF;AAED,MAAM,OAAgB,wBAAwB;IAgBlC,MAAM,CACd,GAAG,MAAyC,EAC3B;QACjB,OAAO,MAAM,CAAC,GAAG,MAAM,CAAC,CAAA;IAAA,CACzB;CACF"}
|
package/dist/server/stream.d.ts
CHANGED
|
@@ -2,12 +2,17 @@ import type { ReadableOptions } from 'node:stream';
|
|
|
2
2
|
import { PassThrough } from 'node:stream';
|
|
3
3
|
import type { ProtocolBlob, ProtocolBlobMetadata } from '../common/blob.ts';
|
|
4
4
|
export declare class ProtocolClientStream extends PassThrough {
|
|
5
|
+
#private;
|
|
5
6
|
readonly id: number;
|
|
6
7
|
readonly metadata: ProtocolBlobMetadata;
|
|
7
8
|
constructor(id: number, metadata: ProtocolBlobMetadata, options?: ReadableOptions);
|
|
9
|
+
_read(size: number): void;
|
|
8
10
|
}
|
|
9
11
|
export declare class ProtocolServerStream extends PassThrough {
|
|
12
|
+
#private;
|
|
10
13
|
readonly id: number;
|
|
11
14
|
readonly metadata: ProtocolBlobMetadata;
|
|
12
15
|
constructor(id: number, blob: ProtocolBlob);
|
|
16
|
+
resume(): this;
|
|
17
|
+
destroy(error?: Error | null): this;
|
|
13
18
|
}
|
package/dist/server/stream.js
CHANGED
|
@@ -3,15 +3,26 @@ import { ReadableStream } from 'node:stream/web';
|
|
|
3
3
|
export class ProtocolClientStream extends PassThrough {
|
|
4
4
|
id;
|
|
5
5
|
metadata;
|
|
6
|
+
#read;
|
|
6
7
|
constructor(id, metadata, options) {
|
|
7
|
-
|
|
8
|
+
const { read, ...rest } = options ?? {};
|
|
9
|
+
super(rest);
|
|
8
10
|
this.id = id;
|
|
9
11
|
this.metadata = metadata;
|
|
12
|
+
this.#read = read;
|
|
13
|
+
}
|
|
14
|
+
_read(size) {
|
|
15
|
+
if (this.#read) {
|
|
16
|
+
this.#read.call(this, size);
|
|
17
|
+
}
|
|
18
|
+
super._read(size);
|
|
10
19
|
}
|
|
11
20
|
}
|
|
12
21
|
export class ProtocolServerStream extends PassThrough {
|
|
13
22
|
id;
|
|
14
23
|
metadata;
|
|
24
|
+
#source;
|
|
25
|
+
#piped = false;
|
|
15
26
|
constructor(id, blob) {
|
|
16
27
|
let readable;
|
|
17
28
|
if (blob.source instanceof Readable) {
|
|
@@ -25,8 +36,26 @@ export class ProtocolServerStream extends PassThrough {
|
|
|
25
36
|
}
|
|
26
37
|
super();
|
|
27
38
|
this.pause();
|
|
28
|
-
readable
|
|
39
|
+
this.#source = readable;
|
|
40
|
+
this.#source.on('error', (error) => {
|
|
41
|
+
this.destroy(error);
|
|
42
|
+
});
|
|
29
43
|
this.id = id;
|
|
30
44
|
this.metadata = blob.metadata;
|
|
31
45
|
}
|
|
46
|
+
resume() {
|
|
47
|
+
if (!this.#piped) {
|
|
48
|
+
this.#piped = true;
|
|
49
|
+
this.#source.pipe(this);
|
|
50
|
+
}
|
|
51
|
+
return super.resume();
|
|
52
|
+
}
|
|
53
|
+
destroy(error) {
|
|
54
|
+
if (!this.#piped) {
|
|
55
|
+
this.#piped = true;
|
|
56
|
+
}
|
|
57
|
+
this.#source.destroy?.(error ?? undefined);
|
|
58
|
+
return super.destroy(error ?? undefined);
|
|
59
|
+
}
|
|
32
60
|
}
|
|
61
|
+
//# sourceMappingURL=stream.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stream.js","sourceRoot":"","sources":["../../src/server/stream.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;AAIhD,MAAM,OAAO,oBAAqB,SAAQ,WAAW;IAIjC,EAAE;IACF,QAAQ;IAJjB,KAAK,CAA0B;IAExC,YACkB,EAAU,EACV,QAA8B,EAC9C,OAAyB,EACzB;QACA,MAAM,EAAE,IAAI,EAAE,GAAG,IAAI,EAAE,GAAG,OAAO,IAAI,EAAE,CAAA;QACvC,KAAK,CAAC,IAAI,CAAC,CAAA;kBALK,EAAE;wBACF,QAAQ;QAKxB,IAAI,CAAC,KAAK,GAAG,IAAI,CAAA;IAAA,CAClB;IAEQ,KAAK,CAAC,IAAY,EAAQ;QACjC,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAA;QAC7B,CAAC;QACD,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;IAAA,CAClB;CACF;AAED,MAAM,OAAO,oBAAqB,SAAQ,WAAW;IACnC,EAAE,CAAQ;IACV,QAAQ,CAAsB;IACrC,OAAO,CAAU;IAC1B,MAAM,GAAG,KAAK,CAAA;IAEd,YAAY,EAAU,EAAE,IAAkB,EAAE;QAC1C,IAAI,QAAkB,CAAA;QAEtB,IAAI,IAAI,CAAC,MAAM,YAAY,QAAQ,EAAE,CAAC;YACpC,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAA;QACxB,CAAC;aAAM,IAAI,IAAI,CAAC,MAAM,YAAY,cAAc,EAAE,CAAC;YACjD,QAAQ,GAAG,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,MAAwB,CAAC,CAAA;QAC5D,CAAC;aAAM,CAAC;YACN,MAAM,IAAI,KAAK,CAAC,qBAAqB,CAAC,CAAA;QACxC,CAAC;QAED,KAAK,EAAE,CAAA;QAEP,IAAI,CAAC,KAAK,EAAE,CAAA;QACZ,IAAI,CAAC,OAAO,GAAG,QAAQ,CAAA;QACvB,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC;YAClC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;QAAA,CACpB,CAAC,CAAA;QAEF,IAAI,CAAC,EAAE,GAAG,EAAE,CAAA;QACZ,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAA;IAAA,CAC9B;IAEQ,MAAM,GAAS;QACtB,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;YACjB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAA;YAClB,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QACzB,CAAC;QACD,OAAO,KAAK,CAAC,MAAM,EAAE,CAAA;IAAA,CACtB;IAEQ,OAAO,CAAC,KAAoB,EAAE;QACrC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;YACjB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAA;QACpB,CAAC;QACD,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,KAAK,IAAI,SAAS,CAAC,CAAA;QAC1C,OAAO,KAAK,CAAC,OAAO,CAAC,KAAK,IAAI,SAAS,CAAC,CAAA;IAAA,CACzC;CACF"}
|
package/dist/server/types.d.ts
CHANGED
|
@@ -1,13 +1,34 @@
|
|
|
1
|
-
import type { PlainType } from '@nmtjs/type
|
|
2
|
-
import type { ProtocolBlobInterface } from '../common/blob.ts';
|
|
1
|
+
import type { PlainType } from '@nmtjs/type';
|
|
2
|
+
import type { ProtocolBlobInterface, ProtocolBlobMetadata } from '../common/blob.ts';
|
|
3
|
+
import type { kBlobKey } from '../common/constants.ts';
|
|
4
|
+
import type { BaseServerDecoder, BaseServerEncoder } from './format.ts';
|
|
5
|
+
import type { ProtocolVersionInterface } from './protocol.ts';
|
|
3
6
|
import type { ProtocolClientStream } from './stream.ts';
|
|
4
|
-
export type
|
|
7
|
+
export type ClientStreamConsumer = (() => ProtocolClientStream) & {
|
|
8
|
+
readonly [kBlobKey]: any;
|
|
9
|
+
readonly metadata: ProtocolBlobMetadata;
|
|
10
|
+
};
|
|
11
|
+
export type MessageContext = {
|
|
12
|
+
protocol: ProtocolVersionInterface;
|
|
13
|
+
connectionId: string;
|
|
14
|
+
streamId: () => number;
|
|
15
|
+
decoder: BaseServerDecoder;
|
|
16
|
+
encoder: BaseServerEncoder;
|
|
17
|
+
addClientStream: (options: {
|
|
18
|
+
streamId: number;
|
|
19
|
+
metadata: ProtocolBlobMetadata;
|
|
20
|
+
callId: number;
|
|
21
|
+
}) => ClientStreamConsumer;
|
|
22
|
+
transport: {
|
|
23
|
+
send?: (connectionId: string, buffer: ArrayBufferView) => boolean | null;
|
|
24
|
+
};
|
|
25
|
+
};
|
|
26
|
+
export type ResolveFormatParams = {
|
|
27
|
+
contentType?: string | null;
|
|
28
|
+
accept?: string | null;
|
|
29
|
+
};
|
|
30
|
+
export type InputType<T> = T extends ProtocolBlobInterface ? ClientStreamConsumer : T extends {
|
|
5
31
|
[PlainType]?: true;
|
|
6
32
|
} ? {
|
|
7
33
|
[K in keyof Omit<T, PlainType>]: InputType<T[K]>;
|
|
8
34
|
} : T;
|
|
9
|
-
export type ProtocolSendMetadata = {
|
|
10
|
-
streamId?: number;
|
|
11
|
-
callId?: number;
|
|
12
|
-
error?: any;
|
|
13
|
-
};
|
package/dist/server/types.js
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/server/types.ts"],"names":[],"mappings":""}
|
package/dist/server/utils.d.ts
CHANGED
|
@@ -1,15 +1,12 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
|
|
3
|
-
contentType?: string | null;
|
|
4
|
-
acceptType?: string | null;
|
|
5
|
-
};
|
|
1
|
+
import type { ProtocolFormats } from './format.ts';
|
|
2
|
+
import type { ResolveFormatParams } from './types.ts';
|
|
6
3
|
export declare class UnsupportedFormatError extends Error {
|
|
7
4
|
}
|
|
8
5
|
export declare class UnsupportedContentTypeError extends UnsupportedFormatError {
|
|
9
6
|
}
|
|
10
7
|
export declare class UnsupportedAcceptTypeError extends UnsupportedFormatError {
|
|
11
8
|
}
|
|
12
|
-
export declare const getFormat: (format:
|
|
9
|
+
export declare const getFormat: (format: ProtocolFormats, { accept, contentType }: ResolveFormatParams) => {
|
|
13
10
|
encoder: import("./format.ts").BaseServerEncoder;
|
|
14
11
|
decoder: import("./format.ts").BaseServerDecoder;
|
|
15
12
|
};
|
package/dist/server/utils.js
CHANGED
|
@@ -4,12 +4,13 @@ export class UnsupportedContentTypeError extends UnsupportedFormatError {
|
|
|
4
4
|
}
|
|
5
5
|
export class UnsupportedAcceptTypeError extends UnsupportedFormatError {
|
|
6
6
|
}
|
|
7
|
-
export const getFormat = (format, {
|
|
7
|
+
export const getFormat = (format, { accept, contentType }) => {
|
|
8
8
|
const encoder = contentType ? format.supportsEncoder(contentType) : undefined;
|
|
9
9
|
if (!encoder)
|
|
10
|
-
throw new UnsupportedContentTypeError('Unsupported Content
|
|
11
|
-
const decoder =
|
|
10
|
+
throw new UnsupportedContentTypeError('Unsupported Content type');
|
|
11
|
+
const decoder = accept ? format.supportsDecoder(accept) : undefined;
|
|
12
12
|
if (!decoder)
|
|
13
|
-
throw new UnsupportedAcceptTypeError('Unsupported Accept
|
|
13
|
+
throw new UnsupportedAcceptTypeError('Unsupported Accept type');
|
|
14
14
|
return { encoder, decoder };
|
|
15
15
|
};
|
|
16
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/server/utils.ts"],"names":[],"mappings":"AAGA,MAAM,OAAO,sBAAuB,SAAQ,KAAK;CAAG;AAEpD,MAAM,OAAO,2BAA4B,SAAQ,sBAAsB;CAAG;AAE1E,MAAM,OAAO,0BAA2B,SAAQ,sBAAsB;CAAG;AAEzE,MAAM,CAAC,MAAM,SAAS,GAAG,CACvB,MAAuB,EACvB,EAAE,MAAM,EAAE,WAAW,EAAuB,EAC5C,EAAE,CAAC;IACH,MAAM,OAAO,GAAG,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,eAAe,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;IAC7E,IAAI,CAAC,OAAO;QACV,MAAM,IAAI,2BAA2B,CAAC,0BAA0B,CAAC,CAAA;IAEnE,MAAM,OAAO,GAAG,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;IACnE,IAAI,CAAC,OAAO;QAAE,MAAM,IAAI,0BAA0B,CAAC,yBAAyB,CAAC,CAAA;IAE7E,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,CAAA;AAAA,CAC5B,CAAA"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import type { ServerMessageTypePayload } from '../protocol.ts';
|
|
2
|
+
import type { MessageContext } from '../types.ts';
|
|
3
|
+
import { ClientMessageType, ProtocolVersion, ServerMessageType } from '../../common/enums.ts';
|
|
4
|
+
import { ProtocolVersionInterface } from '../protocol.ts';
|
|
5
|
+
export declare class ProtocolVersion1 extends ProtocolVersionInterface {
|
|
6
|
+
version: ProtocolVersion;
|
|
7
|
+
decodeMessage(context: MessageContext, buffer: Buffer): {
|
|
8
|
+
callId?: undefined;
|
|
9
|
+
size?: undefined;
|
|
10
|
+
chunk?: undefined;
|
|
11
|
+
streamId?: undefined;
|
|
12
|
+
reason?: undefined;
|
|
13
|
+
type: ClientMessageType.Rpc;
|
|
14
|
+
rpc: {
|
|
15
|
+
callId: number;
|
|
16
|
+
procedure: string;
|
|
17
|
+
payload: unknown;
|
|
18
|
+
};
|
|
19
|
+
} | {
|
|
20
|
+
size?: undefined;
|
|
21
|
+
chunk?: undefined;
|
|
22
|
+
streamId?: undefined;
|
|
23
|
+
reason?: undefined;
|
|
24
|
+
rpc?: undefined;
|
|
25
|
+
type: ClientMessageType.RpcPull;
|
|
26
|
+
callId: number;
|
|
27
|
+
} | {
|
|
28
|
+
size?: undefined;
|
|
29
|
+
chunk?: undefined;
|
|
30
|
+
streamId?: undefined;
|
|
31
|
+
rpc?: undefined;
|
|
32
|
+
type: ClientMessageType.RpcAbort;
|
|
33
|
+
callId: number;
|
|
34
|
+
reason: string | undefined;
|
|
35
|
+
} | {
|
|
36
|
+
callId?: undefined;
|
|
37
|
+
size?: undefined;
|
|
38
|
+
chunk?: undefined;
|
|
39
|
+
rpc?: undefined;
|
|
40
|
+
type: ClientMessageType.ServerStreamAbort;
|
|
41
|
+
streamId: number;
|
|
42
|
+
reason: string | undefined;
|
|
43
|
+
} | {
|
|
44
|
+
callId?: undefined;
|
|
45
|
+
chunk?: undefined;
|
|
46
|
+
reason?: undefined;
|
|
47
|
+
rpc?: undefined;
|
|
48
|
+
type: ClientMessageType.ServerStreamPull;
|
|
49
|
+
streamId: number;
|
|
50
|
+
size: number;
|
|
51
|
+
} | {
|
|
52
|
+
callId?: undefined;
|
|
53
|
+
size?: undefined;
|
|
54
|
+
chunk?: undefined;
|
|
55
|
+
rpc?: undefined;
|
|
56
|
+
type: ClientMessageType.ClientStreamAbort;
|
|
57
|
+
streamId: number;
|
|
58
|
+
reason: string | undefined;
|
|
59
|
+
} | {
|
|
60
|
+
callId?: undefined;
|
|
61
|
+
size?: undefined;
|
|
62
|
+
chunk?: undefined;
|
|
63
|
+
reason?: undefined;
|
|
64
|
+
rpc?: undefined;
|
|
65
|
+
type: ClientMessageType.ClientStreamEnd;
|
|
66
|
+
streamId: number;
|
|
67
|
+
} | {
|
|
68
|
+
callId?: undefined;
|
|
69
|
+
size?: undefined;
|
|
70
|
+
reason?: undefined;
|
|
71
|
+
rpc?: undefined;
|
|
72
|
+
type: ClientMessageType.ClientStreamPush;
|
|
73
|
+
streamId: number;
|
|
74
|
+
chunk: Buffer<ArrayBufferLike>;
|
|
75
|
+
};
|
|
76
|
+
encodeMessage<T extends ServerMessageType>(context: MessageContext, messageType: T, payload: ServerMessageTypePayload[T]): ArrayBufferView<ArrayBufferLike>;
|
|
77
|
+
}
|