@nmtjs/ws-client 0.1.1 → 0.1.4

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/index.js CHANGED
@@ -18,18 +18,7 @@ export class WsClientTransport extends ClientTransport {
18
18
  encodeRpcContext;
19
19
  decodeRpcContext;
20
20
  constructor(options){
21
- super();
22
- this.options = options;
23
- this.type = TransportType.WS;
24
- this.calls = new Map();
25
- this.subscriptions = new Map();
26
- this.upStreams = new Map();
27
- this.downStreams = new Map();
28
- this.upStreamId = 0;
29
- this.queryParams = {};
30
- this.isHealthy = false;
31
- this.checkHealthAttempts = 0;
32
- this.isConnected = false;
21
+ super(), this.options = options, this.type = TransportType.WS, this.calls = new Map(), this.subscriptions = new Map(), this.upStreams = new Map(), this.downStreams = new Map(), this.upStreamId = 0, this.queryParams = {}, this.isHealthy = false, this.checkHealthAttempts = 0, this.isConnected = false;
33
22
  this.autoreconnect = this.options.autoreconnect ?? true;
34
23
  if (options.wsFactory) {
35
24
  this.wsFactory = options.wsFactory;
@@ -77,6 +66,7 @@ export class WsClientTransport extends ClientTransport {
77
66
  }
78
67
  };
79
68
  this.ws.onopen = (event)=>{
69
+ if (this.options.debug) console.log(`[WS] Connected to ${this.options.origin}`);
80
70
  this.isConnected = true;
81
71
  this.emit('open');
82
72
  this.checkHealthAttempts = 0;
@@ -87,10 +77,14 @@ export class WsClientTransport extends ClientTransport {
87
77
  this.emit('close', event.code === 1000 ? undefined : new Error(`Connection closed with code ${event.code}: ${event.reason}`));
88
78
  if (this.autoreconnect) this.connect();
89
79
  };
90
- this.ws.onerror = (event)=>{
80
+ this.ws.onerror = (cause)=>{
91
81
  this.isHealthy = false;
82
+ this.emit('close', new Error('Connection error', {
83
+ cause
84
+ }));
92
85
  };
93
86
  await once(this, 'open');
87
+ if (this.options.debug) console.log(`2[WS] Connected to ${this.options.origin}`);
94
88
  this.emit('connect');
95
89
  }
96
90
  async disconnect() {
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../../index.ts"],"sourcesContent":["import {\n type ClientDownStreamWrapper,\n ClientTransport,\n type ClientTransportRpcCall,\n type ClientTransportRpcResult,\n ClientUpStream,\n Subscription,\n createClientDownStream,\n onAbort,\n once,\n} from '@nmtjs/client'\nimport {\n type DecodeRpcContext,\n type EncodeRpcContext,\n MessageType,\n MessageTypeName,\n TransportType,\n concat,\n decodeNumber,\n encodeNumber,\n} from '@nmtjs/common'\n\nexport type WsClientTransportOptions = {\n /**\n * The origin of the server\n * @example 'http://localhost:3000'\n */\n origin: string\n /**\n * Whether to autoreconnect on close\n * @default true\n */\n autoreconnect?: boolean\n /**\n * Custom WebSocket class\n * @default globalThis.WebSocket\n */\n wsFactory?: (url: URL) => WebSocket\n\n debug?: boolean\n}\n\ntype WsCall = {\n resolve: (value: ClientTransportRpcResult) => void\n reject: (error: Error) => void\n}\n\nexport class WsClientTransport extends ClientTransport<{\n open: []\n close: [Error?]\n connect: []\n healthy: []\n}> {\n readonly type = TransportType.WS\n\n protected readonly calls = new Map<number, WsCall>()\n protected readonly subscriptions = new Map<number, Subscription>()\n protected readonly upStreams = new Map<number, ClientUpStream>()\n protected readonly downStreams = new Map<number, ClientDownStreamWrapper>()\n protected upStreamId = 0\n protected queryParams = {}\n protected ws?: WebSocket\n protected isHealthy = false\n protected checkHealthAttempts = 0\n protected autoreconnect: boolean\n protected isConnected = false\n\n private wsFactory!: (url: URL) => WebSocket\n private encodeRpcContext: EncodeRpcContext\n private decodeRpcContext: DecodeRpcContext\n\n constructor(private readonly options: WsClientTransportOptions) {\n super()\n\n this.autoreconnect = this.options.autoreconnect ?? true\n\n if (options.wsFactory) {\n this.wsFactory = options.wsFactory\n } else {\n this.wsFactory = (url: URL) => new WebSocket(url.toString())\n }\n\n // TODO: wtf is this for?\n this.on('close', (error) => this.clear(error))\n\n this.encodeRpcContext = {\n addStream: (blob) => {\n const id = ++this.upStreamId\n const upstream = new ClientUpStream(id, blob)\n this.upStreams.set(id, upstream)\n return { id, metadata: blob.metadata }\n },\n getStream: (id) => this.upStreams.get(id),\n }\n\n this.decodeRpcContext = {\n addStream: (id, metadata) => {\n const downstream = createClientDownStream(metadata, () =>\n this.send(MessageType.DownStreamPull, encodeNumber(id, 'Uint32')),\n )\n this.downStreams.set(id, downstream)\n return downstream.blob\n },\n getStream: (id) => this.downStreams.get(id),\n }\n }\n\n async connect() {\n // reset default autoreconnect value\n this.autoreconnect = this.options.autoreconnect ?? true\n await this.healthCheck()\n\n this.ws = this.wsFactory(\n this.getURL('api', 'ws', {\n ...this.queryParams,\n accept: this.client.format.contentType,\n 'content-type': this.client.format.contentType,\n services: this.client.services,\n }),\n )\n\n this.ws.binaryType = 'arraybuffer'\n\n this.ws.onmessage = (event) => {\n const buffer: ArrayBuffer = event.data\n const type = decodeNumber(buffer, 'Uint8')\n const handler = this[type]\n if (handler) {\n handler.call(this, buffer.slice(Uint8Array.BYTES_PER_ELEMENT), this.ws)\n }\n }\n this.ws.onopen = (event) => {\n this.isConnected = true\n this.emit('open')\n this.checkHealthAttempts = 0\n }\n this.ws.onclose = (event) => {\n this.isConnected = false\n this.isHealthy = false\n this.emit(\n 'close',\n event.code === 1000\n ? undefined\n : new Error(\n `Connection closed with code ${event.code}: ${event.reason}`,\n ),\n )\n // FIXME: cleanup calls, streams, subscriptions\n if (this.autoreconnect) this.connect()\n }\n this.ws.onerror = (event) => {\n this.isHealthy = false\n }\n await once(this, 'open')\n this.emit('connect')\n }\n\n async disconnect(): Promise<void> {\n this.autoreconnect = false\n this.ws?.close()\n await once(this, 'close')\n }\n\n async rpc(call: ClientTransportRpcCall): Promise<ClientTransportRpcResult> {\n const { signal, callId, payload, procedure, service } = call\n\n const data = this.client.format.encodeRpc(\n {\n callId,\n service,\n procedure,\n payload,\n },\n this.encodeRpcContext,\n )\n\n onAbort(signal, () => {\n const call = this.calls.get(callId)\n if (call) {\n const { reject } = call\n reject(new Error('Request aborted'))\n this.calls.delete(callId)\n this.send(MessageType.RpcAbort, encodeNumber(callId, 'Uint32'))\n }\n })\n\n if (!this.isConnected) await once(this, 'connect')\n\n return new Promise((resolve, reject) => {\n this.calls.set(callId, { resolve, reject })\n this.send(MessageType.Rpc, data)\n })\n }\n\n setQueryParams(params: Record<string, any>) {\n this.queryParams = params\n }\n\n protected send(type: MessageType, ...payload: ArrayBuffer[]) {\n this.ws?.send(concat(encodeNumber(type, 'Uint8'), ...payload))\n if (this.options.debug) {\n console.groupCollapsed(`[WS] Sent ${MessageTypeName[type]}`)\n console.trace()\n console.groupEnd()\n }\n }\n\n protected async clear(error: Error = new Error('Connection closed')) {\n for (const call of this.calls.values()) {\n const { reject } = call\n reject(error)\n }\n\n for (const stream of this.upStreams.values()) {\n stream.reader.cancel(error)\n }\n\n for (const stream of this.downStreams.values()) {\n stream.writer.abort(error)\n }\n\n for (const subscription of this.subscriptions.values()) {\n subscription.unsubscribe()\n }\n\n this.calls.clear()\n this.upStreams.clear()\n this.downStreams.clear()\n this.subscriptions.clear()\n }\n\n protected async healthCheck() {\n while (!this.isHealthy) {\n try {\n const signal = AbortSignal.timeout(10000)\n const url = this.getURL('healthy', 'http', {\n auth: this.client.auth,\n })\n const { ok } = await fetch(url, { signal })\n this.isHealthy = ok\n } catch (e) {}\n\n if (!this.isHealthy) {\n this.checkHealthAttempts++\n const seconds = Math.min(this.checkHealthAttempts, 15)\n await new Promise((r) => setTimeout(r, seconds * 1000))\n }\n }\n this.emit('healthy')\n }\n\n private getURL(\n path = '',\n protocol: 'ws' | 'http',\n params: Record<string, any> = {},\n ) {\n // TODO: add custom path support?\n const base = new URL(this.options.origin)\n const secure = base.protocol === 'https:'\n const url = new URL(\n `${secure ? protocol + 's' : protocol}://${base.host}/${path}`,\n )\n for (let [key, values] of Object.entries(params)) {\n if (!Array.isArray(values)) values = [values]\n for (const value of values) {\n url.searchParams.append(key, value)\n }\n }\n return url\n }\n\n protected resolveRpc(callId: number, value: ClientTransportRpcResult) {\n const call = this.calls.get(callId)\n if (call) {\n const { resolve } = call\n this.calls.delete(callId)\n resolve(value)\n }\n }\n\n protected async [MessageType.Event](buffer: ArrayBuffer) {\n const [service, event, payload] = this.client.format.decode(buffer)\n if (this.options.debug) {\n console.groupCollapsed(`[WS] Received \"Event\" ${service}/${event}`)\n console.log(payload)\n console.groupEnd()\n }\n this.emit('event', service, event, payload)\n }\n\n protected async [MessageType.Rpc](buffer: ArrayBuffer) {\n const { callId, error, payload } = this.client.format.decodeRpc(\n buffer,\n this.decodeRpcContext,\n )\n\n if (this.calls.has(callId)) {\n this.resolveRpc(\n callId,\n error ? { success: false, error } : { success: true, value: payload },\n )\n }\n }\n\n protected async [MessageType.UpStreamPull](buffer: ArrayBuffer) {\n const id = decodeNumber(buffer, 'Uint32')\n const size = decodeNumber(buffer, 'Uint32', Uint32Array.BYTES_PER_ELEMENT)\n\n if (this.options.debug) {\n console.log(`[WS] Received \"UpStreamPull\" ${id}`)\n }\n\n const stream = this.upStreams.get(id)\n if (stream) {\n const buf = new Uint8Array(new ArrayBuffer(size))\n const { done, value } = await stream.reader.read(buf)\n if (done) {\n this.send(MessageType.UpStreamEnd, encodeNumber(id, 'Uint32'))\n } else {\n this.send(\n MessageType.UpStreamPush,\n concat(\n encodeNumber(id, 'Uint32'),\n value.buffer.slice(0, value.byteLength),\n ),\n )\n }\n }\n }\n\n protected async [MessageType.UpStreamEnd](buffer: ArrayBuffer) {\n const id = decodeNumber(buffer, 'Uint32')\n if (this.options.debug) {\n console.log(`[WS] Received \"UpStreamEnd\" ${id}`)\n }\n const stream = this.upStreams.get(id)\n if (stream) {\n stream.reader.cancel()\n this.upStreams.delete(id)\n }\n }\n\n protected [MessageType.UpStreamAbort](buffer: ArrayBuffer) {\n const id = decodeNumber(buffer, 'Uint32')\n if (this.options.debug) {\n console.log(`[WS] Received \"UpStreamAbort\" ${id}`)\n }\n const stream = this.upStreams.get(id)\n if (stream) {\n try {\n stream.reader.cancel(new Error('Aborted by server'))\n } finally {\n this.upStreams.delete(id)\n }\n }\n }\n\n protected async [MessageType.DownStreamPush](buffer: ArrayBuffer) {\n const id = decodeNumber(buffer, 'Uint32')\n if (this.options.debug) {\n console.log(`[WS] Received \"DownStreamPush\" ${id}`)\n }\n const stream = this.downStreams.get(id)\n if (stream) {\n try {\n await stream.writer.ready\n const chunk = buffer.slice(Uint32Array.BYTES_PER_ELEMENT)\n await stream.writer.write(new Uint8Array(chunk))\n await stream.writer.ready\n this.send(MessageType.DownStreamPull, encodeNumber(id, 'Uint32'))\n } catch (e) {\n this.send(MessageType.DownStreamAbort, encodeNumber(id, 'Uint32'))\n this.downStreams.delete(id)\n }\n }\n }\n\n protected async [MessageType.DownStreamEnd](buffer: ArrayBuffer) {\n const id = decodeNumber(buffer, 'Uint32')\n if (this.options.debug) {\n console.log(`[WS] Received \"DownStreamEnd\" ${id}`)\n }\n const stream = this.downStreams.get(id)\n if (stream) {\n this.downStreams.delete(id)\n stream.writer.close().catch(() => {})\n }\n }\n\n protected async [MessageType.DownStreamAbort](buffer: ArrayBuffer) {\n const id = decodeNumber(buffer, 'Uint32')\n if (this.options.debug) {\n console.log(`[WS] Received \"DownStreamAbort\" ${id}`)\n }\n const stream = this.downStreams.get(id)\n if (stream) {\n this.downStreams.delete(id)\n stream.writer.abort(new Error('Aborted by server')).catch(() => {})\n }\n }\n\n protected [MessageType.RpcSubscription](buffer: ArrayBuffer) {\n const {\n callId,\n payload: [key, payload],\n } = this.client.format.decodeRpc(buffer, this.decodeRpcContext)\n if (this.calls.has(callId)) {\n const subscription = new Subscription(key, () => {\n subscription.emit('end')\n this.subscriptions.delete(key)\n this.send(\n MessageType.ClientUnsubscribe,\n this.client.format.encode([key]),\n )\n })\n this.subscriptions.set(key, subscription)\n this.resolveRpc(callId, {\n success: true,\n value: { payload, subscription },\n })\n }\n }\n\n protected [MessageType.ServerSubscriptionEvent](buffer: ArrayBuffer) {\n const [key, event, payload] = this.client.format.decode(buffer)\n if (this.options.debug) {\n console.groupCollapsed(\n `[WS] Received \"ServerSubscriptionEvent\" ${key}/${event}`,\n )\n console.log(payload)\n console.groupEnd()\n }\n const subscription = this.subscriptions.get(key)\n if (subscription) subscription.emit(event, payload)\n }\n\n protected [MessageType.ServerUnsubscribe](buffer: ArrayBuffer) {\n const [key] = this.client.format.decode(buffer)\n if (this.options.debug) {\n console.log(`[WS] Received \"ServerUnsubscribe\" ${key}`)\n }\n const subscription = this.subscriptions.get(key)\n subscription?.emit('end')\n this.subscriptions.delete(key)\n }\n}\n"],"names":["ClientTransport","ClientUpStream","Subscription","createClientDownStream","onAbort","once","MessageType","MessageTypeName","TransportType","concat","decodeNumber","encodeNumber","WsClientTransport","type","calls","subscriptions","upStreams","downStreams","upStreamId","queryParams","ws","isHealthy","checkHealthAttempts","autoreconnect","isConnected","wsFactory","encodeRpcContext","decodeRpcContext","constructor","options","WS","Map","url","WebSocket","toString","on","error","clear","addStream","blob","id","upstream","set","metadata","getStream","get","downstream","send","DownStreamPull","connect","healthCheck","getURL","accept","client","format","contentType","services","binaryType","onmessage","event","buffer","data","handler","call","slice","Uint8Array","BYTES_PER_ELEMENT","onopen","emit","onclose","code","undefined","Error","reason","onerror","disconnect","close","rpc","signal","callId","payload","procedure","service","encodeRpc","reject","delete","RpcAbort","Promise","resolve","Rpc","setQueryParams","params","debug","console","groupCollapsed","trace","groupEnd","values","stream","reader","cancel","writer","abort","subscription","unsubscribe","AbortSignal","timeout","auth","ok","fetch","e","seconds","Math","min","r","setTimeout","path","protocol","base","URL","origin","secure","host","key","Object","entries","Array","isArray","value","searchParams","append","resolveRpc","Event","decode","log","decodeRpc","has","success","UpStreamPull","size","Uint32Array","buf","ArrayBuffer","done","read","UpStreamEnd","UpStreamPush","byteLength","UpStreamAbort","DownStreamPush","ready","chunk","write","DownStreamAbort","DownStreamEnd","catch","RpcSubscription","ClientUnsubscribe","encode","ServerSubscriptionEvent","ServerUnsubscribe"],"mappings":"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"}
1
+ {"version":3,"sources":["../../index.ts"],"sourcesContent":["import {\n type ClientDownStreamWrapper,\n ClientTransport,\n type ClientTransportRpcCall,\n type ClientTransportRpcResult,\n ClientUpStream,\n Subscription,\n createClientDownStream,\n onAbort,\n once,\n} from '@nmtjs/client'\nimport {\n type DecodeRpcContext,\n type EncodeRpcContext,\n MessageType,\n MessageTypeName,\n TransportType,\n concat,\n decodeNumber,\n encodeNumber,\n} from '@nmtjs/common'\n\nexport type WsClientTransportOptions = {\n /**\n * The origin of the server\n * @example 'http://localhost:3000'\n */\n origin: string\n /**\n * Whether to autoreconnect on close\n * @default true\n */\n autoreconnect?: boolean\n /**\n * Custom WebSocket class\n * @default globalThis.WebSocket\n */\n wsFactory?: (url: URL) => WebSocket\n\n debug?: boolean\n}\n\ntype WsCall = {\n resolve: (value: ClientTransportRpcResult) => void\n reject: (error: Error) => void\n}\n\nexport class WsClientTransport extends ClientTransport<{\n open: []\n close: [Error?]\n connect: []\n healthy: []\n}> {\n readonly type = TransportType.WS\n\n protected readonly calls = new Map<number, WsCall>()\n protected readonly subscriptions = new Map<number, Subscription>()\n protected readonly upStreams = new Map<number, ClientUpStream>()\n protected readonly downStreams = new Map<number, ClientDownStreamWrapper>()\n protected upStreamId = 0\n protected queryParams = {}\n protected ws?: WebSocket\n protected isHealthy = false\n protected checkHealthAttempts = 0\n protected autoreconnect: boolean\n protected isConnected = false\n\n private wsFactory!: (url: URL) => WebSocket\n private encodeRpcContext: EncodeRpcContext\n private decodeRpcContext: DecodeRpcContext\n\n constructor(private readonly options: WsClientTransportOptions) {\n super()\n\n this.autoreconnect = this.options.autoreconnect ?? true\n\n if (options.wsFactory) {\n this.wsFactory = options.wsFactory\n } else {\n this.wsFactory = (url: URL) => new WebSocket(url.toString())\n }\n\n // TODO: wtf is this for?\n this.on('close', (error) => this.clear(error))\n\n this.encodeRpcContext = {\n addStream: (blob) => {\n const id = ++this.upStreamId\n const upstream = new ClientUpStream(id, blob)\n this.upStreams.set(id, upstream)\n return { id, metadata: blob.metadata }\n },\n getStream: (id) => this.upStreams.get(id),\n }\n\n this.decodeRpcContext = {\n addStream: (id, metadata) => {\n const downstream = createClientDownStream(metadata, () =>\n this.send(MessageType.DownStreamPull, encodeNumber(id, 'Uint32')),\n )\n this.downStreams.set(id, downstream)\n return downstream.blob\n },\n getStream: (id) => this.downStreams.get(id),\n }\n }\n\n async connect() {\n // reset default autoreconnect value\n this.autoreconnect = this.options.autoreconnect ?? true\n await this.healthCheck()\n\n this.ws = this.wsFactory(\n this.getURL('api', 'ws', {\n ...this.queryParams,\n accept: this.client.format.contentType,\n 'content-type': this.client.format.contentType,\n services: this.client.services,\n }),\n )\n\n this.ws.binaryType = 'arraybuffer'\n\n this.ws.onmessage = (event) => {\n const buffer: ArrayBuffer = event.data\n const type = decodeNumber(buffer, 'Uint8')\n const handler = this[type]\n if (handler) {\n handler.call(this, buffer.slice(Uint8Array.BYTES_PER_ELEMENT), this.ws)\n }\n }\n this.ws.onopen = (event) => {\n if (this.options.debug)\n console.log(`[WS] Connected to ${this.options.origin}`)\n this.isConnected = true\n this.emit('open')\n this.checkHealthAttempts = 0\n }\n this.ws.onclose = (event) => {\n this.isConnected = false\n this.isHealthy = false\n this.emit(\n 'close',\n event.code === 1000\n ? undefined\n : new Error(\n `Connection closed with code ${event.code}: ${event.reason}`,\n ),\n )\n // FIXME: cleanup calls, streams, subscriptions\n if (this.autoreconnect) this.connect()\n }\n this.ws.onerror = (cause) => {\n this.isHealthy = false\n this.emit('close', new Error('Connection error', { cause }))\n }\n await once(this, 'open')\n if (this.options.debug)\n console.log(`2[WS] Connected to ${this.options.origin}`)\n this.emit('connect')\n }\n\n async disconnect(): Promise<void> {\n this.autoreconnect = false\n this.ws?.close()\n await once(this, 'close')\n }\n\n async rpc(call: ClientTransportRpcCall): Promise<ClientTransportRpcResult> {\n const { signal, callId, payload, procedure, service } = call\n\n const data = this.client.format.encodeRpc(\n {\n callId,\n service,\n procedure,\n payload,\n },\n this.encodeRpcContext,\n )\n\n onAbort(signal, () => {\n const call = this.calls.get(callId)\n if (call) {\n const { reject } = call\n reject(new Error('Request aborted'))\n this.calls.delete(callId)\n this.send(MessageType.RpcAbort, encodeNumber(callId, 'Uint32'))\n }\n })\n\n if (!this.isConnected) await once(this, 'connect')\n\n return new Promise((resolve, reject) => {\n this.calls.set(callId, { resolve, reject })\n this.send(MessageType.Rpc, data)\n })\n }\n\n setQueryParams(params: Record<string, any>) {\n this.queryParams = params\n }\n\n protected send(type: MessageType, ...payload: ArrayBuffer[]) {\n this.ws?.send(concat(encodeNumber(type, 'Uint8'), ...payload))\n if (this.options.debug) {\n console.groupCollapsed(`[WS] Sent ${MessageTypeName[type]}`)\n console.trace()\n console.groupEnd()\n }\n }\n\n protected async clear(error: Error = new Error('Connection closed')) {\n for (const call of this.calls.values()) {\n const { reject } = call\n reject(error)\n }\n\n for (const stream of this.upStreams.values()) {\n stream.reader.cancel(error)\n }\n\n for (const stream of this.downStreams.values()) {\n stream.writer.abort(error)\n }\n\n for (const subscription of this.subscriptions.values()) {\n subscription.unsubscribe()\n }\n\n this.calls.clear()\n this.upStreams.clear()\n this.downStreams.clear()\n this.subscriptions.clear()\n }\n\n protected async healthCheck() {\n while (!this.isHealthy) {\n try {\n const signal = AbortSignal.timeout(10000)\n const url = this.getURL('healthy', 'http', {\n auth: this.client.auth,\n })\n const { ok } = await fetch(url, { signal })\n this.isHealthy = ok\n } catch (e) {}\n\n if (!this.isHealthy) {\n this.checkHealthAttempts++\n const seconds = Math.min(this.checkHealthAttempts, 15)\n await new Promise((r) => setTimeout(r, seconds * 1000))\n }\n }\n this.emit('healthy')\n }\n\n private getURL(\n path = '',\n protocol: 'ws' | 'http',\n params: Record<string, any> = {},\n ) {\n // TODO: add custom path support?\n const base = new URL(this.options.origin)\n const secure = base.protocol === 'https:'\n const url = new URL(\n `${secure ? protocol + 's' : protocol}://${base.host}/${path}`,\n )\n for (let [key, values] of Object.entries(params)) {\n if (!Array.isArray(values)) values = [values]\n for (const value of values) {\n url.searchParams.append(key, value)\n }\n }\n return url\n }\n\n protected resolveRpc(callId: number, value: ClientTransportRpcResult) {\n const call = this.calls.get(callId)\n if (call) {\n const { resolve } = call\n this.calls.delete(callId)\n resolve(value)\n }\n }\n\n protected async [MessageType.Event](buffer: ArrayBuffer) {\n const [service, event, payload] = this.client.format.decode(buffer)\n if (this.options.debug) {\n console.groupCollapsed(`[WS] Received \"Event\" ${service}/${event}`)\n console.log(payload)\n console.groupEnd()\n }\n this.emit('event', service, event, payload)\n }\n\n protected async [MessageType.Rpc](buffer: ArrayBuffer) {\n const { callId, error, payload } = this.client.format.decodeRpc(\n buffer,\n this.decodeRpcContext,\n )\n\n if (this.calls.has(callId)) {\n this.resolveRpc(\n callId,\n error ? { success: false, error } : { success: true, value: payload },\n )\n }\n }\n\n protected async [MessageType.UpStreamPull](buffer: ArrayBuffer) {\n const id = decodeNumber(buffer, 'Uint32')\n const size = decodeNumber(buffer, 'Uint32', Uint32Array.BYTES_PER_ELEMENT)\n\n if (this.options.debug) {\n console.log(`[WS] Received \"UpStreamPull\" ${id}`)\n }\n\n const stream = this.upStreams.get(id)\n if (stream) {\n const buf = new Uint8Array(new ArrayBuffer(size))\n const { done, value } = await stream.reader.read(buf)\n if (done) {\n this.send(MessageType.UpStreamEnd, encodeNumber(id, 'Uint32'))\n } else {\n this.send(\n MessageType.UpStreamPush,\n concat(\n encodeNumber(id, 'Uint32'),\n value.buffer.slice(0, value.byteLength),\n ),\n )\n }\n }\n }\n\n protected async [MessageType.UpStreamEnd](buffer: ArrayBuffer) {\n const id = decodeNumber(buffer, 'Uint32')\n if (this.options.debug) {\n console.log(`[WS] Received \"UpStreamEnd\" ${id}`)\n }\n const stream = this.upStreams.get(id)\n if (stream) {\n stream.reader.cancel()\n this.upStreams.delete(id)\n }\n }\n\n protected [MessageType.UpStreamAbort](buffer: ArrayBuffer) {\n const id = decodeNumber(buffer, 'Uint32')\n if (this.options.debug) {\n console.log(`[WS] Received \"UpStreamAbort\" ${id}`)\n }\n const stream = this.upStreams.get(id)\n if (stream) {\n try {\n stream.reader.cancel(new Error('Aborted by server'))\n } finally {\n this.upStreams.delete(id)\n }\n }\n }\n\n protected async [MessageType.DownStreamPush](buffer: ArrayBuffer) {\n const id = decodeNumber(buffer, 'Uint32')\n if (this.options.debug) {\n console.log(`[WS] Received \"DownStreamPush\" ${id}`)\n }\n const stream = this.downStreams.get(id)\n if (stream) {\n try {\n await stream.writer.ready\n const chunk = buffer.slice(Uint32Array.BYTES_PER_ELEMENT)\n await stream.writer.write(new Uint8Array(chunk))\n await stream.writer.ready\n this.send(MessageType.DownStreamPull, encodeNumber(id, 'Uint32'))\n } catch (e) {\n this.send(MessageType.DownStreamAbort, encodeNumber(id, 'Uint32'))\n this.downStreams.delete(id)\n }\n }\n }\n\n protected async [MessageType.DownStreamEnd](buffer: ArrayBuffer) {\n const id = decodeNumber(buffer, 'Uint32')\n if (this.options.debug) {\n console.log(`[WS] Received \"DownStreamEnd\" ${id}`)\n }\n const stream = this.downStreams.get(id)\n if (stream) {\n this.downStreams.delete(id)\n stream.writer.close().catch(() => {})\n }\n }\n\n protected async [MessageType.DownStreamAbort](buffer: ArrayBuffer) {\n const id = decodeNumber(buffer, 'Uint32')\n if (this.options.debug) {\n console.log(`[WS] Received \"DownStreamAbort\" ${id}`)\n }\n const stream = this.downStreams.get(id)\n if (stream) {\n this.downStreams.delete(id)\n stream.writer.abort(new Error('Aborted by server')).catch(() => {})\n }\n }\n\n protected [MessageType.RpcSubscription](buffer: ArrayBuffer) {\n const {\n callId,\n payload: [key, payload],\n } = this.client.format.decodeRpc(buffer, this.decodeRpcContext)\n if (this.calls.has(callId)) {\n const subscription = new Subscription(key, () => {\n subscription.emit('end')\n this.subscriptions.delete(key)\n this.send(\n MessageType.ClientUnsubscribe,\n this.client.format.encode([key]),\n )\n })\n this.subscriptions.set(key, subscription)\n this.resolveRpc(callId, {\n success: true,\n value: { payload, subscription },\n })\n }\n }\n\n protected [MessageType.ServerSubscriptionEvent](buffer: ArrayBuffer) {\n const [key, event, payload] = this.client.format.decode(buffer)\n if (this.options.debug) {\n console.groupCollapsed(\n `[WS] Received \"ServerSubscriptionEvent\" ${key}/${event}`,\n )\n console.log(payload)\n console.groupEnd()\n }\n const subscription = this.subscriptions.get(key)\n if (subscription) subscription.emit(event, payload)\n }\n\n protected [MessageType.ServerUnsubscribe](buffer: ArrayBuffer) {\n const [key] = this.client.format.decode(buffer)\n if (this.options.debug) {\n console.log(`[WS] Received \"ServerUnsubscribe\" ${key}`)\n }\n const subscription = this.subscriptions.get(key)\n subscription?.emit('end')\n this.subscriptions.delete(key)\n }\n}\n"],"names":["ClientTransport","ClientUpStream","Subscription","createClientDownStream","onAbort","once","MessageType","MessageTypeName","TransportType","concat","decodeNumber","encodeNumber","WsClientTransport","type","calls","subscriptions","upStreams","downStreams","upStreamId","queryParams","ws","isHealthy","checkHealthAttempts","autoreconnect","isConnected","wsFactory","encodeRpcContext","decodeRpcContext","constructor","options","WS","Map","url","WebSocket","toString","on","error","clear","addStream","blob","id","upstream","set","metadata","getStream","get","downstream","send","DownStreamPull","connect","healthCheck","getURL","accept","client","format","contentType","services","binaryType","onmessage","event","buffer","data","handler","call","slice","Uint8Array","BYTES_PER_ELEMENT","onopen","debug","console","log","origin","emit","onclose","code","undefined","Error","reason","onerror","cause","disconnect","close","rpc","signal","callId","payload","procedure","service","encodeRpc","reject","delete","RpcAbort","Promise","resolve","Rpc","setQueryParams","params","groupCollapsed","trace","groupEnd","values","stream","reader","cancel","writer","abort","subscription","unsubscribe","AbortSignal","timeout","auth","ok","fetch","e","seconds","Math","min","r","setTimeout","path","protocol","base","URL","secure","host","key","Object","entries","Array","isArray","value","searchParams","append","resolveRpc","Event","decode","decodeRpc","has","success","UpStreamPull","size","Uint32Array","buf","ArrayBuffer","done","read","UpStreamEnd","UpStreamPush","byteLength","UpStreamAbort","DownStreamPush","ready","chunk","write","DownStreamAbort","DownStreamEnd","catch","RpcSubscription","ClientUnsubscribe","encode","ServerSubscriptionEvent","ServerUnsubscribe"],"mappings":"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"}
package/index.ts CHANGED
@@ -130,6 +130,8 @@ export class WsClientTransport extends ClientTransport<{
130
130
  }
131
131
  }
132
132
  this.ws.onopen = (event) => {
133
+ if (this.options.debug)
134
+ console.log(`[WS] Connected to ${this.options.origin}`)
133
135
  this.isConnected = true
134
136
  this.emit('open')
135
137
  this.checkHealthAttempts = 0
@@ -148,10 +150,13 @@ export class WsClientTransport extends ClientTransport<{
148
150
  // FIXME: cleanup calls, streams, subscriptions
149
151
  if (this.autoreconnect) this.connect()
150
152
  }
151
- this.ws.onerror = (event) => {
153
+ this.ws.onerror = (cause) => {
152
154
  this.isHealthy = false
155
+ this.emit('close', new Error('Connection error', { cause }))
153
156
  }
154
157
  await once(this, 'open')
158
+ if (this.options.debug)
159
+ console.log(`2[WS] Connected to ${this.options.origin}`)
155
160
  this.emit('connect')
156
161
  }
157
162
 
package/package.json CHANGED
@@ -1,14 +1,19 @@
1
1
  {
2
2
  "name": "@nmtjs/ws-client",
3
3
  "type": "module",
4
- "module": "./dist/index.js",
4
+ "exports": {
5
+ ".": {
6
+ "import": "./dist/index.js",
7
+ "types": "./index.ts"
8
+ }
9
+ },
5
10
  "peerDependencies": {
6
- "@nmtjs/common": "^0.2.1",
7
- "@nmtjs/client": "^0.2.1"
11
+ "@nmtjs/common": "^0.3.8",
12
+ "@nmtjs/client": "^0.3.8"
8
13
  },
9
14
  "devDependencies": {
10
- "@nmtjs/common": "^0.2.1",
11
- "@nmtjs/client": "^0.2.1"
15
+ "@nmtjs/common": "^0.3.8",
16
+ "@nmtjs/client": "^0.3.8"
12
17
  },
13
18
  "files": [
14
19
  "index.ts",
@@ -17,10 +22,9 @@
17
22
  "LICENSE.md",
18
23
  "README.md"
19
24
  ],
20
- "version": "0.1.1",
25
+ "version": "0.1.4",
21
26
  "scripts": {
22
27
  "build": "neemata-build -p neutral ./index.ts",
23
28
  "type-check": "tsc --noEmit"
24
- },
25
- "types": "./index.ts"
29
+ }
26
30
  }