@nmtjs/protocol 0.6.0 → 0.6.2
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/client/events.js +3 -16
- package/dist/client/events.js.map +1 -1
- package/dist/client/protocol.js +68 -57
- package/dist/client/protocol.js.map +1 -1
- package/dist/client/stream.js +2 -3
- package/dist/client/stream.js.map +1 -1
- package/dist/server/api.js.map +1 -1
- package/dist/server/connection.js +1 -0
- package/dist/server/connection.js.map +1 -1
- package/dist/server/protocol.js +26 -8
- package/dist/server/protocol.js.map +1 -1
- package/lib/client/events.ts +4 -16
- package/lib/client/protocol.ts +108 -68
- package/lib/client/stream.ts +12 -5
- package/lib/server/api.ts +1 -2
- package/lib/server/connection.ts +1 -12
- package/lib/server/protocol.ts +30 -7
- package/package.json +4 -4
package/dist/client/events.js
CHANGED
|
@@ -1,19 +1,7 @@
|
|
|
1
|
-
export function untilAborted(signal) {
|
|
2
|
-
return new Promise((_, reject)=>{
|
|
3
|
-
const handler = ()=>reject(new Error('aborted'));
|
|
4
|
-
const options = {
|
|
5
|
-
once: true
|
|
6
|
-
};
|
|
7
|
-
signal.addEventListener('abort', handler, options);
|
|
8
|
-
});
|
|
9
|
-
}
|
|
10
|
-
export function onAbort(signal, listener) {
|
|
11
|
-
signal.addEventListener('abort', listener, {
|
|
12
|
-
once: true
|
|
13
|
-
});
|
|
14
|
-
return ()=>signal.removeEventListener('abort', listener);
|
|
15
|
-
}
|
|
16
1
|
export class EventEmitter {
|
|
2
|
+
static once(ee, event) {
|
|
3
|
+
return new Promise((resolve)=>ee.once(event, resolve));
|
|
4
|
+
}
|
|
17
5
|
#target = new EventTarget();
|
|
18
6
|
#listeners = new Map();
|
|
19
7
|
on(event, listener, options) {
|
|
@@ -38,4 +26,3 @@ export class EventEmitter {
|
|
|
38
26
|
}));
|
|
39
27
|
}
|
|
40
28
|
}
|
|
41
|
-
export const once = (ee, event)=>new Promise((resolve)=>ee.once(event, resolve));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../lib/client/events.ts"],"sourcesContent":["import type { Callback } from '@nmtjs/common'\n\nexport type EventMap = { [K: string]: any[] }\n\
|
|
1
|
+
{"version":3,"sources":["../../../lib/client/events.ts"],"sourcesContent":["import type { Callback } from '@nmtjs/common'\n\nexport type EventMap = { [K: string]: any[] }\n\n/**\n * Very simple node-like event emitter wrapper around EventTarget\n *\n * @todo add errors and promise rejections handling\n */\nexport class EventEmitter<\n Events extends EventMap = EventMap,\n EventNames extends Extract<keyof Events, string> = Extract<\n keyof Events,\n string\n >,\n> {\n static once(ee: EventEmitter, event: string) {\n return new Promise((resolve) => ee.once(event, resolve))\n }\n\n #target = new EventTarget()\n #listeners = new Map<Callback, Callback>()\n\n on<E extends EventNames>(\n event: E | (Object & string),\n listener: (...args: Events[E]) => void,\n options?: AddEventListenerOptions,\n ) {\n const wrapper = (event) => listener(...event.detail)\n this.#listeners.set(listener, wrapper)\n this.#target.addEventListener(event, wrapper, options)\n return () => this.#target.removeEventListener(event, wrapper)\n }\n\n once<E extends EventNames>(\n event: E | (Object & string),\n listener: (...args: Events[E]) => void,\n options?: AddEventListenerOptions,\n ) {\n return this.on(event, listener, { ...options, once: true })\n }\n\n off(event: EventNames | (Object & string), listener: Callback) {\n const wrapper = this.#listeners.get(listener)\n if (wrapper) this.#target.removeEventListener(event, wrapper)\n }\n\n emit<E extends EventNames | (Object & string)>(\n event: E,\n ...args: E extends EventEmitter ? Events[E] : any[]\n ) {\n return this.#target.dispatchEvent(new CustomEvent(event, { detail: args }))\n }\n}\n"],"names":["EventEmitter","once","ee","event","Promise","resolve","EventTarget","Map","on","listener","options","wrapper","detail","set","addEventListener","removeEventListener","off","get","emit","args","dispatchEvent","CustomEvent"],"mappings":"AASA,OAAO,MAAMA;IAOX,OAAOC,KAAKC,EAAgB,EAAEC,KAAa,EAAE;QAC3C,OAAO,IAAIC,QAAQ,CAACC,UAAYH,GAAGD,IAAI,CAACE,OAAOE;IACjD;IAEA,CAAA,MAAO,GAAG,IAAIC,cAAa;IAC3B,CAAA,SAAU,GAAG,IAAIC,MAAyB;IAE1CC,GACEL,KAA4B,EAC5BM,QAAsC,EACtCC,OAAiC,EACjC;QACA,MAAMC,UAAU,CAACR,QAAUM,YAAYN,MAAMS,MAAM;QACnD,IAAI,CAAC,CAAA,SAAU,CAACC,GAAG,CAACJ,UAAUE;QAC9B,IAAI,CAAC,CAAA,MAAO,CAACG,gBAAgB,CAACX,OAAOQ,SAASD;QAC9C,OAAO,IAAM,IAAI,CAAC,CAAA,MAAO,CAACK,mBAAmB,CAACZ,OAAOQ;IACvD;IAEAV,KACEE,KAA4B,EAC5BM,QAAsC,EACtCC,OAAiC,EACjC;QACA,OAAO,IAAI,CAACF,EAAE,CAACL,OAAOM,UAAU;YAAE,GAAGC,OAAO;YAAET,MAAM;QAAK;IAC3D;IAEAe,IAAIb,KAAqC,EAAEM,QAAkB,EAAE;QAC7D,MAAME,UAAU,IAAI,CAAC,CAAA,SAAU,CAACM,GAAG,CAACR;QACpC,IAAIE,SAAS,IAAI,CAAC,CAAA,MAAO,CAACI,mBAAmB,CAACZ,OAAOQ;IACvD;IAEAO,KACEf,KAAQ,EACR,GAAGgB,IAAgD,EACnD;QACA,OAAO,IAAI,CAAC,CAAA,MAAO,CAACC,aAAa,CAAC,IAAIC,YAAYlB,OAAO;YAAES,QAAQO;QAAK;IAC1E;AACF"}
|
package/dist/client/protocol.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { createPromise } from '@nmtjs/common';
|
|
1
|
+
import { createPromise, onceAborted } from '@nmtjs/common';
|
|
2
2
|
import { concat, decodeNumber, encodeNumber } from "../common/binary.js";
|
|
3
|
-
import { ClientMessageType, ServerMessageType } from "../common/enums.js";
|
|
3
|
+
import { ClientMessageType, ErrorCode, ServerMessageType } from "../common/enums.js";
|
|
4
4
|
import { EventEmitter } from "./events.js";
|
|
5
5
|
import { ProtocolClientBlobStream, ProtocolServerBlobStream, ProtocolServerStream } from "./stream.js";
|
|
6
6
|
export class ProtocolError extends Error {
|
|
@@ -104,115 +104,112 @@ export class ProtocolBaseTransformer {
|
|
|
104
104
|
}
|
|
105
105
|
}
|
|
106
106
|
export class ProtocolBaseClient extends EventEmitter {
|
|
107
|
-
transport;
|
|
108
|
-
format;
|
|
109
|
-
transformer;
|
|
110
107
|
#clientStreams;
|
|
111
108
|
#serverStreams;
|
|
112
|
-
#
|
|
113
|
-
#
|
|
114
|
-
#calls;
|
|
115
|
-
#
|
|
116
|
-
#
|
|
117
|
-
|
|
109
|
+
#rpcStreams;
|
|
110
|
+
#rpcStreamData = new Map();
|
|
111
|
+
#calls = new Map();
|
|
112
|
+
#transport;
|
|
113
|
+
#format;
|
|
114
|
+
transformer = new ProtocolBaseTransformer();
|
|
115
|
+
#timeout;
|
|
116
|
+
#callId = 0;
|
|
117
|
+
#streamId = 0;
|
|
118
|
+
constructor(options){
|
|
118
119
|
super();
|
|
119
|
-
this
|
|
120
|
-
this
|
|
121
|
-
this
|
|
122
|
-
this.#serverRPCStreamCalls = new Map();
|
|
123
|
-
this.#calls = new Map();
|
|
124
|
-
this.#callId = 0;
|
|
125
|
-
this.#streamId = 0;
|
|
120
|
+
this.#transport = options.transport;
|
|
121
|
+
this.#format = options.format;
|
|
122
|
+
this.#timeout = options.timeout ?? 60000;
|
|
126
123
|
this.#clientStreams = new ProtocolClientStreams();
|
|
127
124
|
this.#serverStreams = new ProtocolServerStreams();
|
|
128
|
-
this.#
|
|
129
|
-
this
|
|
130
|
-
const [namespace, event, payload] = this
|
|
125
|
+
this.#rpcStreams = new ProtocolServerStreams();
|
|
126
|
+
this.#transport.on(`${ServerMessageType.Event}`, (buffer)=>{
|
|
127
|
+
const [namespace, event, payload] = this.#format.decode(buffer);
|
|
131
128
|
const name = `${namespace}/${event}`;
|
|
132
129
|
const transformed = this.transformer.decodeEvent(namespace, event, payload);
|
|
133
130
|
this.emit(name, transformed);
|
|
134
131
|
});
|
|
135
|
-
this
|
|
132
|
+
this.#transport.on(`${ServerMessageType.RpcResponse}`, (buffer)=>{
|
|
136
133
|
const { call, error, payload } = this.#handleResponse(buffer);
|
|
137
134
|
if (error) call.reject(error);
|
|
138
135
|
else call.resolve(payload);
|
|
139
136
|
});
|
|
140
|
-
this
|
|
137
|
+
this.#transport.on(`${ServerMessageType.RpcStreamResponse}`, (buffer)=>{
|
|
141
138
|
const { call, response, payload, error } = this.#handleResponse(buffer);
|
|
142
139
|
if (error) return call.reject(error);
|
|
143
140
|
console.log('Creating RPC stream', response);
|
|
144
141
|
const stream = new ProtocolServerStream();
|
|
145
|
-
this.#
|
|
146
|
-
this.#
|
|
142
|
+
this.#rpcStreams.add(response.callId, stream);
|
|
143
|
+
this.#rpcStreamData.set(response.callId, {
|
|
147
144
|
namespace: call.namespace,
|
|
148
145
|
procedure: call.procedure
|
|
149
146
|
});
|
|
150
|
-
call.resolve(
|
|
147
|
+
call.resolve({
|
|
151
148
|
payload,
|
|
152
149
|
stream
|
|
153
|
-
|
|
150
|
+
});
|
|
154
151
|
});
|
|
155
|
-
this
|
|
152
|
+
this.#transport.on(`${ServerMessageType.RpcStreamChunk}`, async (buffer)=>{
|
|
156
153
|
const callId = decodeNumber(buffer, 'Uint32');
|
|
157
154
|
console.log('RPC stream chunk', callId);
|
|
158
155
|
const chunk = buffer.slice(Uint32Array.BYTES_PER_ELEMENT);
|
|
159
156
|
if (chunk.byteLength === 0) {
|
|
160
|
-
this.#
|
|
161
|
-
this.#
|
|
157
|
+
this.#rpcStreams.end(callId);
|
|
158
|
+
this.#rpcStreamData.delete(callId);
|
|
162
159
|
} else {
|
|
163
|
-
const call = this.#
|
|
160
|
+
const call = this.#rpcStreamData.get(callId);
|
|
164
161
|
console.log('RPC stream call', call);
|
|
165
162
|
if (call) {
|
|
166
|
-
const payload = this
|
|
163
|
+
const payload = this.#format.decode(chunk);
|
|
167
164
|
console.log('RPC stream payload', payload);
|
|
168
165
|
try {
|
|
169
166
|
const transformed = this.transformer.decodeRPCChunk(call.namespace, call.procedure, payload);
|
|
170
|
-
await this.#
|
|
167
|
+
await this.#rpcStreams.push(callId, transformed);
|
|
171
168
|
} catch (error) {
|
|
172
|
-
this
|
|
173
|
-
this.#
|
|
174
|
-
this.#
|
|
169
|
+
this.#send(ClientMessageType.RpcStreamAbort, encodeNumber(callId, 'Uint32'));
|
|
170
|
+
this.#rpcStreams.remove(callId);
|
|
171
|
+
this.#rpcStreamData.delete(callId);
|
|
175
172
|
}
|
|
176
173
|
}
|
|
177
174
|
}
|
|
178
175
|
});
|
|
179
|
-
this
|
|
176
|
+
this.#transport.on(`${ServerMessageType.RpcStreamAbort}`, (buffer)=>{
|
|
180
177
|
const callId = decodeNumber(buffer, 'Uint32');
|
|
181
178
|
console.log('RPC stream abort', callId);
|
|
182
179
|
const call = this.#calls.get(callId);
|
|
183
180
|
if (call) {
|
|
184
181
|
this.#serverStreams.end(callId);
|
|
185
|
-
this.#
|
|
182
|
+
this.#rpcStreams.abort(callId);
|
|
186
183
|
}
|
|
187
184
|
});
|
|
188
|
-
this
|
|
185
|
+
this.#transport.on(`${ServerMessageType.ServerStreamPush}`, async (buffer)=>{
|
|
189
186
|
const streamId = decodeNumber(buffer, 'Uint32');
|
|
190
187
|
const chunk = buffer.slice(Uint32Array.BYTES_PER_ELEMENT);
|
|
191
188
|
console.log('Server stream push', streamId, chunk.byteLength);
|
|
192
189
|
try {
|
|
193
190
|
await this.#serverStreams.push(streamId, chunk);
|
|
194
|
-
this
|
|
191
|
+
this.#send(ClientMessageType.ServerStreamPull, encodeNumber(streamId, 'Uint32'));
|
|
195
192
|
} catch (error) {
|
|
196
|
-
this
|
|
193
|
+
this.#send(ClientMessageType.ServerStreamAbort, encodeNumber(streamId, 'Uint32'));
|
|
197
194
|
this.#serverStreams.remove(streamId);
|
|
198
195
|
}
|
|
199
196
|
});
|
|
200
|
-
this
|
|
197
|
+
this.#transport.on(`${ServerMessageType.ServerStreamEnd}`, (buffer)=>{
|
|
201
198
|
const streamId = decodeNumber(buffer, 'Uint32');
|
|
202
199
|
console.log('Server stream end', streamId);
|
|
203
200
|
this.#serverStreams.end(streamId);
|
|
204
201
|
});
|
|
205
|
-
this
|
|
202
|
+
this.#transport.on(`${ServerMessageType.ServerStreamAbort}`, (buffer)=>{
|
|
206
203
|
const streamId = decodeNumber(buffer, 'Uint32');
|
|
207
204
|
console.log('Server stream abort', streamId);
|
|
208
205
|
this.#serverStreams.abort(streamId);
|
|
209
206
|
});
|
|
210
|
-
this
|
|
207
|
+
this.#transport.on(`${ServerMessageType.ClientStreamAbort}`, (buffer)=>{
|
|
211
208
|
const streamId = decodeNumber(buffer, 'Uint32');
|
|
212
209
|
console.log('Client stream abort', streamId);
|
|
213
210
|
this.#clientStreams.abort(streamId);
|
|
214
211
|
});
|
|
215
|
-
this
|
|
212
|
+
this.#transport.on(`${ServerMessageType.ClientStreamPull}`, async (buffer)=>{
|
|
216
213
|
const streamId = decodeNumber(buffer, 'Uint32');
|
|
217
214
|
console.log('Client stream pull', streamId);
|
|
218
215
|
const size = decodeNumber(buffer, 'Uint32', Uint32Array.BYTES_PER_ELEMENT);
|
|
@@ -220,34 +217,39 @@ export class ProtocolBaseClient extends EventEmitter {
|
|
|
220
217
|
try {
|
|
221
218
|
const chunk = await this.#clientStreams.pull(streamId, size);
|
|
222
219
|
if (chunk) {
|
|
223
|
-
this
|
|
220
|
+
this.#send(ClientMessageType.ClientStreamPush, concat(streamIdEncoded, chunk));
|
|
224
221
|
} else {
|
|
225
|
-
this
|
|
222
|
+
this.#send(ClientMessageType.ClientStreamEnd, streamIdEncoded);
|
|
226
223
|
this.#clientStreams.end(streamId);
|
|
227
224
|
}
|
|
228
225
|
} catch (error) {
|
|
229
226
|
console.error(error);
|
|
230
|
-
this
|
|
227
|
+
this.#send(ClientMessageType.ClientStreamAbort, streamIdEncoded);
|
|
231
228
|
}
|
|
232
229
|
});
|
|
233
230
|
}
|
|
234
231
|
async connect(auth) {
|
|
235
|
-
return await this
|
|
232
|
+
return await this.#transport.connect(auth, this.#format.contentType);
|
|
236
233
|
}
|
|
237
234
|
async disconnect() {
|
|
238
|
-
return await this
|
|
235
|
+
return await this.#transport.disconnect();
|
|
239
236
|
}
|
|
240
|
-
async
|
|
237
|
+
async #send(messageType, buffer) {
|
|
241
238
|
console.log('Client transport send', ClientMessageType[messageType], buffer.byteLength);
|
|
242
|
-
return await this
|
|
239
|
+
return await this.#transport.send(messageType, buffer);
|
|
243
240
|
}
|
|
244
241
|
async _call(namespace, procedure, payload, options = {}) {
|
|
242
|
+
const timeoutSignal = AbortSignal.timeout(options.timeout || this.#timeout);
|
|
243
|
+
const signal = options.signal ? AbortSignal.any([
|
|
244
|
+
options.signal,
|
|
245
|
+
timeoutSignal
|
|
246
|
+
]) : timeoutSignal;
|
|
245
247
|
const callId = ++this.#callId;
|
|
246
248
|
const call = Object.assign(createPromise(), {
|
|
247
249
|
namespace,
|
|
248
250
|
procedure
|
|
249
251
|
});
|
|
250
|
-
const buffer = this
|
|
252
|
+
const buffer = this.#format.encodeRPC({
|
|
251
253
|
callId,
|
|
252
254
|
namespace,
|
|
253
255
|
procedure,
|
|
@@ -263,17 +265,26 @@ export class ProtocolBaseClient extends EventEmitter {
|
|
|
263
265
|
return stream;
|
|
264
266
|
}
|
|
265
267
|
});
|
|
266
|
-
this
|
|
268
|
+
this.#transport.send(ClientMessageType.Rpc, buffer).catch(console.error);
|
|
267
269
|
this.#calls.set(callId, call);
|
|
268
|
-
|
|
270
|
+
const onAborted = onceAborted(signal).then(()=>{
|
|
271
|
+
if (this.#calls.has(callId)) {
|
|
272
|
+
this.#send(ClientMessageType.RpcAbort, encodeNumber(callId, 'Uint32'));
|
|
273
|
+
}
|
|
274
|
+
throw new ProtocolError(ErrorCode.RequestTimeout, 'Request timeout');
|
|
275
|
+
});
|
|
276
|
+
return Promise.race([
|
|
277
|
+
call.promise,
|
|
278
|
+
onAborted
|
|
279
|
+
]);
|
|
269
280
|
}
|
|
270
281
|
#handleResponse(buffer) {
|
|
271
282
|
const callStreams = [];
|
|
272
|
-
const response = this
|
|
283
|
+
const response = this.#format.decodeRPC(buffer, {
|
|
273
284
|
addStream: (id, metadata)=>{
|
|
274
285
|
console.log('Client transport blob stream', id, metadata);
|
|
275
286
|
const stream = new ProtocolServerBlobStream(id, metadata, ()=>{
|
|
276
|
-
this
|
|
287
|
+
this.#send(ClientMessageType.ServerStreamPull, encodeNumber(id, 'Uint32'));
|
|
277
288
|
});
|
|
278
289
|
callStreams.push(stream);
|
|
279
290
|
this.#serverStreams.add(id, stream);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../lib/client/protocol.ts"],"sourcesContent":["import { type InteractivePromise, createPromise } from '@nmtjs/common'\nimport { concat, decodeNumber, encodeNumber } from '../common/binary.ts'\nimport type { ProtocolBlobMetadata } from '../common/blob.ts'\nimport { ClientMessageType, ServerMessageType } from '../common/enums.ts'\nimport type { ProtocolRPC } from '../common/types.ts'\nimport { EventEmitter } from './events.ts'\nimport type { BaseClientFormat } from './format.ts'\nimport {\n ProtocolClientBlobStream,\n ProtocolServerBlobStream,\n ProtocolServerStream,\n} from './stream.ts'\n\nexport class ProtocolError extends Error {\n code: string\n data?: any\n\n constructor(code: string, message?: string, data?: any) {\n super(message)\n this.code = code\n this.data = data\n }\n\n get message() {\n return `${this.code} ${super.message}`\n }\n\n toString() {\n return `${this.code} ${this.message}`\n }\n\n toJSON() {\n return {\n code: this.code,\n message: this.message,\n data: this.data,\n }\n }\n}\n\nexport class ProtocolClientStreams {\n readonly #collection = new Map<number, ProtocolClientBlobStream>()\n\n get(streamId: number) {\n const stream = this.#collection.get(streamId)\n if (!stream) throw new Error('Stream not found')\n return stream\n }\n\n add(\n source: ReadableStream,\n streamId: number,\n metadata: ProtocolBlobMetadata,\n ) {\n const stream = new ProtocolClientBlobStream(source, streamId, metadata)\n this.#collection.set(streamId, stream)\n return stream\n }\n\n remove(streamId: number) {\n this.#collection.delete(streamId)\n }\n\n abort(streamId: number) {\n const stream = this.get(streamId)\n stream.abort()\n this.remove(streamId)\n }\n\n pull(streamId: number, size: number) {\n const stream = this.get(streamId)\n return stream.read(size)\n }\n\n end(streamId: number) {\n const stream = this.get(streamId)\n stream.end()\n this.remove(streamId)\n }\n}\n\nexport class ProtocolServerStreams {\n readonly #collection = new Map<number, ProtocolServerStream>()\n\n has(streamId: number) {\n return this.#collection.has(streamId)\n }\n\n get(streamId: number) {\n const stream = this.#collection.get(streamId)\n if (!stream) throw new Error('Stream not found')\n return stream\n }\n\n add(streamId: number, stream: ProtocolServerStream) {\n this.#collection.set(streamId, stream)\n return stream\n }\n\n remove(streamId: number) {\n this.#collection.delete(streamId)\n }\n\n abort(streamId: number) {\n if (this.has(streamId)) {\n const stream = this.get(streamId)\n stream.abort()\n this.remove(streamId)\n }\n }\n\n async push(streamId: number, chunk: ArrayBuffer) {\n const stream = this.get(streamId)\n return await stream.push(chunk)\n }\n\n end(streamId: number) {\n const stream = this.get(streamId)\n stream.end()\n this.remove(streamId)\n }\n}\n\nexport interface ProtocolTransport\n extends EventEmitter<{\n [K in `${ServerMessageType}`]: [ArrayBuffer]\n }> {\n connect(\n auth: any,\n contentType: BaseClientFormat['contentType'],\n ): Promise<void>\n disconnect(): Promise<void>\n send(messageType: ClientMessageType, buffer: ArrayBuffer): Promise<void>\n}\n\nexport class ProtocolBaseTransformer {\n encodeRPC(namespace: string, procedure: string, payload: any) {\n return payload\n }\n decodeRPC(namespace: string, procedure: string, payload: any) {\n return payload\n }\n decodeRPCChunk(namespace: string, procedure: string, payload: any) {\n return payload\n }\n decodeEvent(namespace: string, event: string, payload: any) {\n return payload\n }\n}\n\nexport type ProtocolClientCall = InteractivePromise<any> &\n Pick<ProtocolRPC, 'namespace' | 'procedure'>\n\nexport abstract class ProtocolBaseClient<\n T extends Record<string, Record<string, any>>,\n> extends EventEmitter<\n {\n [N in keyof T]: {\n [E in keyof T[N] as `${Extract<N, string>}/${Extract<E, string>}`]: [\n payload: T[N][E],\n ]\n }\n }[keyof T]\n> {\n readonly #clientStreams: ProtocolClientStreams\n readonly #serverStreams: ProtocolServerStreams\n readonly #serverRPCStreams: ProtocolServerStreams\n readonly #serverRPCStreamCalls = new Map<\n number,\n Pick<ProtocolRPC, 'namespace' | 'procedure'>\n >()\n readonly #calls = new Map<number, ProtocolClientCall>()\n\n #callId = 0\n #streamId = 0\n\n constructor(\n protected readonly transport: ProtocolTransport,\n protected readonly format: BaseClientFormat,\n protected readonly transformer: ProtocolBaseTransformer = new ProtocolBaseTransformer(),\n ) {\n super()\n\n this.#clientStreams = new ProtocolClientStreams()\n this.#serverStreams = new ProtocolServerStreams()\n this.#serverRPCStreams = new ProtocolServerStreams()\n\n this.transport.on(`${ServerMessageType.Event}`, (buffer) => {\n const [namespace, event, payload] = this.format.decode(buffer)\n const name = `${namespace}/${event}`\n const transformed = this.transformer.decodeEvent(\n namespace,\n event,\n payload,\n )\n this.emit(name, transformed)\n })\n\n this.transport.on(`${ServerMessageType.RpcResponse}`, (buffer) => {\n const { call, error, payload } = this.#handleResponse(buffer)\n if (error) call.reject(error)\n else call.resolve(payload)\n })\n\n this.transport.on(`${ServerMessageType.RpcStreamResponse}`, (buffer) => {\n const { call, response, payload, error } = this.#handleResponse(buffer)\n if (error) return call.reject(error)\n console.log('Creating RPC stream', response)\n const stream = new ProtocolServerStream()\n this.#serverRPCStreams.add(response.callId, stream)\n this.#serverRPCStreamCalls.set(response.callId, {\n namespace: call.namespace,\n procedure: call.procedure,\n })\n call.resolve([payload, stream])\n })\n\n this.transport.on(`${ServerMessageType.RpcStreamChunk}`, async (buffer) => {\n const callId = decodeNumber(buffer, 'Uint32')\n console.log('RPC stream chunk', callId)\n\n const chunk = buffer.slice(Uint32Array.BYTES_PER_ELEMENT)\n if (chunk.byteLength === 0) {\n this.#serverRPCStreams.end(callId)\n this.#serverRPCStreamCalls.delete(callId)\n } else {\n const call = this.#serverRPCStreamCalls.get(callId)\n console.log('RPC stream call', call)\n if (call) {\n const payload = this.format.decode(chunk)\n console.log('RPC stream payload', payload)\n try {\n const transformed = this.transformer.decodeRPCChunk(\n call.namespace,\n call.procedure,\n payload,\n )\n await this.#serverRPCStreams.push(callId, transformed)\n } catch (error) {\n this._send(\n ClientMessageType.RpcStreamAbort,\n encodeNumber(callId, 'Uint32'),\n )\n this.#serverRPCStreams.remove(callId)\n this.#serverRPCStreamCalls.delete(callId)\n }\n }\n }\n })\n\n this.transport.on(`${ServerMessageType.RpcStreamAbort}`, (buffer) => {\n const callId = decodeNumber(buffer, 'Uint32')\n console.log('RPC stream abort', callId)\n const call = this.#calls.get(callId)\n if (call) {\n this.#serverStreams.end(callId)\n this.#serverRPCStreams.abort(callId)\n }\n })\n\n this.transport.on(\n `${ServerMessageType.ServerStreamPush}`,\n async (buffer) => {\n const streamId = decodeNumber(buffer, 'Uint32')\n const chunk = buffer.slice(Uint32Array.BYTES_PER_ELEMENT)\n console.log('Server stream push', streamId, chunk.byteLength)\n try {\n await this.#serverStreams.push(streamId, chunk)\n this._send(\n ClientMessageType.ServerStreamPull,\n encodeNumber(streamId, 'Uint32'),\n )\n } catch (error) {\n this._send(\n ClientMessageType.ServerStreamAbort,\n encodeNumber(streamId, 'Uint32'),\n )\n this.#serverStreams.remove(streamId)\n }\n },\n )\n\n this.transport.on(`${ServerMessageType.ServerStreamEnd}`, (buffer) => {\n const streamId = decodeNumber(buffer, 'Uint32')\n console.log('Server stream end', streamId)\n this.#serverStreams.end(streamId)\n })\n\n this.transport.on(`${ServerMessageType.ServerStreamAbort}`, (buffer) => {\n const streamId = decodeNumber(buffer, 'Uint32')\n console.log('Server stream abort', streamId)\n this.#serverStreams.abort(streamId)\n })\n\n this.transport.on(`${ServerMessageType.ClientStreamAbort}`, (buffer) => {\n const streamId = decodeNumber(buffer, 'Uint32')\n console.log('Client stream abort', streamId)\n this.#clientStreams.abort(streamId)\n })\n\n this.transport.on(\n `${ServerMessageType.ClientStreamPull}`,\n async (buffer) => {\n const streamId = decodeNumber(buffer, 'Uint32')\n console.log('Client stream pull', streamId)\n const size = decodeNumber(\n buffer,\n 'Uint32',\n Uint32Array.BYTES_PER_ELEMENT,\n )\n const streamIdEncoded = encodeNumber(streamId, 'Uint32')\n try {\n const chunk = await this.#clientStreams.pull(streamId, size)\n if (chunk) {\n this._send(\n ClientMessageType.ClientStreamPush,\n concat(streamIdEncoded, chunk),\n )\n } else {\n this._send(ClientMessageType.ClientStreamEnd, streamIdEncoded)\n this.#clientStreams.end(streamId)\n }\n } catch (error) {\n console.error(error)\n this._send(ClientMessageType.ClientStreamAbort, streamIdEncoded)\n }\n },\n )\n }\n\n async connect(auth: any) {\n return await this.transport.connect(auth, this.format.contentType)\n }\n\n async disconnect() {\n return await this.transport.disconnect()\n }\n\n protected async _send(messageType: ClientMessageType, buffer: ArrayBuffer) {\n console.log(\n 'Client transport send',\n ClientMessageType[messageType],\n buffer.byteLength,\n )\n return await this.transport.send(messageType, buffer)\n }\n\n protected async _call(\n namespace: string,\n procedure: string,\n payload: any,\n options = {},\n ) {\n const callId = ++this.#callId\n const call = Object.assign(createPromise(), {\n namespace,\n procedure,\n })\n const buffer = this.format.encodeRPC(\n {\n callId,\n namespace,\n procedure,\n payload: this.transformer.encodeRPC(namespace, procedure, payload),\n },\n {\n addStream: (blob) => {\n const streamId = ++this.#streamId\n const stream = this.#clientStreams.add(\n blob.source,\n streamId,\n blob.metadata,\n )\n return stream\n },\n getStream: (id) => {\n const stream = this.#clientStreams.get(id)\n return stream\n },\n },\n )\n\n this.transport.send(ClientMessageType.Rpc, buffer).catch(console.error)\n\n this.#calls.set(callId, call)\n\n return call.promise\n }\n\n #handleResponse(buffer: ArrayBuffer) {\n const callStreams: ProtocolServerBlobStream[] = []\n const response = this.format.decodeRPC(buffer, {\n addStream: (id, metadata) => {\n console.log('Client transport blob stream', id, metadata)\n const stream = new ProtocolServerBlobStream(id, metadata, () => {\n this._send(\n ClientMessageType.ServerStreamPull,\n encodeNumber(id, 'Uint32'),\n )\n })\n callStreams.push(stream)\n this.#serverStreams.add(id, stream)\n return stream\n },\n getStream: (id) => {\n return this.#serverStreams.get(id)\n },\n })\n\n console.log('Client transport response', response)\n\n const call = this.#calls.get(response.callId)\n\n if (call) {\n this.#calls.delete(response.callId)\n\n if (response.error) {\n const error = new ProtocolError(\n response.error.code,\n response.error.message,\n response.error.data,\n )\n return { call, response, error }\n } else {\n const payload = this.transformer.decodeRPC(\n call.namespace,\n call.procedure,\n response.payload,\n )\n return { call, response, payload }\n }\n }\n\n for (const stream of callStreams) {\n this.#serverStreams.abort(stream.id)\n }\n\n throw new Error('Call not found')\n }\n}\n"],"names":["createPromise","concat","decodeNumber","encodeNumber","ClientMessageType","ServerMessageType","EventEmitter","ProtocolClientBlobStream","ProtocolServerBlobStream","ProtocolServerStream","ProtocolError","Error","code","data","constructor","message","toString","toJSON","ProtocolClientStreams","Map","get","streamId","stream","add","source","metadata","set","remove","delete","abort","pull","size","read","end","ProtocolServerStreams","has","push","chunk","ProtocolBaseTransformer","encodeRPC","namespace","procedure","payload","decodeRPC","decodeRPCChunk","decodeEvent","event","ProtocolBaseClient","transport","format","transformer","on","Event","buffer","decode","name","transformed","emit","RpcResponse","call","error","reject","resolve","RpcStreamResponse","response","console","log","callId","RpcStreamChunk","slice","Uint32Array","BYTES_PER_ELEMENT","byteLength","_send","RpcStreamAbort","ServerStreamPush","ServerStreamPull","ServerStreamAbort","ServerStreamEnd","ClientStreamAbort","ClientStreamPull","streamIdEncoded","ClientStreamPush","ClientStreamEnd","connect","auth","contentType","disconnect","messageType","send","_call","options","Object","assign","addStream","blob","getStream","id","Rpc","catch","promise","callStreams"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../lib/client/protocol.ts"],"sourcesContent":["import {\n type InteractivePromise,\n createPromise,\n onceAborted,\n} from '@nmtjs/common'\nimport { concat, decodeNumber, encodeNumber } from '../common/binary.ts'\nimport type { ProtocolBlobMetadata } from '../common/blob.ts'\nimport {\n ClientMessageType,\n ErrorCode,\n ServerMessageType,\n} from '../common/enums.ts'\nimport type { ProtocolRPC } from '../common/types.ts'\nimport { EventEmitter } from './events.ts'\nimport type { BaseClientFormat } from './format.ts'\nimport {\n ProtocolClientBlobStream,\n ProtocolServerBlobStream,\n ProtocolServerStream,\n} from './stream.ts'\n\nexport class ProtocolError extends Error {\n code: string\n data?: any\n\n constructor(code: string, message?: string, data?: any) {\n super(message)\n this.code = code\n this.data = data\n }\n\n get message() {\n return `${this.code} ${super.message}`\n }\n\n toString() {\n return `${this.code} ${this.message}`\n }\n\n toJSON() {\n return {\n code: this.code,\n message: this.message,\n data: this.data,\n }\n }\n}\n\nexport class ProtocolClientStreams {\n readonly #collection = new Map<number, ProtocolClientBlobStream>()\n\n get(streamId: number) {\n const stream = this.#collection.get(streamId)\n if (!stream) throw new Error('Stream not found')\n return stream\n }\n\n add(\n source: ReadableStream,\n streamId: number,\n metadata: ProtocolBlobMetadata,\n ) {\n const stream = new ProtocolClientBlobStream(source, streamId, metadata)\n this.#collection.set(streamId, stream)\n return stream\n }\n\n remove(streamId: number) {\n this.#collection.delete(streamId)\n }\n\n abort(streamId: number) {\n const stream = this.get(streamId)\n stream.abort()\n this.remove(streamId)\n }\n\n pull(streamId: number, size: number) {\n const stream = this.get(streamId)\n return stream.read(size)\n }\n\n end(streamId: number) {\n const stream = this.get(streamId)\n stream.end()\n this.remove(streamId)\n }\n}\n\nexport class ProtocolServerStreams {\n readonly #collection = new Map<number, ProtocolServerStream>()\n\n has(streamId: number) {\n return this.#collection.has(streamId)\n }\n\n get(streamId: number) {\n const stream = this.#collection.get(streamId)\n if (!stream) throw new Error('Stream not found')\n return stream\n }\n\n add(streamId: number, stream: ProtocolServerStream) {\n this.#collection.set(streamId, stream)\n return stream\n }\n\n remove(streamId: number) {\n this.#collection.delete(streamId)\n }\n\n abort(streamId: number) {\n if (this.has(streamId)) {\n const stream = this.get(streamId)\n stream.abort()\n this.remove(streamId)\n }\n }\n\n async push(streamId: number, chunk: ArrayBuffer) {\n const stream = this.get(streamId)\n return await stream.push(chunk)\n }\n\n end(streamId: number) {\n const stream = this.get(streamId)\n stream.end()\n this.remove(streamId)\n }\n}\n\nexport interface ProtocolTransport\n extends EventEmitter<{\n [K in `${ServerMessageType}`]: [ArrayBuffer]\n }> {\n connect(\n auth: any,\n contentType: BaseClientFormat['contentType'],\n ): Promise<void>\n disconnect(): Promise<void>\n send(messageType: ClientMessageType, buffer: ArrayBuffer): Promise<void>\n}\n\nexport class ProtocolBaseTransformer {\n encodeRPC(namespace: string, procedure: string, payload: any) {\n return payload\n }\n decodeRPC(namespace: string, procedure: string, payload: any) {\n return payload\n }\n decodeRPCChunk(namespace: string, procedure: string, payload: any) {\n return payload\n }\n decodeEvent(namespace: string, event: string, payload: any) {\n return payload\n }\n}\n\nexport type ProtocolClientCall = InteractivePromise<any> &\n Pick<ProtocolRPC, 'namespace' | 'procedure'>\n\nexport type ProtocolBaseClientOptions = {\n transport: ProtocolTransport\n format: BaseClientFormat\n transformer?: ProtocolBaseTransformer\n timeout?: number\n}\n\nexport type ProtocolBaseClientCallOptions = {\n signal?: AbortSignal\n timeout?: number\n}\n\nexport abstract class ProtocolBaseClient<\n T extends Record<string, Record<string, any>>,\n> extends EventEmitter<\n {\n [N in keyof T]: {\n [E in keyof T[N] as `${Extract<N, string>}/${Extract<E, string>}`]: [\n payload: T[N][E],\n ]\n }\n }[keyof T]\n> {\n readonly #clientStreams: ProtocolClientStreams\n readonly #serverStreams: ProtocolServerStreams\n readonly #rpcStreams: ProtocolServerStreams\n readonly #rpcStreamData = new Map<\n number,\n Pick<ProtocolRPC, 'namespace' | 'procedure'>\n >()\n readonly #calls = new Map<number, ProtocolClientCall>()\n\n readonly #transport: ProtocolTransport\n readonly #format: BaseClientFormat\n readonly transformer: ProtocolBaseTransformer = new ProtocolBaseTransformer()\n readonly #timeout: number\n\n #callId = 0\n #streamId = 0\n\n constructor(options: ProtocolBaseClientOptions) {\n super()\n\n this.#transport = options.transport\n this.#format = options.format\n this.#timeout = options.timeout ?? 60000\n\n this.#clientStreams = new ProtocolClientStreams()\n this.#serverStreams = new ProtocolServerStreams()\n this.#rpcStreams = new ProtocolServerStreams()\n\n this.#transport.on(`${ServerMessageType.Event}`, (buffer) => {\n const [namespace, event, payload] = this.#format.decode(buffer)\n const name = `${namespace}/${event}`\n const transformed = this.transformer.decodeEvent(\n namespace,\n event,\n payload,\n )\n this.emit(name, transformed)\n })\n\n this.#transport.on(`${ServerMessageType.RpcResponse}`, (buffer) => {\n const { call, error, payload } = this.#handleResponse(buffer)\n if (error) call.reject(error)\n else call.resolve(payload)\n })\n\n this.#transport.on(`${ServerMessageType.RpcStreamResponse}`, (buffer) => {\n const { call, response, payload, error } = this.#handleResponse(buffer)\n if (error) return call.reject(error)\n console.log('Creating RPC stream', response)\n const stream = new ProtocolServerStream()\n this.#rpcStreams.add(response.callId, stream)\n this.#rpcStreamData.set(response.callId, {\n namespace: call.namespace,\n procedure: call.procedure,\n })\n call.resolve({ payload, stream })\n })\n\n this.#transport.on(\n `${ServerMessageType.RpcStreamChunk}`,\n async (buffer) => {\n const callId = decodeNumber(buffer, 'Uint32')\n console.log('RPC stream chunk', callId)\n\n const chunk = buffer.slice(Uint32Array.BYTES_PER_ELEMENT)\n if (chunk.byteLength === 0) {\n this.#rpcStreams.end(callId)\n this.#rpcStreamData.delete(callId)\n } else {\n const call = this.#rpcStreamData.get(callId)\n console.log('RPC stream call', call)\n if (call) {\n const payload = this.#format.decode(chunk)\n console.log('RPC stream payload', payload)\n try {\n const transformed = this.transformer.decodeRPCChunk(\n call.namespace,\n call.procedure,\n payload,\n )\n await this.#rpcStreams.push(callId, transformed)\n } catch (error) {\n this.#send(\n ClientMessageType.RpcStreamAbort,\n encodeNumber(callId, 'Uint32'),\n )\n this.#rpcStreams.remove(callId)\n this.#rpcStreamData.delete(callId)\n }\n }\n }\n },\n )\n\n this.#transport.on(`${ServerMessageType.RpcStreamAbort}`, (buffer) => {\n const callId = decodeNumber(buffer, 'Uint32')\n console.log('RPC stream abort', callId)\n const call = this.#calls.get(callId)\n if (call) {\n this.#serverStreams.end(callId)\n this.#rpcStreams.abort(callId)\n }\n })\n\n this.#transport.on(\n `${ServerMessageType.ServerStreamPush}`,\n async (buffer) => {\n const streamId = decodeNumber(buffer, 'Uint32')\n const chunk = buffer.slice(Uint32Array.BYTES_PER_ELEMENT)\n console.log('Server stream push', streamId, chunk.byteLength)\n try {\n await this.#serverStreams.push(streamId, chunk)\n this.#send(\n ClientMessageType.ServerStreamPull,\n encodeNumber(streamId, 'Uint32'),\n )\n } catch (error) {\n this.#send(\n ClientMessageType.ServerStreamAbort,\n encodeNumber(streamId, 'Uint32'),\n )\n this.#serverStreams.remove(streamId)\n }\n },\n )\n\n this.#transport.on(`${ServerMessageType.ServerStreamEnd}`, (buffer) => {\n const streamId = decodeNumber(buffer, 'Uint32')\n console.log('Server stream end', streamId)\n this.#serverStreams.end(streamId)\n })\n\n this.#transport.on(`${ServerMessageType.ServerStreamAbort}`, (buffer) => {\n const streamId = decodeNumber(buffer, 'Uint32')\n console.log('Server stream abort', streamId)\n this.#serverStreams.abort(streamId)\n })\n\n this.#transport.on(`${ServerMessageType.ClientStreamAbort}`, (buffer) => {\n const streamId = decodeNumber(buffer, 'Uint32')\n console.log('Client stream abort', streamId)\n this.#clientStreams.abort(streamId)\n })\n\n this.#transport.on(\n `${ServerMessageType.ClientStreamPull}`,\n async (buffer) => {\n const streamId = decodeNumber(buffer, 'Uint32')\n console.log('Client stream pull', streamId)\n const size = decodeNumber(\n buffer,\n 'Uint32',\n Uint32Array.BYTES_PER_ELEMENT,\n )\n const streamIdEncoded = encodeNumber(streamId, 'Uint32')\n try {\n const chunk = await this.#clientStreams.pull(streamId, size)\n if (chunk) {\n this.#send(\n ClientMessageType.ClientStreamPush,\n concat(streamIdEncoded, chunk),\n )\n } else {\n this.#send(ClientMessageType.ClientStreamEnd, streamIdEncoded)\n this.#clientStreams.end(streamId)\n }\n } catch (error) {\n console.error(error)\n this.#send(ClientMessageType.ClientStreamAbort, streamIdEncoded)\n }\n },\n )\n }\n\n async connect(auth: any) {\n return await this.#transport.connect(auth, this.#format.contentType)\n }\n\n async disconnect() {\n return await this.#transport.disconnect()\n }\n\n async #send(messageType: ClientMessageType, buffer: ArrayBuffer) {\n console.log(\n 'Client transport send',\n ClientMessageType[messageType],\n buffer.byteLength,\n )\n return await this.#transport.send(messageType, buffer)\n }\n\n protected async _call(\n namespace: string,\n procedure: string,\n payload: any,\n options: ProtocolBaseClientCallOptions = {},\n ) {\n const timeoutSignal = AbortSignal.timeout(options.timeout || this.#timeout)\n const signal = options.signal\n ? AbortSignal.any([options.signal, timeoutSignal])\n : timeoutSignal\n\n const callId = ++this.#callId\n const call = Object.assign(createPromise(), {\n namespace,\n procedure,\n })\n const buffer = this.#format.encodeRPC(\n {\n callId,\n namespace,\n procedure,\n payload: this.transformer.encodeRPC(namespace, procedure, payload),\n },\n {\n addStream: (blob) => {\n const streamId = ++this.#streamId\n const stream = this.#clientStreams.add(\n blob.source,\n streamId,\n blob.metadata,\n )\n return stream\n },\n getStream: (id) => {\n const stream = this.#clientStreams.get(id)\n return stream\n },\n },\n )\n\n this.#transport.send(ClientMessageType.Rpc, buffer).catch(console.error)\n\n this.#calls.set(callId, call)\n\n const onAborted = onceAborted(signal).then(() => {\n if (this.#calls.has(callId)) {\n this.#send(ClientMessageType.RpcAbort, encodeNumber(callId, 'Uint32'))\n }\n throw new ProtocolError(ErrorCode.RequestTimeout, 'Request timeout')\n })\n\n return Promise.race([call.promise, onAborted])\n }\n\n #handleResponse(buffer: ArrayBuffer) {\n const callStreams: ProtocolServerBlobStream[] = []\n const response = this.#format.decodeRPC(buffer, {\n addStream: (id, metadata) => {\n console.log('Client transport blob stream', id, metadata)\n const stream = new ProtocolServerBlobStream(id, metadata, () => {\n this.#send(\n ClientMessageType.ServerStreamPull,\n encodeNumber(id, 'Uint32'),\n )\n })\n callStreams.push(stream)\n this.#serverStreams.add(id, stream)\n return stream\n },\n getStream: (id) => {\n return this.#serverStreams.get(id)\n },\n })\n\n console.log('Client transport response', response)\n\n const call = this.#calls.get(response.callId)\n\n if (call) {\n this.#calls.delete(response.callId)\n\n if (response.error) {\n const error = new ProtocolError(\n response.error.code,\n response.error.message,\n response.error.data,\n )\n return { call, response, error }\n } else {\n const payload = this.transformer.decodeRPC(\n call.namespace,\n call.procedure,\n response.payload,\n )\n return { call, response, payload }\n }\n }\n\n for (const stream of callStreams) {\n this.#serverStreams.abort(stream.id)\n }\n\n throw new Error('Call not found')\n }\n}\n"],"names":["createPromise","onceAborted","concat","decodeNumber","encodeNumber","ClientMessageType","ErrorCode","ServerMessageType","EventEmitter","ProtocolClientBlobStream","ProtocolServerBlobStream","ProtocolServerStream","ProtocolError","Error","code","data","constructor","message","toString","toJSON","ProtocolClientStreams","Map","get","streamId","stream","add","source","metadata","set","remove","delete","abort","pull","size","read","end","ProtocolServerStreams","has","push","chunk","ProtocolBaseTransformer","encodeRPC","namespace","procedure","payload","decodeRPC","decodeRPCChunk","decodeEvent","event","ProtocolBaseClient","transformer","options","transport","format","timeout","on","Event","buffer","decode","name","transformed","emit","RpcResponse","call","error","reject","resolve","RpcStreamResponse","response","console","log","callId","RpcStreamChunk","slice","Uint32Array","BYTES_PER_ELEMENT","byteLength","RpcStreamAbort","ServerStreamPush","ServerStreamPull","ServerStreamAbort","ServerStreamEnd","ClientStreamAbort","ClientStreamPull","streamIdEncoded","ClientStreamPush","ClientStreamEnd","connect","auth","contentType","disconnect","messageType","send","_call","timeoutSignal","AbortSignal","signal","any","Object","assign","addStream","blob","getStream","id","Rpc","catch","onAborted","then","RpcAbort","RequestTimeout","Promise","race","promise","callStreams"],"mappings":"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"}
|
package/dist/client/stream.js
CHANGED
|
@@ -51,9 +51,8 @@ export class ProtocolClientBlobStream extends TransformStream {
|
|
|
51
51
|
this.#reader.cancel(error);
|
|
52
52
|
}
|
|
53
53
|
async end() {
|
|
54
|
-
if (!this.writable.locked
|
|
55
|
-
|
|
56
|
-
}
|
|
54
|
+
if (!this.writable.locked) await this.writable.close();
|
|
55
|
+
else await this.writable.abort(new Error('Stream closed'));
|
|
57
56
|
}
|
|
58
57
|
}
|
|
59
58
|
export class ProtocolServerStream extends TransformStream {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../lib/client/stream.ts"],"sourcesContent":["import { type Callback, defer } from '@nmtjs/common'\nimport { encodeText } from '../common/binary.ts'\nimport type { ProtocolBlobMetadata } from '../common/blob.ts'\n\nexport class ProtocolClientBlobStream extends TransformStream<\n any,\n ArrayBuffer\n> {\n #queue: ArrayBuffer\n #reader: ReadableStreamDefaultReader\n\n constructor(\n readonly source: ReadableStream,\n readonly id: number,\n readonly metadata: ProtocolBlobMetadata,\n ) {\n super({\n start: () => {\n defer(() => source.pipeThrough(this))\n },\n transform: (chunk, controller) => {\n if (chunk instanceof ArrayBuffer) {\n controller.enqueue(chunk)\n } else if (chunk instanceof Uint8Array) {\n controller.enqueue(chunk.buffer)\n } else if (typeof chunk === 'string') {\n controller.enqueue(encodeText(chunk))\n } else {\n throw new Error(\n 'Invalid chunk data type. Expected ArrayBuffer, Uint8Array, or string.',\n )\n }\n },\n })\n\n this.#queue = new ArrayBuffer(0)\n this.#reader = this.readable.getReader()\n }\n\n async read(size: number) {\n if (this.#queue.byteLength >= size) {\n const chunk = this.#queue.slice(0, size)\n const remaining = this.#queue.slice(size)\n this.#queue = remaining\n return chunk\n } else {\n const { done, value } = await this.#reader.read()\n if (!done) {\n const buffer = value as ArrayBuffer\n const chunk = buffer.slice(0, size)\n const remaining = buffer.slice(size)\n this.#queue = remaining\n return chunk\n }\n return null\n }\n }\n\n abort(error = new Error('Stream aborted')) {\n this.#reader.cancel(error)\n }\n\n async end() {\n if (!this.writable.locked
|
|
1
|
+
{"version":3,"sources":["../../../lib/client/stream.ts"],"sourcesContent":["import { type Callback, defer } from '@nmtjs/common'\nimport { encodeText } from '../common/binary.ts'\nimport type { ProtocolBlobMetadata } from '../common/blob.ts'\n\nexport class ProtocolClientBlobStream extends TransformStream<\n any,\n ArrayBuffer\n> {\n #queue: ArrayBuffer\n #reader: ReadableStreamDefaultReader\n\n constructor(\n readonly source: ReadableStream,\n readonly id: number,\n readonly metadata: ProtocolBlobMetadata,\n ) {\n super({\n start: () => {\n defer(() => source.pipeThrough(this))\n },\n transform: (chunk, controller) => {\n if (chunk instanceof ArrayBuffer) {\n controller.enqueue(chunk)\n } else if (chunk instanceof Uint8Array) {\n controller.enqueue(chunk.buffer as unknown as ArrayBuffer)\n } else if (typeof chunk === 'string') {\n controller.enqueue(encodeText(chunk))\n } else {\n throw new Error(\n 'Invalid chunk data type. Expected ArrayBuffer, Uint8Array, or string.',\n )\n }\n },\n })\n\n this.#queue = new ArrayBuffer(0)\n this.#reader = this.readable.getReader()\n }\n\n async read(size: number) {\n if (this.#queue.byteLength >= size) {\n const chunk = this.#queue.slice(0, size)\n const remaining = this.#queue.slice(size)\n this.#queue = remaining\n return chunk\n } else {\n const { done, value } = await this.#reader.read()\n if (!done) {\n const buffer = value as ArrayBuffer\n const chunk = buffer.slice(0, size)\n const remaining = buffer.slice(size)\n this.#queue = remaining\n return chunk\n }\n return null\n }\n }\n\n abort(error = new Error('Stream aborted')) {\n this.#reader.cancel(error)\n }\n\n async end() {\n if (!this.writable.locked) await this.writable.close()\n else await this.writable.abort(new Error('Stream closed'))\n }\n}\n\nexport interface ProtocolServerStreamInterface<T = any> {\n [Symbol.asyncIterator](): AsyncGenerator<T>\n abort(error?: Error): void\n}\n\nexport class ProtocolServerStream<T = any>\n extends TransformStream<any, T>\n implements ProtocolServerStreamInterface<T>\n{\n #writer: WritableStreamDefaultWriter\n\n constructor(start?: Callback) {\n super({ start })\n this.#writer = this.writable.getWriter()\n }\n\n async *[Symbol.asyncIterator]() {\n const reader = this.readable.getReader()\n while (true) {\n const { done, value } = await reader.read()\n if (!done) yield value\n else return void 0\n }\n }\n\n async push(chunk: any) {\n await this.#writer.write(chunk)\n }\n\n async end() {\n await this.#writer.close()\n }\n\n abort(error = new Error('Stream aborted')) {\n this.#writer.abort(error)\n }\n}\n\nexport class ProtocolServerBlobStream extends ProtocolServerStream<ArrayBuffer> {\n constructor(\n readonly id: number,\n readonly metadata: ProtocolBlobMetadata,\n start: Callback,\n ) {\n super(start)\n }\n\n push(chunk: ArrayBuffer) {\n return super.push(chunk)\n }\n\n end() {\n return super.end()\n }\n}\n"],"names":["defer","encodeText","ProtocolClientBlobStream","TransformStream","constructor","source","id","metadata","start","pipeThrough","transform","chunk","controller","ArrayBuffer","enqueue","Uint8Array","buffer","Error","readable","getReader","read","size","byteLength","slice","remaining","done","value","abort","error","cancel","end","writable","locked","close","ProtocolServerStream","getWriter","Symbol","asyncIterator","reader","push","write","ProtocolServerBlobStream"],"mappings":"AAAA,SAAwBA,KAAK,QAAQ,gBAAe;AACpD,SAASC,UAAU,QAAQ,sBAAqB;AAGhD,OAAO,MAAMC,iCAAiCC;;;;IAI5C,CAAA,KAAM,CAAa;IACnB,CAAA,MAAO,CAA6B;IAEpCC,YACE,AAASC,MAAsB,EAC/B,AAASC,EAAU,EACnB,AAASC,QAA8B,CACvC;QACA,KAAK,CAAC;YACJC,OAAO;gBACLR,MAAM,IAAMK,OAAOI,WAAW,CAAC,IAAI;YACrC;YACAC,WAAW,CAACC,OAAOC;gBACjB,IAAID,iBAAiBE,aAAa;oBAChCD,WAAWE,OAAO,CAACH;gBACrB,OAAO,IAAIA,iBAAiBI,YAAY;oBACtCH,WAAWE,OAAO,CAACH,MAAMK,MAAM;gBACjC,OAAO,IAAI,OAAOL,UAAU,UAAU;oBACpCC,WAAWE,OAAO,CAACb,WAAWU;gBAChC,OAAO;oBACL,MAAM,IAAIM,MACR;gBAEJ;YACF;QACF;aArBSZ,SAAAA;aACAC,KAAAA;aACAC,WAAAA;QAqBT,IAAI,CAAC,CAAA,KAAM,GAAG,IAAIM,YAAY;QAC9B,IAAI,CAAC,CAAA,MAAO,GAAG,IAAI,CAACK,QAAQ,CAACC,SAAS;IACxC;IAEA,MAAMC,KAAKC,IAAY,EAAE;QACvB,IAAI,IAAI,CAAC,CAAA,KAAM,CAACC,UAAU,IAAID,MAAM;YAClC,MAAMV,QAAQ,IAAI,CAAC,CAAA,KAAM,CAACY,KAAK,CAAC,GAAGF;YACnC,MAAMG,YAAY,IAAI,CAAC,CAAA,KAAM,CAACD,KAAK,CAACF;YACpC,IAAI,CAAC,CAAA,KAAM,GAAGG;YACd,OAAOb;QACT,OAAO;YACL,MAAM,EAAEc,IAAI,EAAEC,KAAK,EAAE,GAAG,MAAM,IAAI,CAAC,CAAA,MAAO,CAACN,IAAI;YAC/C,IAAI,CAACK,MAAM;gBACT,MAAMT,SAASU;gBACf,MAAMf,QAAQK,OAAOO,KAAK,CAAC,GAAGF;gBAC9B,MAAMG,YAAYR,OAAOO,KAAK,CAACF;gBAC/B,IAAI,CAAC,CAAA,KAAM,GAAGG;gBACd,OAAOb;YACT;YACA,OAAO;QACT;IACF;IAEAgB,MAAMC,QAAQ,IAAIX,MAAM,iBAAiB,EAAE;QACzC,IAAI,CAAC,CAAA,MAAO,CAACY,MAAM,CAACD;IACtB;IAEA,MAAME,MAAM;QACV,IAAI,CAAC,IAAI,CAACC,QAAQ,CAACC,MAAM,EAAE,MAAM,IAAI,CAACD,QAAQ,CAACE,KAAK;aAC/C,MAAM,IAAI,CAACF,QAAQ,CAACJ,KAAK,CAAC,IAAIV,MAAM;IAC3C;AACF;AAOA,OAAO,MAAMiB,6BACH/B;IAGR,CAAA,MAAO,CAA6B;IAEpCC,YAAYI,KAAgB,CAAE;QAC5B,KAAK,CAAC;YAAEA;QAAM;QACd,IAAI,CAAC,CAAA,MAAO,GAAG,IAAI,CAACuB,QAAQ,CAACI,SAAS;IACxC;IAEA,OAAO,CAACC,OAAOC,aAAa,CAAC,GAAG;QAC9B,MAAMC,SAAS,IAAI,CAACpB,QAAQ,CAACC,SAAS;QACtC,MAAO,KAAM;YACX,MAAM,EAAEM,IAAI,EAAEC,KAAK,EAAE,GAAG,MAAMY,OAAOlB,IAAI;YACzC,IAAI,CAACK,MAAM,MAAMC;iBACZ,OAAO,KAAK;QACnB;IACF;IAEA,MAAMa,KAAK5B,KAAU,EAAE;QACrB,MAAM,IAAI,CAAC,CAAA,MAAO,CAAC6B,KAAK,CAAC7B;IAC3B;IAEA,MAAMmB,MAAM;QACV,MAAM,IAAI,CAAC,CAAA,MAAO,CAACG,KAAK;IAC1B;IAEAN,MAAMC,QAAQ,IAAIX,MAAM,iBAAiB,EAAE;QACzC,IAAI,CAAC,CAAA,MAAO,CAACU,KAAK,CAACC;IACrB;AACF;AAEA,OAAO,MAAMa,iCAAiCP;;;IAC5C9B,YACE,AAASE,EAAU,EACnB,AAASC,QAA8B,EACvCC,KAAe,CACf;QACA,KAAK,CAACA;aAJGF,KAAAA;aACAC,WAAAA;IAIX;IAEAgC,KAAK5B,KAAkB,EAAE;QACvB,OAAO,KAAK,CAAC4B,KAAK5B;IACpB;IAEAmB,MAAM;QACJ,OAAO,KAAK,CAACA;IACf;AACF"}
|
package/dist/server/api.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../lib/server/api.ts"],"sourcesContent":["import type { Container } from '@nmtjs/core'\nimport type { Hook } from '@nmtjs/core'\nimport type { Connection } from './connection.ts'\n\nexport type ProtocolApiCallOptions = {\n connection: Connection\n namespace: string\n procedure: string\n container: Container\n payload: any\n signal: AbortSignal\n}\n\nexport type ProtocolAnyIterable<T> =\n | (() => AsyncGenerator<T>)\n
|
|
1
|
+
{"version":3,"sources":["../../../lib/server/api.ts"],"sourcesContent":["import type { Container } from '@nmtjs/core'\nimport type { Hook } from '@nmtjs/core'\nimport type { Connection } from './connection.ts'\n\nexport type ProtocolApiCallOptions = {\n connection: Connection\n namespace: string\n procedure: string\n container: Container\n payload: any\n signal: AbortSignal\n}\n\nexport type ProtocolAnyIterable<T> =\n | (() => AsyncGenerator<T>)\n | AsyncIterable<T>\n\nexport interface ProtocolApiCallBaseResult {\n output: unknown\n}\nexport interface ProtocolApiCallSubscriptionResult\n extends ProtocolApiCallBaseResult {\n subscription: never\n}\n\nexport interface ProtocolApiCallIterableResult\n extends ProtocolApiCallBaseResult {\n iterable: ProtocolAnyIterable<unknown>\n onFinish?: () => void\n}\n\nexport type ProtocolApiCallResult =\n | ProtocolApiCallBaseResult\n | ProtocolApiCallSubscriptionResult\n | ProtocolApiCallIterableResult\n\nexport interface ProtocolApi {\n call(options: ProtocolApiCallOptions): Promise<ProtocolApiCallResult>\n}\n\ndeclare module '@nmtjs/core' {\n export interface HookType {\n [Hook.OnConnect]: (connection: Connection) => any\n [Hook.OnDisconnect]: (connection: Connection) => any\n }\n}\n"],"names":[],"mappings":"AAoCA,WAEC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../lib/server/connection.ts"],"sourcesContent":["import { randomUUID } from 'node:crypto'\
|
|
1
|
+
{"version":3,"sources":["../../../lib/server/connection.ts"],"sourcesContent":["import { randomUUID } from 'node:crypto'\nimport type { InteractivePromise } from '@nmtjs/common'\nimport type { Container } from '@nmtjs/core'\nimport type { ProtocolApiCallResult } from './api.ts'\nimport type { BaseServerDecoder, BaseServerEncoder } from './format.ts'\nimport type { ProtocolClientStream, ProtocolServerStream } from './stream.ts'\n\nexport type ConnectionOptions<Data = unknown> = {\n id?: string\n data: Data\n}\n\nexport class Connection<Data = unknown> {\n readonly id: string\n readonly data: Data\n\n constructor(options: ConnectionOptions<Data>) {\n this.id = options.id ?? randomUUID()\n this.data = options.data\n }\n}\n\nexport type ConnectionCall<T = unknown> = InteractivePromise<T> & {\n abort: AbortController['abort']\n}\n\nexport class ConnectionContext {\n streamId = 1\n calls = new Map<number, ConnectionCall<ProtocolApiCallResult>>()\n clientStreams = new Map<number, ProtocolClientStream>()\n serverStreams = new Map<number, ProtocolServerStream>()\n rpcStreams = new Map<number, AbortController>()\n container: Container\n format: {\n encoder: BaseServerEncoder\n decoder: BaseServerDecoder\n }\n\n constructor(\n container: ConnectionContext['container'],\n format: ConnectionContext['format'],\n ) {\n this.container = container\n this.format = format\n }\n}\n"],"names":["randomUUID","Connection","id","data","constructor","options","ConnectionContext","streamId","calls","Map","clientStreams","serverStreams","rpcStreams","container","format"],"mappings":"AAAA,SAASA,UAAU,QAAQ,cAAa;AAYxC,OAAO,MAAMC;IACFC,GAAU;IACVC,KAAU;IAEnBC,YAAYC,OAAgC,CAAE;QAC5C,IAAI,CAACH,EAAE,GAAGG,QAAQH,EAAE,IAAIF;QACxB,IAAI,CAACG,IAAI,GAAGE,QAAQF,IAAI;IAC1B;AACF;AAMA,OAAO,MAAMG;IACXC,WAAW,EAAC;IACZC,QAAQ,IAAIC,MAAoD;IAChEC,gBAAgB,IAAID,MAAmC;IACvDE,gBAAgB,IAAIF,MAAmC;IACvDG,aAAa,IAAIH,MAA8B;IAC/CI,UAAoB;IACpBC,OAGC;IAEDV,YACES,SAAyC,EACzCC,MAAmC,CACnC;QACA,IAAI,CAACD,SAAS,GAAGA;QACjB,IAAI,CAACC,MAAM,GAAGA;IAChB;AACF"}
|
package/dist/server/protocol.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { createPromise, throwError } from '@nmtjs/common';
|
|
1
|
+
import { createPromise, defer, throwError } from '@nmtjs/common';
|
|
2
2
|
import { Hook, Scope } from '@nmtjs/core';
|
|
3
3
|
import { concat, decodeNumber, encodeNumber } from "../common/binary.js";
|
|
4
4
|
import { ErrorCode, ServerMessageType } from "../common/enums.js";
|
|
@@ -63,7 +63,7 @@ export class ProtocolConnections {
|
|
|
63
63
|
concurrent: true
|
|
64
64
|
}, connection);
|
|
65
65
|
this.#collection.delete(connectionId);
|
|
66
|
-
const { calls, serverStreams, clientStreams, container } = context;
|
|
66
|
+
const { calls, serverStreams, clientStreams, rpcStreams, container } = context;
|
|
67
67
|
for (const call of calls.values()){
|
|
68
68
|
call.reject(new Error('Connection closed'));
|
|
69
69
|
}
|
|
@@ -73,6 +73,9 @@ export class ProtocolConnections {
|
|
|
73
73
|
for (const stream of serverStreams.values()){
|
|
74
74
|
stream.destroy(new Error('Connection closed'));
|
|
75
75
|
}
|
|
76
|
+
for (const stream of rpcStreams.values()){
|
|
77
|
+
stream.abort(new Error('Connection closed'));
|
|
78
|
+
}
|
|
76
79
|
try {
|
|
77
80
|
await container.dispose();
|
|
78
81
|
} catch (error) {
|
|
@@ -169,7 +172,7 @@ export class Protocol {
|
|
|
169
172
|
this.clientStreams = new ProtocolClientStreams(this.connections);
|
|
170
173
|
this.serverStreams = new ProtocolServerStreams(this.connections);
|
|
171
174
|
}
|
|
172
|
-
async
|
|
175
|
+
async rpc(connectionId, rpc, params = {}) {
|
|
173
176
|
const { connection, context, transport } = this.connections.get(connectionId);
|
|
174
177
|
const { calls, format } = context;
|
|
175
178
|
const { callId, namespace, procedure, payload } = rpc;
|
|
@@ -222,14 +225,20 @@ export class Protocol {
|
|
|
222
225
|
} else if ('iterable' in response) {
|
|
223
226
|
transport.send(connection, ServerMessageType.RpcStreamResponse, responseEncoded);
|
|
224
227
|
try {
|
|
228
|
+
const ab = new AbortController();
|
|
229
|
+
context.rpcStreams.set(callId, ab);
|
|
225
230
|
const iterable = typeof response.iterable === 'function' ? response.iterable() : response.iterable;
|
|
226
231
|
for await (const chunk of iterable){
|
|
232
|
+
if (ab.signal.aborted) break;
|
|
227
233
|
const chunkEncoded = format.encoder.encode(chunk);
|
|
228
234
|
transport.send(connection, ServerMessageType.RpcStreamChunk, concat(callIdEncoded, chunkEncoded));
|
|
229
235
|
}
|
|
230
236
|
} catch (error) {
|
|
231
237
|
this.application.logger.error(error);
|
|
232
238
|
transport.send(connection, ServerMessageType.RpcStreamAbort, callIdEncoded);
|
|
239
|
+
} finally{
|
|
240
|
+
context.rpcStreams.delete(callId);
|
|
241
|
+
response.onFinish && defer(response.onFinish);
|
|
233
242
|
}
|
|
234
243
|
} else {
|
|
235
244
|
transport.send(connection, ServerMessageType.RpcResponse, responseEncoded);
|
|
@@ -263,7 +272,7 @@ export class Protocol {
|
|
|
263
272
|
});
|
|
264
273
|
}
|
|
265
274
|
}
|
|
266
|
-
async
|
|
275
|
+
async rpcRaw(connectionId, buffer, params = {}) {
|
|
267
276
|
const { connection, context, transport } = this.connections.get(connectionId);
|
|
268
277
|
const { format } = context;
|
|
269
278
|
const rpc = format.decoder.decodeRPC(buffer, {
|
|
@@ -276,16 +285,25 @@ export class Protocol {
|
|
|
276
285
|
return this.serverStreams.get(connectionId, id);
|
|
277
286
|
}
|
|
278
287
|
});
|
|
279
|
-
return await this.
|
|
288
|
+
return await this.rpc(connectionId, rpc, params);
|
|
280
289
|
}
|
|
281
|
-
|
|
290
|
+
rpcAbort(connectionId, callId) {
|
|
282
291
|
const { context } = this.connections.get(connectionId);
|
|
283
292
|
const call = context.calls.get(callId) ?? throwError('Call not found');
|
|
284
293
|
call.abort();
|
|
285
294
|
}
|
|
286
|
-
|
|
295
|
+
rpcAbortRaw(connectionId, buffer) {
|
|
296
|
+
const callId = decodeNumber(buffer, 'Uint32');
|
|
297
|
+
return this.rpcAbort(connectionId, callId);
|
|
298
|
+
}
|
|
299
|
+
rpcStreamAbort(connectionId, callId) {
|
|
300
|
+
const { context } = this.connections.get(connectionId);
|
|
301
|
+
const ab = context.rpcStreams.get(callId) ?? throwError('Call stream not found');
|
|
302
|
+
ab.abort();
|
|
303
|
+
}
|
|
304
|
+
rpcStreamAbortRaw(connectionId, buffer) {
|
|
287
305
|
const callId = decodeNumber(buffer, 'Uint32');
|
|
288
|
-
return this.
|
|
306
|
+
return this.rpcStreamAbort(connectionId, callId);
|
|
289
307
|
}
|
|
290
308
|
notify(connectionId, event, payload) {
|
|
291
309
|
throw Error('Unimplemented');
|