@nmtjs/protocol 0.8.0 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. package/dist/client/events.js +2 -0
  2. package/dist/client/events.js.map +1 -1
  3. package/dist/client/format.js +2 -0
  4. package/dist/client/format.js.map +1 -1
  5. package/dist/client/index.js +3 -0
  6. package/dist/client/index.js.map +1 -1
  7. package/dist/client/protocol.js +205 -199
  8. package/dist/client/protocol.js.map +1 -1
  9. package/dist/client/stream.js +9 -12
  10. package/dist/client/stream.js.map +1 -1
  11. package/dist/client/types.js +3 -0
  12. package/dist/client/types.js.map +1 -0
  13. package/dist/common/binary.js +2 -0
  14. package/dist/common/binary.js.map +1 -1
  15. package/dist/common/blob.js +6 -2
  16. package/dist/common/blob.js.map +1 -1
  17. package/dist/common/enums.js +4 -1
  18. package/dist/common/enums.js.map +1 -1
  19. package/dist/common/index.js +2 -0
  20. package/dist/common/index.js.map +1 -1
  21. package/dist/common/types.js +2 -0
  22. package/dist/common/types.js.map +1 -1
  23. package/dist/server/api.js +4 -1
  24. package/dist/server/api.js.map +1 -1
  25. package/dist/server/connection.js +2 -0
  26. package/dist/server/connection.js.map +1 -1
  27. package/dist/server/constants.js +2 -0
  28. package/dist/server/constants.js.map +1 -1
  29. package/dist/server/format.js +2 -0
  30. package/dist/server/format.js.map +1 -1
  31. package/dist/server/index.js +3 -0
  32. package/dist/server/index.js.map +1 -1
  33. package/dist/server/injectables.js +2 -0
  34. package/dist/server/injectables.js.map +1 -1
  35. package/dist/server/protocol.js +154 -55
  36. package/dist/server/protocol.js.map +1 -1
  37. package/dist/server/registry.js +2 -0
  38. package/dist/server/registry.js.map +1 -1
  39. package/dist/server/stream.js +3 -1
  40. package/dist/server/stream.js.map +1 -1
  41. package/dist/server/transport.js +2 -0
  42. package/dist/server/transport.js.map +1 -1
  43. package/dist/server/types.js +3 -0
  44. package/dist/server/types.js.map +1 -0
  45. package/dist/server/utils.js +7 -2
  46. package/dist/server/utils.js.map +1 -1
  47. package/package.json +7 -7
  48. package/src/client/format.ts +34 -5
  49. package/src/client/index.ts +2 -0
  50. package/src/client/protocol.ts +381 -274
  51. package/src/client/stream.ts +7 -14
  52. package/src/client/types.ts +14 -0
  53. package/src/common/blob.ts +10 -3
  54. package/src/common/enums.ts +3 -1
  55. package/src/common/types.ts +28 -47
  56. package/src/server/api.ts +15 -1
  57. package/src/server/connection.ts +1 -5
  58. package/src/server/format.ts +14 -4
  59. package/src/server/index.ts +1 -0
  60. package/src/server/protocol.ts +208 -66
  61. package/src/server/stream.ts +2 -7
  62. package/src/server/transport.ts +5 -1
  63. package/src/server/types.ts +21 -0
  64. package/src/server/utils.ts +9 -2
@@ -29,3 +29,5 @@ export class EventEmitter {
29
29
  return this.#target.dispatchEvent(new CustomEvent(event, { detail: args }));
30
30
  }
31
31
  }
32
+
33
+ //# sourceMappingURL=events.js.map
@@ -1 +1 @@
1
- {"mappings":";;;;;AASA,OAAO,MAAM,aAMX;CACA,OAAO,KAGLA,IAAOC,OAAU;AACjB,SAAO,IAAI,QAAQ,CAAC,YAAY,GAAG,KAAK,OAAO,QAAQ;CACxD;CAED,UAAU,IAAI;CACd,aAAa,IAAI;CAEjB,GACEC,OACAC,UACAC,SACA;EACA,MAAM,UAAU,CAAC,UAAU,SAAS,GAAG,MAAM,OAAO;AACpD,OAAKC,WAAW,IAAI,UAAU,QAAQ;AACtC,OAAKC,QAAQ,iBAAiB,OAAO,SAAS,QAAQ;AACtD,SAAO,MAAM,KAAKA,QAAQ,oBAAoB,OAAO,QAAQ;CAC9D;CAED,KACEJ,OACAC,UACAC,SACA;AACA,SAAO,KAAK,GAAG,OAAO,UAAU;GAAE,GAAG;GAAS,MAAM;EAAM,EAAC;CAC5D;CAED,IAAIG,OAAuCC,UAAoB;EAC7D,MAAM,UAAU,KAAKH,WAAW,IAAI,SAAS;AAC7C,MAAI,QAAS,MAAKC,QAAQ,oBAAoB,OAAO,QAAQ;CAC9D;CAED,KACEL,OACA,GAAG,MACH;AACA,SAAO,KAAKK,QAAQ,cAAc,IAAI,YAAY,OAAO,EAAE,QAAQ,KAAM,GAAE;CAC5E;AACF","names":["ee: T","event: E","event: E | (Object & string)","listener: (...args: Events[E]) => void","options?: AddEventListenerOptions","#listeners","#target","event: EventNames | (Object & string)","listener: Callback"],"sources":["src/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<\n T extends EventEmitter,\n E extends T extends EventEmitter<any, infer Event> ? Event : never,\n >(ee: T, event: E) {\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"],"version":3}
1
+ {"mappings":";;;;;AASA,OAAO,MAAM,aAMX;CACA,OAAO,KAGLA,IAAOC,OAAU;AACjB,SAAO,IAAI,QAAQ,CAAC,YAAY,GAAG,KAAK,OAAO,QAAQ;CACxD;CAED,UAAU,IAAI;CACd,aAAa,IAAI;CAEjB,GACEC,OACAC,UACAC,SACA;EACA,MAAM,UAAU,CAAC,UAAU,SAAS,GAAG,MAAM,OAAO;AACpD,OAAKC,WAAW,IAAI,UAAU,QAAQ;AACtC,OAAKC,QAAQ,iBAAiB,OAAO,SAAS,QAAQ;AACtD,SAAO,MAAM,KAAKA,QAAQ,oBAAoB,OAAO,QAAQ;CAC9D;CAED,KACEJ,OACAC,UACAC,SACA;AACA,SAAO,KAAK,GAAG,OAAO,UAAU;GAAE,GAAG;GAAS,MAAM;EAAM,EAAC;CAC5D;CAED,IAAIG,OAAuCC,UAAoB;EAC7D,MAAM,UAAU,KAAKH,WAAW,IAAI,SAAS;AAC7C,MAAI,QAAS,MAAKC,QAAQ,oBAAoB,OAAO,QAAQ;CAC9D;CAED,KACEL,OACA,GAAG,MACH;AACA,SAAO,KAAKK,QAAQ,cAAc,IAAI,YAAY,OAAO,EAAE,QAAQ,KAAM,GAAE;CAC5E;AACF","names":["ee: T","event: E","event: E | (Object & string)","listener: (...args: Events[E]) => void","options?: AddEventListenerOptions","#listeners","#target","event: EventNames | (Object & string)","listener: Callback"],"sources":["../../src/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<\n T extends EventEmitter,\n E extends T extends EventEmitter<any, infer Event> ? Event : never,\n >(ee: T, event: E) {\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"],"version":3,"file":"events.js"}
@@ -1 +1,3 @@
1
1
  export class BaseClientFormat {}
2
+
3
+ //# sourceMappingURL=format.js.map
@@ -1 +1 @@
1
- {"mappings":"AASA,OAAO,MAAe,iBAEtB,CAUC","names":[],"sources":["src/client/format.ts"],"sourcesContent":["import type {\n BaseClientDecoder,\n BaseClientEncoder,\n DecodeRPCContext,\n EncodeRPCContext,\n ProtocolRPC,\n ProtocolRPCResponse,\n} from '../common/types.ts'\n\nexport abstract class BaseClientFormat\n implements BaseClientDecoder, BaseClientEncoder\n{\n abstract contentType: string\n\n abstract encode(data: any): ArrayBuffer\n abstract encodeRPC(rpc: ProtocolRPC, context: EncodeRPCContext): ArrayBuffer\n abstract decode(buffer: ArrayBuffer): any\n abstract decodeRPC(\n buffer: ArrayBuffer,\n context: DecodeRPCContext,\n ): ProtocolRPCResponse\n}\n"],"version":3}
1
+ {"mappings":"AAmCA,OAAO,MAAe,iBAEtB,CAaC","names":[],"sources":["../../src/client/format.ts"],"sourcesContent":["import type {\n // BaseClientDecoder,\n // BaseClientEncoder,\n DecodeRPCContext,\n EncodeRPCContext,\n ProtocolRPC,\n // ProtocolRPCEncode,\n ProtocolRPCResponse,\n} from '../common/types.ts'\nimport type {\n ProtocolClientBlobStream,\n ProtocolServerBlobStream,\n} from './stream.ts'\n\nexport type ProtocolRPCEncode = {\n buffer: ArrayBuffer\n streams: Record<number, ProtocolClientBlobStream>\n}\n\nexport interface BaseClientDecoder {\n decode(buffer: ArrayBuffer): any\n decodeRPC(\n buffer: ArrayBuffer,\n context: DecodeRPCContext<ProtocolServerBlobStream>,\n ): ProtocolRPCResponse<ProtocolServerBlobStream>\n}\n\nexport interface BaseClientEncoder {\n encode(data: any): ArrayBuffer\n encodeRPC(\n rpc: ProtocolRPC,\n context: EncodeRPCContext<ProtocolClientBlobStream>,\n ): ProtocolRPCEncode\n}\n\nexport abstract class BaseClientFormat\n implements BaseClientDecoder, BaseClientEncoder\n{\n abstract contentType: string\n\n abstract encode(data: any): ArrayBuffer\n abstract encodeRPC(\n rpc: ProtocolRPC,\n context: EncodeRPCContext<ProtocolClientBlobStream>,\n ): ProtocolRPCEncode\n abstract decode(buffer: ArrayBuffer): any\n abstract decodeRPC(\n buffer: ArrayBuffer,\n context: DecodeRPCContext<ProtocolServerBlobStream>,\n ): ProtocolRPCResponse<ProtocolServerBlobStream>\n}\n"],"version":3,"file":"format.js"}
@@ -2,3 +2,6 @@ export * from "./events.js";
2
2
  export * from "./format.js";
3
3
  export * from "./protocol.js";
4
4
  export * from "./stream.js";
5
+ export * from "./types.js";
6
+
7
+ //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"mappings":"AAAA,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc","names":[],"sources":["src/client/index.ts"],"sourcesContent":["export * from './events.ts'\nexport * from './format.ts'\nexport * from './protocol.ts'\nexport * from './stream.ts'\n"],"version":3}
1
+ {"mappings":"AAAA,cAAc;AACd,cAAc;AACd,cAAc;AAEd,cAAc;AACd,cAAc","names":[],"sources":["../../src/client/index.ts"],"sourcesContent":["export * from './events.ts'\nexport * from './format.ts'\nexport * from './protocol.ts'\n// export * from './protocolv1.ts'\nexport * from './stream.ts'\nexport * from './types.ts'\n"],"version":3,"file":"index.js"}
@@ -1,4 +1,4 @@
1
- import { createPromise, onceAborted } from "@nmtjs/common";
1
+ import { createPromise } from "@nmtjs/common";
2
2
  import { concat, decodeNumber, encodeNumber } from "../common/binary.js";
3
3
  import { ClientMessageType, ErrorCode, ServerMessageType } from "../common/enums.js";
4
4
  import { EventEmitter } from "./events.js";
@@ -40,9 +40,9 @@ export class ProtocolClientStreams {
40
40
  remove(streamId) {
41
41
  this.#collection.delete(streamId);
42
42
  }
43
- abort(streamId) {
43
+ abort(streamId, error) {
44
44
  const stream = this.get(streamId);
45
- stream.abort();
45
+ stream.abort(error);
46
46
  this.remove(streamId);
47
47
  }
48
48
  pull(streamId, size) {
@@ -104,6 +104,7 @@ export class ProtocolServerStreams {
104
104
  this.#collection.clear();
105
105
  }
106
106
  }
107
+ export class ProtocolTransport {}
107
108
  export class ProtocolBaseTransformer {
108
109
  encodeRPC(namespace, procedure, payload) {
109
110
  return payload;
@@ -118,228 +119,233 @@ export class ProtocolBaseTransformer {
118
119
  return payload;
119
120
  }
120
121
  }
121
- export class ProtocolBaseClient extends EventEmitter {
122
- #clientStreams;
123
- #serverStreams;
124
- #rpcStreams;
125
- #rpcStreamData = new Map();
126
- #calls = new Map();
127
- #transport;
128
- #format;
129
- transformer = new ProtocolBaseTransformer();
130
- #timeout;
131
- #callId = 0;
132
- #streamId = 0;
133
- constructor(options) {
122
+ export class BaseProtocol extends EventEmitter {
123
+ clientStreams = new ProtocolClientStreams();
124
+ serverStreams = new ProtocolServerStreams();
125
+ rpcStreams = new ProtocolServerStreams();
126
+ calls = new Map();
127
+ callId = 0;
128
+ streamId = 0;
129
+ constructor(format) {
134
130
  super();
135
- this.#transport = options.transport;
136
- this.#format = options.format;
137
- this.#timeout = options.timeout ?? 6e4;
138
- this.#clientStreams = new ProtocolClientStreams();
139
- this.#serverStreams = new ProtocolServerStreams();
140
- this.#rpcStreams = new ProtocolServerStreams();
141
- this.#transport.on(`${ServerMessageType.Event}`, (buffer) => {
142
- const [namespace, event, payload] = this.#format.decode(buffer);
143
- const name = `${namespace}/${event}`;
144
- const transformed = this.transformer.decodeEvent(namespace, event, payload);
145
- this.emit(name, transformed);
146
- });
147
- this.#transport.on(`${ServerMessageType.RpcResponse}`, (buffer) => {
148
- const { call, error, payload } = this.#handleResponse(buffer);
149
- if (error) call.reject(error);
150
- else call.resolve(payload);
151
- });
152
- this.#transport.on(`${ServerMessageType.RpcStreamResponse}`, (buffer) => {
153
- const { call, response, payload, error } = this.#handleResponse(buffer);
154
- if (error) return call.reject(error);
155
- console.log("Creating RPC stream", response);
156
- const stream = new ProtocolServerStream();
157
- this.#rpcStreams.add(response.callId, stream);
158
- this.#rpcStreamData.set(response.callId, {
159
- namespace: call.namespace,
160
- procedure: call.procedure
161
- });
162
- call.resolve({
163
- payload,
164
- stream
165
- });
166
- });
167
- this.#transport.on(`${ServerMessageType.RpcStreamChunk}`, async (buffer) => {
168
- const callId = decodeNumber(buffer, "Uint32");
169
- console.log("RPC stream chunk", callId);
170
- const chunk = buffer.slice(Uint32Array.BYTES_PER_ELEMENT);
171
- if (chunk.byteLength === 0) {
172
- this.#rpcStreams.end(callId);
173
- this.#rpcStreamData.delete(callId);
174
- } else {
175
- const call = this.#rpcStreamData.get(callId);
176
- console.log("RPC stream call", call);
177
- if (call) {
178
- const payload = this.#format.decode(chunk);
179
- console.log("RPC stream payload", payload);
180
- try {
181
- const transformed = this.transformer.decodeRPCChunk(call.namespace, call.procedure, payload);
182
- await this.#rpcStreams.push(callId, transformed);
183
- } catch (error) {
184
- this.#send(ClientMessageType.RpcStreamAbort, encodeNumber(callId, "Uint32"));
185
- this.#rpcStreams.remove(callId);
186
- this.#rpcStreamData.delete(callId);
187
- }
188
- }
189
- }
190
- });
191
- this.#transport.on(`${ServerMessageType.RpcStreamAbort}`, (buffer) => {
192
- const callId = decodeNumber(buffer, "Uint32");
193
- console.log("RPC stream abort", callId);
194
- const call = this.#calls.get(callId);
195
- if (call) {
196
- this.#serverStreams.end(callId);
197
- this.#rpcStreams.abort(callId);
198
- }
199
- });
200
- this.#transport.on(`${ServerMessageType.ServerStreamPush}`, async (buffer) => {
201
- const streamId = decodeNumber(buffer, "Uint32");
202
- const chunk = buffer.slice(Uint32Array.BYTES_PER_ELEMENT);
203
- console.log("Server stream push", streamId, chunk.byteLength);
204
- try {
205
- await this.#serverStreams.push(streamId, chunk);
206
- this.#send(ClientMessageType.ServerStreamPull, encodeNumber(streamId, "Uint32"));
207
- } catch (error) {
208
- this.#send(ClientMessageType.ServerStreamAbort, encodeNumber(streamId, "Uint32"));
209
- this.#serverStreams.remove(streamId);
210
- }
211
- });
212
- this.#transport.on(`${ServerMessageType.ServerStreamEnd}`, (buffer) => {
213
- const streamId = decodeNumber(buffer, "Uint32");
214
- console.log("Server stream end", streamId);
215
- this.#serverStreams.end(streamId);
216
- });
217
- this.#transport.on(`${ServerMessageType.ServerStreamAbort}`, (buffer) => {
218
- const streamId = decodeNumber(buffer, "Uint32");
219
- console.log("Server stream abort", streamId);
220
- this.#serverStreams.abort(streamId);
221
- });
222
- this.#transport.on(`${ServerMessageType.ClientStreamAbort}`, (buffer) => {
223
- const streamId = decodeNumber(buffer, "Uint32");
224
- console.log("Client stream abort", streamId);
225
- this.#clientStreams.abort(streamId);
226
- });
227
- this.#transport.on(`${ServerMessageType.ClientStreamPull}`, async (buffer) => {
228
- const streamId = decodeNumber(buffer, "Uint32");
229
- console.log("Client stream pull", streamId);
230
- const size = decodeNumber(buffer, "Uint32", Uint32Array.BYTES_PER_ELEMENT);
231
- const streamIdEncoded = encodeNumber(streamId, "Uint32");
131
+ this.format = format;
132
+ }
133
+ get contentType() {
134
+ return this.format.contentType;
135
+ }
136
+ handleCallResponse(callId, call, response, transformer) {
137
+ if (response.error) {
138
+ call.reject(new ProtocolError(response.error.code, response.error.message, response.error.data));
139
+ } else {
232
140
  try {
233
- const chunk = await this.#clientStreams.pull(streamId, size);
234
- if (chunk) {
235
- this.#send(ClientMessageType.ClientStreamPush, concat(streamIdEncoded, chunk));
236
- } else {
237
- this.#send(ClientMessageType.ClientStreamEnd, streamIdEncoded);
238
- this.#clientStreams.end(streamId);
239
- }
141
+ const transformed = transformer.decodeRPC(call.namespace, call.procedure, response.result);
142
+ if (response.stream) call.resolve({
143
+ result: transformed,
144
+ stream: response.stream
145
+ });
146
+ else call.resolve(transformed);
240
147
  } catch (error) {
241
- console.error(error);
242
- this.#send(ClientMessageType.ClientStreamAbort, streamIdEncoded);
148
+ call.reject(new ProtocolError(ErrorCode.ClientRequestError, "Unable to decode response", error));
243
149
  }
244
- });
245
- this.#transport.on("disconnected", () => {
246
- this.#clear();
247
- });
150
+ }
151
+ this.calls.delete(callId);
248
152
  }
249
- async connect(auth) {
250
- return await this.#transport.connect(auth, this.#format.contentType);
251
- }
252
- async disconnect() {
253
- this.#clear();
254
- return await this.#transport.disconnect();
255
- }
256
- async #send(messageType, buffer) {
257
- console.log("Client transport send", ClientMessageType[messageType], buffer.byteLength);
258
- return await this.#transport.send(messageType, buffer);
259
- }
260
- async #clear() {
261
- const error = new ProtocolError(ErrorCode.ConnectionError, "Connection closed");
262
- for (const call of this.#calls.values()) call.reject(error);
263
- this.#calls.clear();
264
- this.#serverStreams.clear(error);
265
- this.#clientStreams.clear(error);
266
- this.#rpcStreams.clear(error);
267
- this.#callId = 0;
268
- this.#streamId = 0;
269
- }
270
- async _call(namespace, procedure, payload, options = {}) {
271
- const timeoutSignal = AbortSignal.timeout(options.timeout || this.#timeout);
153
+ handleRpcResponse({ callId, error, result, streams }, transformer, stream) {
154
+ const call = this.calls.get(callId);
155
+ if (!call) throw new Error("Call not found");
156
+ for (const key in streams) {
157
+ const stream = streams[key];
158
+ this.serverStreams.add(stream.id, stream);
159
+ }
160
+ this.handleCallResponse(callId, call, error ? { error } : {
161
+ result,
162
+ stream
163
+ }, transformer);
164
+ return call;
165
+ }
166
+ handleRpcStreamResponse(response, stream, transformer) {
167
+ const call = this.handleRpcResponse(response, transformer, stream);
168
+ this.rpcStreams.add(response.callId, stream);
169
+ return call;
170
+ }
171
+ createCall(namespace, procedure, options) {
172
+ const timeoutSignal = AbortSignal.timeout(options.timeout);
272
173
  const signal = options.signal ? AbortSignal.any([options.signal, timeoutSignal]) : timeoutSignal;
273
- const callId = ++this.#callId;
274
174
  const call = Object.assign(createPromise(), {
275
175
  namespace,
276
- procedure
176
+ procedure,
177
+ signal
277
178
  });
278
- const buffer = this.#format.encodeRPC({
179
+ timeoutSignal.addEventListener("abort", () => {
180
+ const error = new ProtocolError(ErrorCode.RequestTimeout, "Request timeout");
181
+ call.reject(error);
182
+ }, { once: true });
183
+ return call;
184
+ }
185
+ createRpc(namespace, procedure, payload, options, transformer) {
186
+ const callId = ++this.callId;
187
+ const call = this.createCall(namespace, procedure, options);
188
+ const { buffer, streams } = this.format.encodeRPC({
279
189
  callId,
280
190
  namespace,
281
191
  procedure,
282
- payload: this.transformer.encodeRPC(namespace, procedure, payload)
192
+ payload: transformer.encodeRPC(namespace, procedure, payload)
283
193
  }, {
284
194
  addStream: (blob) => {
285
- const streamId = ++this.#streamId;
286
- const stream = this.#clientStreams.add(blob.source, streamId, blob.metadata);
287
- return stream;
195
+ const streamId = ++this.streamId;
196
+ return this.clientStreams.add(blob.source, streamId, blob.metadata);
288
197
  },
289
198
  getStream: (id) => {
290
- const stream = this.#clientStreams.get(id);
199
+ const stream = this.clientStreams.get(id);
291
200
  return stream;
292
201
  }
293
202
  });
294
- this.#transport.send(ClientMessageType.Rpc, buffer).catch(console.error);
295
- this.#calls.set(callId, call);
296
- const onAborted = onceAborted(signal).then(() => {
297
- if (this.#calls.has(callId)) {
298
- this.#send(ClientMessageType.RpcAbort, encodeNumber(callId, "Uint32"));
203
+ this.calls.set(callId, call);
204
+ return {
205
+ callId,
206
+ call,
207
+ streams,
208
+ buffer
209
+ };
210
+ }
211
+ pushRpcStream(callId, chunk) {
212
+ this.rpcStreams.push(callId, chunk);
213
+ }
214
+ endRpcStream(callId) {
215
+ this.rpcStreams.end(callId);
216
+ }
217
+ abortRpcStream(callId) {
218
+ this.rpcStreams.abort(callId);
219
+ }
220
+ removeClientStream(streamId) {
221
+ this.clientStreams.remove(streamId);
222
+ }
223
+ pullClientStream(streamId, size) {
224
+ return this.clientStreams.pull(streamId, size);
225
+ }
226
+ endClientStream(streamId) {
227
+ this.clientStreams.end(streamId);
228
+ }
229
+ abortClientStream(streamId, error) {
230
+ this.clientStreams.abort(streamId, error);
231
+ }
232
+ addServerStream(stream) {
233
+ this.serverStreams.add(stream.id, stream);
234
+ }
235
+ removeServerStream(streamId) {
236
+ this.serverStreams.remove(streamId);
237
+ }
238
+ pushServerStream(streamId, chunk) {
239
+ return this.serverStreams.push(streamId, chunk);
240
+ }
241
+ endServerStream(streamId) {
242
+ this.serverStreams.end(streamId);
243
+ }
244
+ abortServerStream(streamId, error) {
245
+ this.serverStreams.abort(streamId);
246
+ }
247
+ emitEvent(namespace, event, payload, transformer) {
248
+ const transformed = transformer.decodeEvent(namespace, event, payload);
249
+ this.emit(`${namespace}/${event}`, transformed);
250
+ }
251
+ }
252
+ export class Protocol extends BaseProtocol {
253
+ handleServerMessage(buffer, transport, transformer) {
254
+ const type = decodeNumber(buffer, "Uint8");
255
+ const messageBuffer = buffer.slice(Uint8Array.BYTES_PER_ELEMENT);
256
+ if (type in ServerMessageType) {
257
+ const messageType = type;
258
+ if (typeof ServerMessageType[messageType] !== "undefined") {
259
+ this[messageType](messageBuffer, transport, transformer);
260
+ } else {
261
+ throw new Error(`Unknown message type: ${messageType}`);
262
+ }
263
+ }
264
+ }
265
+ [ServerMessageType.Event](buffer, transport, transformer) {
266
+ const [namespace, event, payload] = this.format.decode(buffer);
267
+ this.emitEvent(namespace, event, payload, transformer);
268
+ }
269
+ [ServerMessageType.RpcResponse](buffer, transport, transformer) {
270
+ const response = this.format.decodeRPC(buffer, {
271
+ addStream: (id, callId, metadata) => {
272
+ return new ProtocolServerBlobStream(id, metadata, { start: () => {
273
+ transport.send(ClientMessageType.ServerStreamPull, encodeNumber(id, "Uint32"), {
274
+ callId,
275
+ streamId: id
276
+ });
277
+ } });
278
+ },
279
+ getStream: (id) => {
280
+ return this.serverStreams.get(id);
299
281
  }
300
- throw new ProtocolError(ErrorCode.RequestTimeout, "Request timeout");
301
282
  });
302
- return Promise.race([call.promise, onAborted]);
303
- }
304
- #handleResponse(buffer) {
305
- const callStreams = [];
306
- const response = this.#format.decodeRPC(buffer, {
307
- addStream: (id, metadata) => {
308
- console.log("Client transport blob stream", id, metadata);
309
- const stream = new ProtocolServerBlobStream(id, metadata, () => {
310
- this.#send(ClientMessageType.ServerStreamPull, encodeNumber(id, "Uint32"));
311
- });
312
- callStreams.push(stream);
313
- this.#serverStreams.add(id, stream);
314
- return stream;
283
+ this.handleRpcResponse(response, transformer);
284
+ }
285
+ [ServerMessageType.RpcStreamResponse](buffer, transport, transformer) {
286
+ const response = this.format.decodeRPC(buffer, {
287
+ addStream: (id, callId, metadata) => {
288
+ return new ProtocolServerBlobStream(id, metadata, { start: () => {
289
+ transport.send(ClientMessageType.ServerStreamPull, encodeNumber(id, "Uint32"), {
290
+ callId,
291
+ streamId: id
292
+ });
293
+ } });
315
294
  },
316
295
  getStream: (id) => {
317
- return this.#serverStreams.get(id);
296
+ return this.serverStreams.get(id);
318
297
  }
319
298
  });
320
- console.log("Client transport response", response);
321
- const call = this.#calls.get(response.callId);
322
- if (call) {
323
- this.#calls.delete(response.callId);
324
- if (response.error) {
325
- const error = new ProtocolError(response.error.code, response.error.message, response.error.data);
326
- return {
327
- call,
328
- response,
329
- error
330
- };
299
+ const stream = new ProtocolServerStream({ transform: (chunk, controller) => {
300
+ const transformed = transformer.decodeRPCChunk(call.namespace, call.procedure, chunk);
301
+ controller.enqueue(transformed);
302
+ } });
303
+ const call = this.handleRpcStreamResponse(response, stream, transformer);
304
+ }
305
+ [ServerMessageType.RpcStreamChunk](buffer, transport, transformer) {
306
+ const callId = decodeNumber(buffer, "Uint32");
307
+ const chunk = buffer.slice(Uint32Array.BYTES_PER_ELEMENT);
308
+ const payload = this.format.decode(chunk);
309
+ this.pushRpcStream(callId, payload);
310
+ }
311
+ [ServerMessageType.RpcStreamEnd](buffer, transport, transformer) {
312
+ const callId = decodeNumber(buffer, "Uint32");
313
+ this.endRpcStream(callId);
314
+ }
315
+ [ServerMessageType.RpcStreamAbort](buffer, transport, transformer) {
316
+ const callId = decodeNumber(buffer, "Uint32");
317
+ this.abortRpcStream(callId);
318
+ }
319
+ [ServerMessageType.ServerStreamPush](buffer, transport, transformer) {
320
+ const streamId = decodeNumber(buffer, "Uint32");
321
+ const chunk = buffer.slice(Uint32Array.BYTES_PER_ELEMENT);
322
+ this.pushServerStream(streamId, chunk);
323
+ transport.send(ClientMessageType.ServerStreamPull, encodeNumber(streamId, "Uint32"), { streamId });
324
+ }
325
+ [ServerMessageType.ServerStreamEnd](buffer, transport, transformer) {
326
+ const streamId = decodeNumber(buffer, "Uint32");
327
+ this.endServerStream(streamId);
328
+ }
329
+ [ServerMessageType.ServerStreamAbort](buffer, transport, transformer) {
330
+ const streamId = decodeNumber(buffer, "Uint32");
331
+ this.abortServerStream(streamId);
332
+ }
333
+ [ServerMessageType.ClientStreamPull](buffer, transport, transformer) {
334
+ const streamId = decodeNumber(buffer, "Uint32");
335
+ const size = decodeNumber(buffer, "Uint32", Uint32Array.BYTES_PER_ELEMENT);
336
+ this.pullClientStream(streamId, size).then((chunk) => {
337
+ if (chunk) {
338
+ transport.send(ClientMessageType.ClientStreamPush, concat(encodeNumber(streamId, "Uint32"), chunk), { streamId });
331
339
  } else {
332
- const payload = this.transformer.decodeRPC(call.namespace, call.procedure, response.payload);
333
- return {
334
- call,
335
- response,
336
- payload
337
- };
340
+ transport.send(ClientMessageType.ClientStreamEnd, encodeNumber(streamId, "Uint32"), { streamId });
341
+ this.endClientStream(streamId);
338
342
  }
339
- }
340
- for (const stream of callStreams) {
341
- this.#serverStreams.abort(stream.id);
342
- }
343
- throw new Error("Call not found");
343
+ });
344
+ }
345
+ [ServerMessageType.ClientStreamAbort](buffer, transport, transformer) {
346
+ const streamId = decodeNumber(buffer, "Uint32");
347
+ this.abortClientStream(streamId);
344
348
  }
345
349
  }
350
+
351
+ //# sourceMappingURL=protocol.js.map
@@ -1 +1 @@
1
- {"mappings":"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","names":["code: string","message?: string","data?: any","#collection","streamId: number","source: ReadableStream","metadata: ProtocolBlobMetadata","size: number","error?: Error","stream: ProtocolServerStream","chunk: ArrayBuffer","namespace: string","procedure: string","payload: any","event: string","#clientStreams","#serverStreams","#rpcStreams","#rpcStreamData","#calls","#transport","#format","#timeout","options: ProtocolBaseClientOptions","#handleResponse","#send","#clear","auth: any","messageType: ClientMessageType","buffer: ArrayBuffer","#callId","#streamId","options: ProtocolBaseClientCallOptions","callStreams: ProtocolServerBlobStream[]"],"sources":["src/client/protocol.ts"],"sourcesContent":["import {\n createPromise,\n type InteractivePromise,\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 this.get(streamId).end()\n this.remove(streamId)\n }\n\n clear(error?: Error) {\n if (error) {\n for (const stream of this.#collection.values()) {\n stream.abort(error)\n }\n }\n this.#collection.clear()\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 clear(error?: Error) {\n if (error) {\n for (const stream of this.#collection.values()) {\n stream.abort(error)\n }\n }\n this.#collection.clear()\n }\n}\n\nexport type ProtocolTransportEventMap = {\n [K in `${ServerMessageType}`]: [ArrayBuffer]\n} & {\n connected: []\n disconnected: []\n}\n\nexport interface ProtocolTransport\n extends EventEmitter<ProtocolTransportEventMap> {\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 this.#transport.on('disconnected', () => {\n this.#clear()\n })\n }\n\n async connect(auth: any) {\n return await this.#transport.connect(auth, this.#format.contentType)\n }\n\n async disconnect() {\n this.#clear()\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 async #clear() {\n const error = new ProtocolError(\n ErrorCode.ConnectionError,\n 'Connection closed',\n )\n for (const call of this.#calls.values()) call.reject(error)\n this.#calls.clear()\n this.#serverStreams.clear(error)\n this.#clientStreams.clear(error)\n this.#rpcStreams.clear(error)\n this.#callId = 0\n this.#streamId = 0\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"],"version":3}
1
+ {"mappings":"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","names":["code: string","message?: string","data?: any","#collection","streamId: number","source: ReadableStream","metadata: ProtocolBlobMetadata","error?: Error","size: number","stream: T","chunk: ArrayBuffer","namespace: string","procedure: string","payload: any","event: string","format: BaseClientFormat","callId: number","call: ProtocolClientCall","response: OneOf<\n [{ error: BaseProtocolError }, { result: any; stream?: any }]\n >","transformer: ProtocolBaseTransformer","stream?: ProtocolServerStream","response: ProtocolRPCResponse","stream: ProtocolServerStream","options: ProtocolBaseClientCallOptions","chunk: any","stream: ProtocolServerBlobStream","payload: string","buffer: ArrayBuffer","transport: ProtocolTransport"],"sources":["../../src/client/protocol.ts"],"sourcesContent":["import {\n createPromise,\n type InteractivePromise,\n type OneOf,\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 {\n BaseProtocolError,\n ProtocolRPC,\n ProtocolRPCResponse,\n} 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 implements BaseProtocolError {\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, error?: Error) {\n const stream = this.get(streamId)\n stream.abort(error)\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 this.get(streamId).end()\n this.remove(streamId)\n }\n\n clear(error?: Error) {\n if (error) {\n for (const stream of this.#collection.values()) {\n stream.abort(error)\n }\n }\n this.#collection.clear()\n }\n}\n\nexport class ProtocolServerStreams<\n T extends ProtocolServerStream = ProtocolServerStream,\n> {\n readonly #collection = new Map<number, T>()\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: T) {\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 clear(error?: Error) {\n if (error) {\n for (const stream of this.#collection.values()) {\n stream.abort(error)\n }\n }\n this.#collection.clear()\n }\n}\n\nexport type ProtocolTransportEventMap = {\n [K in `${ServerMessageType}`]: [ArrayBuffer]\n} & {\n connected: []\n disconnected: []\n}\n\nexport interface ProtocolSendMetadata {\n callId?: number\n streamId?: number\n}\n\nexport abstract class ProtocolTransport {\n abstract connect(\n auth: any,\n transformer: ProtocolBaseTransformer,\n ): Promise<void>\n abstract disconnect(): Promise<void>\n abstract call(\n namespace: string,\n procedure: string,\n payload: any,\n options: ProtocolBaseClientCallOptions,\n transformer: ProtocolBaseTransformer,\n ): Promise<ProtocolClientCall>\n abstract send(\n messageType: ClientMessageType,\n buffer: ArrayBuffer,\n metadata: ProtocolSendMetadata,\n ): 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'> & { signal: AbortSignal }\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 class BaseProtocol<\n T extends Record<string, Record<string, any>> = Record<\n string,\n Record<string, any>\n >,\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 protected readonly clientStreams: ProtocolClientStreams =\n new ProtocolClientStreams()\n protected readonly serverStreams: ProtocolServerStreams<ProtocolServerBlobStream> =\n new ProtocolServerStreams()\n protected readonly rpcStreams: ProtocolServerStreams =\n new ProtocolServerStreams()\n protected readonly calls = new Map<number, ProtocolClientCall>()\n protected callId = 0\n protected streamId = 0\n\n constructor(public readonly format: BaseClientFormat) {\n super()\n }\n\n get contentType() {\n return this.format.contentType\n }\n\n handleCallResponse(\n callId: number,\n call: ProtocolClientCall,\n response: OneOf<\n [{ error: BaseProtocolError }, { result: any; stream?: any }]\n >,\n transformer: ProtocolBaseTransformer,\n ) {\n if (response.error) {\n call.reject(\n new ProtocolError(\n response.error.code,\n response.error.message,\n response.error.data,\n ),\n )\n } else {\n try {\n const transformed = transformer.decodeRPC(\n call.namespace,\n call.procedure,\n response.result,\n )\n if (response.stream)\n call.resolve({ result: transformed, stream: response.stream })\n else call.resolve(transformed)\n } catch (error) {\n call.reject(\n new ProtocolError(\n ErrorCode.ClientRequestError,\n 'Unable to decode response',\n error,\n ),\n )\n }\n }\n this.calls.delete(callId)\n }\n\n handleRpcResponse(\n { callId, error, result, streams }: ProtocolRPCResponse,\n transformer: ProtocolBaseTransformer,\n stream?: ProtocolServerStream,\n ) {\n const call = this.calls.get(callId)\n if (!call) throw new Error('Call not found')\n for (const key in streams) {\n const stream = streams[key]\n this.serverStreams.add(stream.id, stream)\n }\n this.handleCallResponse(\n callId,\n call,\n error ? { error } : { result, stream },\n transformer,\n )\n return call\n }\n\n handleRpcStreamResponse(\n response: ProtocolRPCResponse,\n stream: ProtocolServerStream,\n transformer: ProtocolBaseTransformer,\n ) {\n const call = this.handleRpcResponse(response, transformer, stream)\n this.rpcStreams.add(response.callId, stream)\n return call\n }\n\n createCall(\n namespace: string,\n procedure: string,\n options: ProtocolBaseClientCallOptions,\n ) {\n const timeoutSignal = AbortSignal.timeout(options.timeout)\n const signal = options.signal\n ? AbortSignal.any([options.signal, timeoutSignal])\n : timeoutSignal\n\n const call = Object.assign(createPromise(), {\n namespace,\n procedure,\n signal,\n })\n\n timeoutSignal.addEventListener(\n 'abort',\n () => {\n const error = new ProtocolError(\n ErrorCode.RequestTimeout,\n 'Request timeout',\n )\n call.reject(error)\n },\n { once: true },\n )\n\n return call\n }\n\n createRpc(\n namespace: string,\n procedure: string,\n payload: any,\n options: ProtocolBaseClientCallOptions,\n transformer: ProtocolBaseTransformer,\n ) {\n const callId = ++this.callId\n const call = this.createCall(namespace, procedure, options)\n const { buffer, streams } = this.format.encodeRPC(\n {\n callId,\n namespace,\n procedure,\n payload: transformer.encodeRPC(namespace, procedure, payload),\n },\n {\n addStream: (blob) => {\n const streamId = ++this.streamId\n return this.clientStreams.add(blob.source, streamId, blob.metadata)\n },\n getStream: (id) => {\n const stream = this.clientStreams.get(id)\n return stream\n },\n },\n )\n\n this.calls.set(callId, call)\n\n return { callId, call, streams, buffer }\n }\n\n pushRpcStream(callId: number, chunk: any) {\n this.rpcStreams.push(callId, chunk)\n }\n\n endRpcStream(callId: number) {\n this.rpcStreams.end(callId)\n }\n\n abortRpcStream(callId: number) {\n this.rpcStreams.abort(callId)\n }\n\n removeClientStream(streamId: number) {\n this.clientStreams.remove(streamId)\n }\n\n pullClientStream(streamId: number, size: number) {\n return this.clientStreams.pull(streamId, size)\n }\n\n endClientStream(streamId: number) {\n this.clientStreams.end(streamId)\n }\n\n abortClientStream(streamId: number, error?: Error) {\n this.clientStreams.abort(streamId, error)\n }\n\n addServerStream(stream: ProtocolServerBlobStream) {\n this.serverStreams.add(stream.id, stream)\n }\n\n removeServerStream(streamId: number) {\n this.serverStreams.remove(streamId)\n }\n\n pushServerStream(streamId: number, chunk: ArrayBuffer) {\n return this.serverStreams.push(streamId, chunk)\n }\n\n endServerStream(streamId: number) {\n this.serverStreams.end(streamId)\n }\n\n abortServerStream(streamId: number, error?: Error) {\n this.serverStreams.abort(streamId)\n }\n\n emitEvent(\n namespace: string,\n event: string,\n payload: string,\n transformer: ProtocolBaseTransformer,\n ) {\n const transformed = transformer.decodeEvent(namespace, event, payload)\n this.emit(`${namespace}/${event}`, transformed)\n }\n}\n\nexport class Protocol<\n T extends Record<string, Record<string, any>> = Record<\n string,\n Record<string, any>\n >,\n> extends BaseProtocol<T> {\n handleServerMessage(\n buffer: ArrayBuffer,\n transport: ProtocolTransport,\n transformer: ProtocolBaseTransformer,\n ) {\n const type = decodeNumber(buffer, 'Uint8')\n const messageBuffer = buffer.slice(Uint8Array.BYTES_PER_ELEMENT)\n if (type in ServerMessageType) {\n const messageType = type as ServerMessageType\n if (typeof ServerMessageType[messageType] !== 'undefined') {\n this[messageType](messageBuffer, transport, transformer)\n } else {\n throw new Error(`Unknown message type: ${messageType}`)\n }\n }\n }\n\n protected [ServerMessageType.Event](\n buffer: ArrayBuffer,\n transport: ProtocolTransport,\n transformer: ProtocolBaseTransformer,\n ) {\n const [namespace, event, payload] = this.format.decode(buffer)\n this.emitEvent(namespace, event, payload, transformer)\n }\n\n protected [ServerMessageType.RpcResponse](\n buffer: ArrayBuffer,\n transport: ProtocolTransport,\n transformer: ProtocolBaseTransformer,\n ) {\n const response = this.format.decodeRPC(buffer, {\n addStream: (id, callId, metadata) => {\n return new ProtocolServerBlobStream(id, metadata, {\n start: () => {\n transport.send(\n ClientMessageType.ServerStreamPull,\n encodeNumber(id, 'Uint32'),\n { callId, streamId: id },\n )\n },\n })\n },\n getStream: (id) => {\n return this.serverStreams.get(id)\n },\n })\n this.handleRpcResponse(response, transformer)\n }\n\n protected [ServerMessageType.RpcStreamResponse](\n buffer: ArrayBuffer,\n transport: ProtocolTransport,\n transformer: ProtocolBaseTransformer,\n ) {\n const response = this.format.decodeRPC(buffer, {\n addStream: (id, callId, metadata) => {\n return new ProtocolServerBlobStream(id, metadata, {\n start: () => {\n transport.send(\n ClientMessageType.ServerStreamPull,\n encodeNumber(id, 'Uint32'),\n { callId, streamId: id },\n )\n },\n })\n },\n getStream: (id) => {\n return this.serverStreams.get(id)\n },\n })\n\n const stream = new ProtocolServerStream({\n transform: (chunk, controller) => {\n const transformed = transformer.decodeRPCChunk(\n call.namespace,\n call.procedure,\n chunk,\n )\n controller.enqueue(transformed)\n },\n })\n\n const call = this.handleRpcStreamResponse(response, stream, transformer)\n }\n\n protected [ServerMessageType.RpcStreamChunk](\n buffer: ArrayBuffer,\n transport: ProtocolTransport,\n transformer: ProtocolBaseTransformer,\n ) {\n const callId = decodeNumber(buffer, 'Uint32')\n const chunk = buffer.slice(Uint32Array.BYTES_PER_ELEMENT)\n const payload = this.format.decode(chunk)\n this.pushRpcStream(callId, payload)\n }\n\n protected [ServerMessageType.RpcStreamEnd](\n buffer: ArrayBuffer,\n transport: ProtocolTransport,\n transformer: ProtocolBaseTransformer,\n ) {\n const callId = decodeNumber(buffer, 'Uint32')\n this.endRpcStream(callId)\n }\n\n protected [ServerMessageType.RpcStreamAbort](\n buffer: ArrayBuffer,\n transport: ProtocolTransport,\n transformer: ProtocolBaseTransformer,\n ) {\n const callId = decodeNumber(buffer, 'Uint32')\n this.abortRpcStream(callId)\n }\n\n protected [ServerMessageType.ServerStreamPush](\n buffer: ArrayBuffer,\n transport: ProtocolTransport,\n transformer: ProtocolBaseTransformer,\n ) {\n const streamId = decodeNumber(buffer, 'Uint32')\n const chunk = buffer.slice(Uint32Array.BYTES_PER_ELEMENT)\n this.pushServerStream(streamId, chunk)\n transport.send(\n ClientMessageType.ServerStreamPull,\n encodeNumber(streamId, 'Uint32'),\n { streamId },\n )\n }\n\n protected [ServerMessageType.ServerStreamEnd](\n buffer: ArrayBuffer,\n transport: ProtocolTransport,\n transformer: ProtocolBaseTransformer,\n ) {\n const streamId = decodeNumber(buffer, 'Uint32')\n this.endServerStream(streamId)\n }\n\n protected [ServerMessageType.ServerStreamAbort](\n buffer: ArrayBuffer,\n transport: ProtocolTransport,\n transformer: ProtocolBaseTransformer,\n ) {\n const streamId = decodeNumber(buffer, 'Uint32')\n this.abortServerStream(streamId)\n }\n\n protected [ServerMessageType.ClientStreamPull](\n buffer: ArrayBuffer,\n transport: ProtocolTransport,\n transformer: ProtocolBaseTransformer,\n ) {\n const streamId = decodeNumber(buffer, 'Uint32')\n const size = decodeNumber(buffer, 'Uint32', Uint32Array.BYTES_PER_ELEMENT)\n this.pullClientStream(streamId, size).then((chunk) => {\n if (chunk) {\n transport.send(\n ClientMessageType.ClientStreamPush,\n concat(encodeNumber(streamId, 'Uint32'), chunk),\n { streamId },\n )\n } else {\n transport.send(\n ClientMessageType.ClientStreamEnd,\n encodeNumber(streamId, 'Uint32'),\n { streamId },\n )\n this.endClientStream(streamId)\n }\n })\n }\n\n protected [ServerMessageType.ClientStreamAbort](\n buffer: ArrayBuffer,\n transport: ProtocolTransport,\n transformer: ProtocolBaseTransformer,\n ) {\n const streamId = decodeNumber(buffer, 'Uint32')\n this.abortClientStream(streamId)\n }\n}\n"],"version":3,"file":"protocol.js"}