@nmtjs/ws-client 0.8.1 → 0.10.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.
- package/dist/index.js +36 -30
- package/dist/index.js.map +1 -1
- package/package.json +7 -7
- package/src/index.ts +52 -45
package/dist/index.js
CHANGED
|
@@ -1,53 +1,57 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
export class WebSocketClientTransport extends
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
constructor(options) {
|
|
1
|
+
import { ClientMessageType, concat, encodeNumber } from "@nmtjs/protocol";
|
|
2
|
+
import { ProtocolTransport } from "@nmtjs/protocol/client";
|
|
3
|
+
export class WebSocketClientTransport extends ProtocolTransport {
|
|
4
|
+
webSocket = null;
|
|
5
|
+
connecting = null;
|
|
6
|
+
constructor(protocol, options) {
|
|
7
7
|
super();
|
|
8
|
+
this.protocol = protocol;
|
|
8
9
|
this.options = options;
|
|
9
10
|
}
|
|
10
|
-
connect(auth
|
|
11
|
-
const wsUrl = new URL(this.options.origin);
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
11
|
+
connect(auth, transformer) {
|
|
12
|
+
const wsUrl = new URL("/api", this.options.origin);
|
|
13
|
+
if (this.protocol.contentType) {
|
|
14
|
+
wsUrl.searchParams.set("content-type", this.protocol.contentType);
|
|
15
|
+
wsUrl.searchParams.set("accept", this.protocol.contentType);
|
|
16
|
+
}
|
|
16
17
|
if (auth) wsUrl.searchParams.set("auth", auth);
|
|
17
18
|
const ws = this.options.wsFactory?.(wsUrl) ?? new WebSocket(wsUrl.toString());
|
|
18
19
|
ws.binaryType = "arraybuffer";
|
|
19
20
|
ws.addEventListener("message", ({ data }) => {
|
|
20
|
-
|
|
21
|
-
const type = decodeNumber(buffer, "Uint8");
|
|
22
|
-
if (type in ServerMessageType) {
|
|
23
|
-
this.emit(`${type}`, buffer.slice(Uint8Array.BYTES_PER_ELEMENT));
|
|
24
|
-
}
|
|
21
|
+
this.protocol.handleServerMessage(data, this, transformer);
|
|
25
22
|
});
|
|
26
|
-
this
|
|
27
|
-
this
|
|
23
|
+
this.webSocket = ws;
|
|
24
|
+
this.connecting = new Promise((resolve, reject) => {
|
|
28
25
|
ws.addEventListener("open", () => {
|
|
29
|
-
this.emit("connected");
|
|
26
|
+
this.protocol.emit("connected");
|
|
30
27
|
resolve();
|
|
31
28
|
}, { once: true });
|
|
32
|
-
ws.addEventListener("error", (event) =>
|
|
29
|
+
ws.addEventListener("error", (event) => {
|
|
30
|
+
reject(new Error("WebSocket error", { cause: event }));
|
|
31
|
+
}, { once: true });
|
|
33
32
|
ws.addEventListener("close", (event) => {
|
|
34
|
-
this.emit("disconnected");
|
|
35
|
-
this
|
|
33
|
+
this.protocol.emit("disconnected");
|
|
34
|
+
this.webSocket = null;
|
|
36
35
|
if (this.options.autoreconnect === true) {
|
|
37
|
-
setTimeout(
|
|
36
|
+
setTimeout(this.connect.bind(this), 1e3);
|
|
38
37
|
}
|
|
39
38
|
}, { once: true });
|
|
40
39
|
});
|
|
41
|
-
return this
|
|
40
|
+
return this.connecting;
|
|
42
41
|
}
|
|
43
42
|
async disconnect() {
|
|
44
|
-
if (this
|
|
45
|
-
this
|
|
46
|
-
return _once(this
|
|
43
|
+
if (this.webSocket === null) return;
|
|
44
|
+
this.webSocket.close();
|
|
45
|
+
return _once(this.webSocket, "close");
|
|
46
|
+
}
|
|
47
|
+
async call(namespace, procedure, payload, options, transformer) {
|
|
48
|
+
const { call, buffer } = this.protocol.createRpc(namespace, procedure, payload, options, transformer);
|
|
49
|
+
await this.send(ClientMessageType.Rpc, buffer);
|
|
50
|
+
return call;
|
|
47
51
|
}
|
|
48
52
|
async send(messageType, buffer) {
|
|
49
|
-
if (this
|
|
50
|
-
this
|
|
53
|
+
if (this.connecting) await this.connecting;
|
|
54
|
+
this.webSocket.send(concat(encodeNumber(messageType, "Uint8"), buffer));
|
|
51
55
|
}
|
|
52
56
|
}
|
|
53
57
|
function _once(target, event) {
|
|
@@ -55,3 +59,5 @@ function _once(target, event) {
|
|
|
55
59
|
target.addEventListener(event, () => resolve(), { once: true });
|
|
56
60
|
});
|
|
57
61
|
}
|
|
62
|
+
|
|
63
|
+
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"mappings":"AAAA,
|
|
1
|
+
{"mappings":"AAAA,SAAS,mBAAmB,QAAQ,oBAAoB,iBAAiB;AACzE,SAIE,yBACK,wBAAwB;AAsB/B,OAAO,MAAM,iCAAiC,kBAAkB;CAC9D,AAAU,YAA8B;CACxC,AAAU,aAAmC;CAE7C,YACqBA,UACAC,SACnB;AACA,SAAO;OAHY;OACA;CAGpB;CAED,QAAQC,MAAWC,aAAqD;EACtE,MAAM,QAAQ,IAAI,IAAI,QAAQ,KAAK,QAAQ;AAC3C,MAAI,KAAK,SAAS,aAAa;AAC7B,SAAM,aAAa,IAAI,gBAAgB,KAAK,SAAS,YAAY;AACjE,SAAM,aAAa,IAAI,UAAU,KAAK,SAAS,YAAY;EAC5D;AACD,MAAI,KAAM,OAAM,aAAa,IAAI,QAAQ,KAAK;EAE9C,MAAM,KACJ,KAAK,QAAQ,YAAY,MAAM,IAAI,IAAI,UAAU,MAAM,UAAU;AAEnE,KAAG,aAAa;AAEhB,KAAG,iBAAiB,WAAW,CAAC,EAAE,MAAM,KAAK;AAC3C,QAAK,SAAS,oBAAoB,MAAqB,MAAM,YAAY;EAC1E,EAAC;AAEF,OAAK,YAAY;AAEjB,OAAK,aAAa,IAAI,QAAQ,CAAC,SAAS,WAAW;AACjD,MAAG,iBACD,QACA,MAAM;AACJ,SAAK,SAAS,KAAK,YAAY;AAC/B,aAAS;GACV,GACD,EAAE,MAAM,KAAM,EACf;AAED,MAAG,iBACD,SACA,CAAC,UAAU;AACT,WAAO,IAAI,MAAM,mBAAmB,EAAE,OAAO,MAAO,GAAE;GACvD,GACD,EAAE,MAAM,KAAM,EACf;AAED,MAAG,iBACD,SACA,CAAC,UAAU;AACT,SAAK,SAAS,KAAK,eAAe;AAClC,SAAK,YAAY;AACjB,QAAI,KAAK,QAAQ,kBAAkB,MAAM;AACvC,gBAAW,KAAK,QAAQ,KAAK,KAAK,EAAE,IAAK;IAC1C;GACF,GACD,EAAE,MAAM,KAAM,EACf;EACF;AAED,SAAO,KAAK;CACb;CAED,MAAM,aAA4B;AAChC,MAAI,KAAK,cAAc,KAAM;AAC7B,OAAK,UAAW,OAAO;AACvB,SAAO,MAAM,KAAK,WAAW,QAAQ;CACtC;CAED,MAAM,KACJC,WACAC,WACAC,SACAC,SACAJ,aACA;EACA,MAAM,EAAE,MAAM,QAAQ,GAAG,KAAK,SAAS,UACrC,WACA,WACA,SACA,SACA,YACD;AACD,QAAM,KAAK,KAAK,kBAAkB,KAAK,OAAO;AAC9C,SAAO;CACR;CAED,MAAM,KACJK,aACAC,QACe;AACf,MAAI,KAAK,WAAY,OAAM,KAAK;AAChC,OAAK,UAAW,KAAK,OAAO,aAAa,aAAa,QAAQ,EAAE,OAAO,CAAC;CACzE;AACF;AAED,SAAS,MAAMC,QAAqBC,OAAe;AACjD,QAAO,IAAI,QAAc,CAAC,YAAY;AACpC,SAAO,iBAAiB,OAAO,MAAM,SAAS,EAAE,EAAE,MAAM,KAAM,EAAC;CAChE;AACF","names":["protocol: Protocol","options: WebSocketClientTransportOptions","auth: any","transformer: ProtocolBaseTransformer","namespace: string","procedure: string","payload: any","options: ProtocolBaseClientCallOptions","messageType: ClientMessageType","buffer: ArrayBuffer","target: EventTarget","event: string"],"sources":["../src/index.ts"],"sourcesContent":["import { ClientMessageType, concat, encodeNumber } from '@nmtjs/protocol'\nimport {\n type Protocol,\n type ProtocolBaseClientCallOptions,\n type ProtocolBaseTransformer,\n ProtocolTransport,\n} from '@nmtjs/protocol/client'\n\nexport type WebSocketClientTransportOptions = {\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\nexport class WebSocketClientTransport extends ProtocolTransport {\n protected webSocket: WebSocket | null = null\n protected connecting: Promise<void> | null = null\n\n constructor(\n protected readonly protocol: Protocol,\n protected readonly options: WebSocketClientTransportOptions,\n ) {\n super()\n }\n\n connect(auth: any, transformer: ProtocolBaseTransformer): Promise<void> {\n const wsUrl = new URL('/api', this.options.origin)\n if (this.protocol.contentType) {\n wsUrl.searchParams.set('content-type', this.protocol.contentType)\n wsUrl.searchParams.set('accept', this.protocol.contentType)\n }\n if (auth) wsUrl.searchParams.set('auth', auth)\n\n const ws =\n this.options.wsFactory?.(wsUrl) ?? new WebSocket(wsUrl.toString())\n\n ws.binaryType = 'arraybuffer'\n\n ws.addEventListener('message', ({ data }) => {\n this.protocol.handleServerMessage(data as ArrayBuffer, this, transformer)\n })\n\n this.webSocket = ws\n\n this.connecting = new Promise((resolve, reject) => {\n ws.addEventListener(\n 'open',\n () => {\n this.protocol.emit('connected')\n resolve()\n },\n { once: true },\n )\n\n ws.addEventListener(\n 'error',\n (event) => {\n reject(new Error('WebSocket error', { cause: event }))\n },\n { once: true },\n )\n\n ws.addEventListener(\n 'close',\n (event) => {\n this.protocol.emit('disconnected')\n this.webSocket = null\n if (this.options.autoreconnect === true) {\n setTimeout(this.connect.bind(this), 1000)\n }\n },\n { once: true },\n )\n })\n\n return this.connecting\n }\n\n async disconnect(): Promise<void> {\n if (this.webSocket === null) return\n this.webSocket!.close()\n return _once(this.webSocket, 'close')\n }\n\n async call(\n namespace: string,\n procedure: string,\n payload: any,\n options: ProtocolBaseClientCallOptions,\n transformer: ProtocolBaseTransformer,\n ) {\n const { call, buffer } = this.protocol.createRpc(\n namespace,\n procedure,\n payload,\n options,\n transformer,\n )\n await this.send(ClientMessageType.Rpc, buffer)\n return call\n }\n\n async send(\n messageType: ClientMessageType,\n buffer: ArrayBuffer,\n ): Promise<void> {\n if (this.connecting) await this.connecting\n this.webSocket!.send(concat(encodeNumber(messageType, 'Uint8'), buffer))\n }\n}\n\nfunction _once(target: EventTarget, event: string) {\n return new Promise<void>((resolve) => {\n target.addEventListener(event, () => resolve(), { once: true })\n })\n}\n"],"version":3,"file":"index.js"}
|
package/package.json
CHANGED
|
@@ -8,14 +8,14 @@
|
|
|
8
8
|
}
|
|
9
9
|
},
|
|
10
10
|
"dependencies": {
|
|
11
|
-
"@nmtjs/client": "0.
|
|
12
|
-
"@nmtjs/protocol": "0.
|
|
13
|
-
"@nmtjs/common": "0.
|
|
11
|
+
"@nmtjs/client": "0.10.0",
|
|
12
|
+
"@nmtjs/protocol": "0.10.0",
|
|
13
|
+
"@nmtjs/common": "0.10.0"
|
|
14
14
|
},
|
|
15
15
|
"peerDependencies": {
|
|
16
|
-
"@nmtjs/client": "0.
|
|
17
|
-
"@nmtjs/common": "0.
|
|
18
|
-
"@nmtjs/protocol": "0.
|
|
16
|
+
"@nmtjs/client": "0.10.0",
|
|
17
|
+
"@nmtjs/common": "0.10.0",
|
|
18
|
+
"@nmtjs/protocol": "0.10.0"
|
|
19
19
|
},
|
|
20
20
|
"files": [
|
|
21
21
|
"src",
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
"LICENSE.md",
|
|
24
24
|
"README.md"
|
|
25
25
|
],
|
|
26
|
-
"version": "0.
|
|
26
|
+
"version": "0.10.0",
|
|
27
27
|
"scripts": {
|
|
28
28
|
"build": "neemata-build --root=./src './*.ts'",
|
|
29
29
|
"type-check": "tsc --noEmit"
|
package/src/index.ts
CHANGED
|
@@ -1,16 +1,10 @@
|
|
|
1
|
+
import { ClientMessageType, concat, encodeNumber } from '@nmtjs/protocol'
|
|
1
2
|
import {
|
|
2
|
-
type
|
|
3
|
-
|
|
4
|
-
type
|
|
5
|
-
|
|
3
|
+
type Protocol,
|
|
4
|
+
type ProtocolBaseClientCallOptions,
|
|
5
|
+
type ProtocolBaseTransformer,
|
|
6
|
+
ProtocolTransport,
|
|
6
7
|
} from '@nmtjs/protocol/client'
|
|
7
|
-
import {
|
|
8
|
-
type ClientMessageType,
|
|
9
|
-
concat,
|
|
10
|
-
decodeNumber,
|
|
11
|
-
encodeNumber,
|
|
12
|
-
ServerMessageType,
|
|
13
|
-
} from '@nmtjs/protocol/common'
|
|
14
8
|
|
|
15
9
|
export type WebSocketClientTransportOptions = {
|
|
16
10
|
/**
|
|
@@ -32,26 +26,23 @@ export type WebSocketClientTransportOptions = {
|
|
|
32
26
|
debug?: boolean
|
|
33
27
|
}
|
|
34
28
|
|
|
35
|
-
export class WebSocketClientTransport
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
{
|
|
39
|
-
#webSocket: WebSocket | null = null
|
|
40
|
-
#connecting: Promise<void> | null = null
|
|
29
|
+
export class WebSocketClientTransport extends ProtocolTransport {
|
|
30
|
+
protected webSocket: WebSocket | null = null
|
|
31
|
+
protected connecting: Promise<void> | null = null
|
|
41
32
|
|
|
42
|
-
constructor(
|
|
33
|
+
constructor(
|
|
34
|
+
protected readonly protocol: Protocol,
|
|
35
|
+
protected readonly options: WebSocketClientTransportOptions,
|
|
36
|
+
) {
|
|
43
37
|
super()
|
|
44
38
|
}
|
|
45
39
|
|
|
46
|
-
connect(
|
|
47
|
-
|
|
48
|
-
contentType
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
wsUrl.pathname = '/api'
|
|
53
|
-
wsUrl.searchParams.set('content-type', contentType)
|
|
54
|
-
wsUrl.searchParams.set('accept', contentType)
|
|
40
|
+
connect(auth: any, transformer: ProtocolBaseTransformer): Promise<void> {
|
|
41
|
+
const wsUrl = new URL('/api', this.options.origin)
|
|
42
|
+
if (this.protocol.contentType) {
|
|
43
|
+
wsUrl.searchParams.set('content-type', this.protocol.contentType)
|
|
44
|
+
wsUrl.searchParams.set('accept', this.protocol.contentType)
|
|
45
|
+
}
|
|
55
46
|
if (auth) wsUrl.searchParams.set('auth', auth)
|
|
56
47
|
|
|
57
48
|
const ws =
|
|
@@ -60,20 +51,16 @@ export class WebSocketClientTransport
|
|
|
60
51
|
ws.binaryType = 'arraybuffer'
|
|
61
52
|
|
|
62
53
|
ws.addEventListener('message', ({ data }) => {
|
|
63
|
-
|
|
64
|
-
const type = decodeNumber(buffer, 'Uint8')
|
|
65
|
-
if (type in ServerMessageType) {
|
|
66
|
-
this.emit(`${type}`, buffer.slice(Uint8Array.BYTES_PER_ELEMENT))
|
|
67
|
-
}
|
|
54
|
+
this.protocol.handleServerMessage(data as ArrayBuffer, this, transformer)
|
|
68
55
|
})
|
|
69
56
|
|
|
70
|
-
this
|
|
57
|
+
this.webSocket = ws
|
|
71
58
|
|
|
72
|
-
this
|
|
59
|
+
this.connecting = new Promise((resolve, reject) => {
|
|
73
60
|
ws.addEventListener(
|
|
74
61
|
'open',
|
|
75
62
|
() => {
|
|
76
|
-
this.emit('connected')
|
|
63
|
+
this.protocol.emit('connected')
|
|
77
64
|
resolve()
|
|
78
65
|
},
|
|
79
66
|
{ once: true },
|
|
@@ -81,38 +68,58 @@ export class WebSocketClientTransport
|
|
|
81
68
|
|
|
82
69
|
ws.addEventListener(
|
|
83
70
|
'error',
|
|
84
|
-
(event) =>
|
|
71
|
+
(event) => {
|
|
72
|
+
reject(new Error('WebSocket error', { cause: event }))
|
|
73
|
+
},
|
|
85
74
|
{ once: true },
|
|
86
75
|
)
|
|
87
76
|
|
|
88
77
|
ws.addEventListener(
|
|
89
78
|
'close',
|
|
90
79
|
(event) => {
|
|
91
|
-
this.emit('disconnected')
|
|
92
|
-
this
|
|
80
|
+
this.protocol.emit('disconnected')
|
|
81
|
+
this.webSocket = null
|
|
93
82
|
if (this.options.autoreconnect === true) {
|
|
94
|
-
setTimeout(
|
|
83
|
+
setTimeout(this.connect.bind(this), 1000)
|
|
95
84
|
}
|
|
96
85
|
},
|
|
97
86
|
{ once: true },
|
|
98
87
|
)
|
|
99
88
|
})
|
|
100
89
|
|
|
101
|
-
return this
|
|
90
|
+
return this.connecting
|
|
102
91
|
}
|
|
103
92
|
|
|
104
93
|
async disconnect(): Promise<void> {
|
|
105
|
-
if (this
|
|
106
|
-
this
|
|
107
|
-
return _once(this
|
|
94
|
+
if (this.webSocket === null) return
|
|
95
|
+
this.webSocket!.close()
|
|
96
|
+
return _once(this.webSocket, 'close')
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
async call(
|
|
100
|
+
namespace: string,
|
|
101
|
+
procedure: string,
|
|
102
|
+
payload: any,
|
|
103
|
+
options: ProtocolBaseClientCallOptions,
|
|
104
|
+
transformer: ProtocolBaseTransformer,
|
|
105
|
+
) {
|
|
106
|
+
const { call, buffer } = this.protocol.createRpc(
|
|
107
|
+
namespace,
|
|
108
|
+
procedure,
|
|
109
|
+
payload,
|
|
110
|
+
options,
|
|
111
|
+
transformer,
|
|
112
|
+
)
|
|
113
|
+
await this.send(ClientMessageType.Rpc, buffer)
|
|
114
|
+
return call
|
|
108
115
|
}
|
|
109
116
|
|
|
110
117
|
async send(
|
|
111
118
|
messageType: ClientMessageType,
|
|
112
119
|
buffer: ArrayBuffer,
|
|
113
120
|
): Promise<void> {
|
|
114
|
-
if (this
|
|
115
|
-
this
|
|
121
|
+
if (this.connecting) await this.connecting
|
|
122
|
+
this.webSocket!.send(concat(encodeNumber(messageType, 'Uint8'), buffer))
|
|
116
123
|
}
|
|
117
124
|
}
|
|
118
125
|
|