@xloon/xms-client 0.1.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/LICENSE +201 -0
- package/NOTICE +4 -0
- package/README.md +97 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -0
- package/dist/protocol.d.ts +197 -0
- package/dist/protocol.js +4 -0
- package/dist/protocol.js.map +1 -0
- package/dist/room.d.ts +201 -0
- package/dist/room.js +610 -0
- package/dist/room.js.map +1 -0
- package/dist/signaling.d.ts +52 -0
- package/dist/signaling.js +165 -0
- package/dist/signaling.js.map +1 -0
- package/package.json +42 -0
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { EventData, EventName, MethodName, MethodParams, MethodResult } from './protocol.js';
|
|
2
|
+
/**
|
|
3
|
+
* The subset of the WebSocket interface signalingClient depends on. Letting
|
|
4
|
+
* the constructor accept a factory that produces this shape (rather than
|
|
5
|
+
* hard-coding `new WebSocket(url)`) is what makes request/response
|
|
6
|
+
* correlation unit-testable without a real server or a jsdom WebSocket
|
|
7
|
+
* implementation -- tests inject a hand-written fake.
|
|
8
|
+
*/
|
|
9
|
+
export interface WebSocketLike {
|
|
10
|
+
send(data: string): void;
|
|
11
|
+
close(code?: number, reason?: string): void;
|
|
12
|
+
readonly readyState: number;
|
|
13
|
+
onopen: ((event: Event) => void) | null;
|
|
14
|
+
onmessage: ((event: MessageEvent) => void) | null;
|
|
15
|
+
onerror: ((event: Event) => void) | null;
|
|
16
|
+
onclose: ((event: CloseEvent) => void) | null;
|
|
17
|
+
}
|
|
18
|
+
export type WebSocketFactory = (url: string) => WebSocketLike;
|
|
19
|
+
export type ConnectionState = 'idle' | 'connecting' | 'open' | 'closed';
|
|
20
|
+
type EventHandler<E extends EventName> = (data: EventData[E]) => void;
|
|
21
|
+
export declare class SignalingClient {
|
|
22
|
+
private readonly url;
|
|
23
|
+
private readonly wsFactory;
|
|
24
|
+
private ws;
|
|
25
|
+
private state;
|
|
26
|
+
private nextRequestId;
|
|
27
|
+
private readonly pending;
|
|
28
|
+
private readonly eventListeners;
|
|
29
|
+
private readonly openHandlers;
|
|
30
|
+
private readonly closeHandlers;
|
|
31
|
+
private readonly errorHandlers;
|
|
32
|
+
constructor(url: string, wsFactory?: WebSocketFactory);
|
|
33
|
+
getState(): ConnectionState;
|
|
34
|
+
connect(): Promise<void>;
|
|
35
|
+
disconnect(): void;
|
|
36
|
+
/**
|
|
37
|
+
* Sends a correlated request and resolves/rejects when the matching
|
|
38
|
+
* {type:"response", id} arrives. Rejects with the server's `error` object
|
|
39
|
+
* when `ok:false`, and with a synthetic ProtocolError if the connection is
|
|
40
|
+
* not open or closes before a response arrives -- never silently hangs.
|
|
41
|
+
*/
|
|
42
|
+
request<M extends MethodName>(method: M, params: MethodParams[M]): Promise<MethodResult[M]>;
|
|
43
|
+
/** Subscribes to an unsolicited server event. Returns an unsubscribe function. */
|
|
44
|
+
on<E extends EventName>(event: E, handler: EventHandler<E>): () => void;
|
|
45
|
+
onOpen(handler: () => void): () => void;
|
|
46
|
+
onClose(handler: (event: CloseEvent) => void): () => void;
|
|
47
|
+
onError(handler: (event: Event) => void): () => void;
|
|
48
|
+
private generateRequestId;
|
|
49
|
+
private rejectAllPending;
|
|
50
|
+
private handleMessage;
|
|
51
|
+
}
|
|
52
|
+
export {};
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
const CONNECTION_CLOSED_ERROR = {
|
|
2
|
+
code: 'CONNECTION_CLOSED',
|
|
3
|
+
message: 'The signaling WebSocket connection closed before a response was received.',
|
|
4
|
+
};
|
|
5
|
+
const NOT_CONNECTED_ERROR = {
|
|
6
|
+
code: 'NOT_CONNECTED',
|
|
7
|
+
message: 'The signaling WebSocket is not connected.',
|
|
8
|
+
};
|
|
9
|
+
function defaultWebSocketFactory(url) {
|
|
10
|
+
return new WebSocket(url);
|
|
11
|
+
}
|
|
12
|
+
export class SignalingClient {
|
|
13
|
+
url;
|
|
14
|
+
wsFactory;
|
|
15
|
+
ws = null;
|
|
16
|
+
state = 'idle';
|
|
17
|
+
nextRequestId = 0;
|
|
18
|
+
pending = new Map();
|
|
19
|
+
eventListeners = new Map();
|
|
20
|
+
openHandlers = new Set();
|
|
21
|
+
closeHandlers = new Set();
|
|
22
|
+
errorHandlers = new Set();
|
|
23
|
+
constructor(url, wsFactory = defaultWebSocketFactory) {
|
|
24
|
+
this.url = url;
|
|
25
|
+
this.wsFactory = wsFactory;
|
|
26
|
+
}
|
|
27
|
+
getState() {
|
|
28
|
+
return this.state;
|
|
29
|
+
}
|
|
30
|
+
connect() {
|
|
31
|
+
if (this.state === 'open') {
|
|
32
|
+
return Promise.resolve();
|
|
33
|
+
}
|
|
34
|
+
this.state = 'connecting';
|
|
35
|
+
return new Promise((resolve, reject) => {
|
|
36
|
+
const ws = this.wsFactory(this.url);
|
|
37
|
+
this.ws = ws;
|
|
38
|
+
ws.onopen = () => {
|
|
39
|
+
this.state = 'open';
|
|
40
|
+
for (const handler of this.openHandlers)
|
|
41
|
+
handler();
|
|
42
|
+
resolve();
|
|
43
|
+
};
|
|
44
|
+
ws.onmessage = (event) => {
|
|
45
|
+
this.handleMessage(event.data);
|
|
46
|
+
};
|
|
47
|
+
ws.onerror = (event) => {
|
|
48
|
+
for (const handler of this.errorHandlers)
|
|
49
|
+
handler(event);
|
|
50
|
+
if (this.state === 'connecting') {
|
|
51
|
+
reject(new Error('Signaling WebSocket failed to connect.'));
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
ws.onclose = (event) => {
|
|
55
|
+
this.state = 'closed';
|
|
56
|
+
this.rejectAllPending(CONNECTION_CLOSED_ERROR);
|
|
57
|
+
for (const handler of this.closeHandlers)
|
|
58
|
+
handler(event);
|
|
59
|
+
};
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
disconnect() {
|
|
63
|
+
this.ws?.close();
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Sends a correlated request and resolves/rejects when the matching
|
|
67
|
+
* {type:"response", id} arrives. Rejects with the server's `error` object
|
|
68
|
+
* when `ok:false`, and with a synthetic ProtocolError if the connection is
|
|
69
|
+
* not open or closes before a response arrives -- never silently hangs.
|
|
70
|
+
*/
|
|
71
|
+
request(method, params) {
|
|
72
|
+
if (!this.ws || this.state !== 'open') {
|
|
73
|
+
return Promise.reject(NOT_CONNECTED_ERROR);
|
|
74
|
+
}
|
|
75
|
+
const id = this.generateRequestId();
|
|
76
|
+
const message = { type: 'request', id, method, params };
|
|
77
|
+
return new Promise((resolve, reject) => {
|
|
78
|
+
this.pending.set(id, {
|
|
79
|
+
resolve: resolve,
|
|
80
|
+
reject,
|
|
81
|
+
});
|
|
82
|
+
try {
|
|
83
|
+
this.ws.send(JSON.stringify(message));
|
|
84
|
+
}
|
|
85
|
+
catch (err) {
|
|
86
|
+
this.pending.delete(id);
|
|
87
|
+
reject({ code: 'SEND_FAILED', message: `Failed to send request: ${String(err)}` });
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
/** Subscribes to an unsolicited server event. Returns an unsubscribe function. */
|
|
92
|
+
on(event, handler) {
|
|
93
|
+
let handlers = this.eventListeners.get(event);
|
|
94
|
+
if (!handlers) {
|
|
95
|
+
handlers = new Set();
|
|
96
|
+
this.eventListeners.set(event, handlers);
|
|
97
|
+
}
|
|
98
|
+
handlers.add(handler);
|
|
99
|
+
return () => {
|
|
100
|
+
handlers.delete(handler);
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
onOpen(handler) {
|
|
104
|
+
this.openHandlers.add(handler);
|
|
105
|
+
return () => this.openHandlers.delete(handler);
|
|
106
|
+
}
|
|
107
|
+
onClose(handler) {
|
|
108
|
+
this.closeHandlers.add(handler);
|
|
109
|
+
return () => this.closeHandlers.delete(handler);
|
|
110
|
+
}
|
|
111
|
+
onError(handler) {
|
|
112
|
+
this.errorHandlers.add(handler);
|
|
113
|
+
return () => this.errorHandlers.delete(handler);
|
|
114
|
+
}
|
|
115
|
+
generateRequestId() {
|
|
116
|
+
this.nextRequestId += 1;
|
|
117
|
+
return `c-${this.nextRequestId.toString(36)}`;
|
|
118
|
+
}
|
|
119
|
+
rejectAllPending(error) {
|
|
120
|
+
for (const { reject } of this.pending.values()) {
|
|
121
|
+
reject(error);
|
|
122
|
+
}
|
|
123
|
+
this.pending.clear();
|
|
124
|
+
}
|
|
125
|
+
handleMessage(raw) {
|
|
126
|
+
let message;
|
|
127
|
+
try {
|
|
128
|
+
message = JSON.parse(raw);
|
|
129
|
+
}
|
|
130
|
+
catch (err) {
|
|
131
|
+
console.error('signalingClient: received malformed JSON message', raw, err);
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
if (message.type === 'response') {
|
|
135
|
+
const pending = this.pending.get(message.id);
|
|
136
|
+
if (!pending) {
|
|
137
|
+
console.warn(`signalingClient: response for unknown/expired request id "${message.id}"`, message);
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
this.pending.delete(message.id);
|
|
141
|
+
if (message.ok) {
|
|
142
|
+
pending.resolve(message.result);
|
|
143
|
+
}
|
|
144
|
+
else {
|
|
145
|
+
pending.reject(message.error);
|
|
146
|
+
}
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
if (message.type === 'event') {
|
|
150
|
+
const handlers = this.eventListeners.get(message.event);
|
|
151
|
+
if (!handlers || handlers.size === 0) {
|
|
152
|
+
// No listener registered for this event -- expected for events no
|
|
153
|
+
// currently-mounted component cares about; nothing to correlate
|
|
154
|
+
// since events never carry a request id.
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
for (const handler of handlers) {
|
|
158
|
+
handler(message.data);
|
|
159
|
+
}
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
console.warn('signalingClient: received message with unknown "type"', message);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
//# sourceMappingURL=signaling.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"signaling.js","sourceRoot":"","sources":["../src/signaling.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@xloon/xms-client",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Browser client SDK for the Xloon Media Server (XMS)",
|
|
5
|
+
"license": "Apache-2.0",
|
|
6
|
+
"keywords": [
|
|
7
|
+
"webrtc",
|
|
8
|
+
"sfu",
|
|
9
|
+
"video-conferencing",
|
|
10
|
+
"xms",
|
|
11
|
+
"xloon"
|
|
12
|
+
],
|
|
13
|
+
"type": "module",
|
|
14
|
+
"main": "./dist/index.js",
|
|
15
|
+
"types": "./dist/index.d.ts",
|
|
16
|
+
"exports": {
|
|
17
|
+
".": {
|
|
18
|
+
"types": "./dist/index.d.ts",
|
|
19
|
+
"import": "./dist/index.js"
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
"files": [
|
|
23
|
+
"dist",
|
|
24
|
+
"LICENSE",
|
|
25
|
+
"NOTICE"
|
|
26
|
+
],
|
|
27
|
+
"sideEffects": false,
|
|
28
|
+
"scripts": {
|
|
29
|
+
"build": "tsc -p tsconfig.build.json",
|
|
30
|
+
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
31
|
+
"test": "vitest run",
|
|
32
|
+
"prepublishOnly": "npm run typecheck && npm test && npm run build"
|
|
33
|
+
},
|
|
34
|
+
"publishConfig": {
|
|
35
|
+
"access": "public"
|
|
36
|
+
},
|
|
37
|
+
"devDependencies": {
|
|
38
|
+
"jsdom": "^30.1.1",
|
|
39
|
+
"typescript": "~6.0.2",
|
|
40
|
+
"vitest": "^5.0.2"
|
|
41
|
+
}
|
|
42
|
+
}
|