-
Notifications
You must be signed in to change notification settings - Fork 195
/
index.ts
98 lines (84 loc) · 2.38 KB
/
index.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
// Copyright 2019-2023 Tauri Programme within The Commons Conservancy
// SPDX-License-Identifier: Apache-2.0
// SPDX-License-Identifier: MIT
import { invoke, Channel } from "@tauri-apps/api/core";
export interface ConnectionConfig {
writeBufferSize?: number;
maxWriteBufferSize?: number;
maxMessageSize?: number;
maxFrameSize?: number;
acceptUnmaskedFrames?: boolean;
headers?: HeadersInit;
}
export interface MessageKind<T, D> {
type: T;
data: D;
}
export interface CloseFrame {
code: number;
reason: string;
}
export type Message =
| MessageKind<"Text", string>
| MessageKind<"Binary", number[]>
| MessageKind<"Ping", number[]>
| MessageKind<"Pong", number[]>
| MessageKind<"Close", CloseFrame | null>;
export default class WebSocket {
id: number;
private readonly listeners: Array<(arg: Message) => void>;
constructor(id: number, listeners: Array<(arg: Message) => void>) {
this.id = id;
this.listeners = listeners;
}
static async connect(
url: string,
config?: ConnectionConfig,
): Promise<WebSocket> {
const listeners: Array<(arg: Message) => void> = [];
const onMessage = new Channel<Message>();
onMessage.onmessage = (message: Message): void => {
listeners.forEach((l) => {
l(message);
});
};
if (config?.headers) {
config.headers = Array.from(new Headers(config.headers).entries());
}
return await invoke<number>("plugin:websocket|connect", {
url,
onMessage,
config,
}).then((id) => new WebSocket(id, listeners));
}
addListener(cb: (arg: Message) => void): void {
this.listeners.push(cb);
}
async send(message: Message | string | number[]): Promise<void> {
let m: Message;
if (typeof message === "string") {
m = { type: "Text", data: message };
} else if (typeof message === "object" && "type" in message) {
m = message;
} else if (Array.isArray(message)) {
m = { type: "Binary", data: message };
} else {
throw new Error(
"invalid `message` type, expected a `{ type: string, data: any }` object, a string or a numeric array",
);
}
await invoke("plugin:websocket|send", {
id: this.id,
message: m,
});
}
async disconnect(): Promise<void> {
await this.send({
type: "Close",
data: {
code: 1000,
reason: "Disconnected by client",
},
});
}
}