thinkncollab-shell 0.0.5 → 0.0.6
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/package.json +1 -1
- package/src/commands/auth/login.js +58 -58
- package/src/commands/auth/register.js +52 -0
- package/src/commands/index.js +62 -43
- package/src/commands/room/join.js +119 -45
- package/src/commands/shell/notify.js +88 -0
- package/src/commands/tasks/complete.js +47 -0
- package/src/commands/tasks/create-task.js +101 -0
- package/src/commands/tasks/suggestTask.js +0 -0
- package/src/commands/tasks/task.js +75 -0
- package/src/commands/tasks/tasks.js +74 -0
- package/src/commands/terminal/share.js +252 -0
- package/src/core/api-client.js +104 -50
- package/src/core/notification-window.js +1 -1
- package/src/core/project-config.js +100 -0
- package/src/core/shell.js +222 -210
- package/src/core/websocket.js +135 -148
package/src/core/websocket.js
CHANGED
|
@@ -1,15 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* WebSocket Manager for ThinkNCollab Shell
|
|
3
|
-
* Uses thinknsh: prefixed events for terminal-specific communication
|
|
2
|
+
* src/core/websocket.js — WebSocket Manager for ThinkNCollab Shell
|
|
4
3
|
*/
|
|
5
4
|
|
|
6
|
-
const { io }
|
|
5
|
+
const { io } = require('socket.io-client');
|
|
7
6
|
const EventEmitter = require('events');
|
|
8
7
|
|
|
9
8
|
class WebSocketManager extends EventEmitter {
|
|
9
|
+
|
|
10
10
|
constructor(config = {}) {
|
|
11
11
|
super();
|
|
12
|
-
|
|
13
12
|
this.config = {
|
|
14
13
|
serverUrl: config.serverUrl || 'https://thinkncollab.com',
|
|
15
14
|
reconnectAttempts: config.reconnectAttempts || 5,
|
|
@@ -19,12 +18,13 @@ class WebSocketManager extends EventEmitter {
|
|
|
19
18
|
|
|
20
19
|
this.socket = null;
|
|
21
20
|
this.connected = false;
|
|
22
|
-
this.currentUser = null;
|
|
21
|
+
this.currentUser = null; // always { userId, name, userType }
|
|
23
22
|
this.roomId = null;
|
|
24
23
|
this.reconnectCount = 0;
|
|
25
24
|
this.messageQueue = [];
|
|
26
25
|
this._authToken = null;
|
|
27
26
|
this._handlersSetup = false;
|
|
27
|
+
this._serverReady = false;
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
// ─── Connect ──────────────────────────────────────────────────────────────
|
|
@@ -32,40 +32,34 @@ class WebSocketManager extends EventEmitter {
|
|
|
32
32
|
connect(authToken = null) {
|
|
33
33
|
return new Promise((resolve, reject) => {
|
|
34
34
|
try {
|
|
35
|
-
this._authToken = authToken;
|
|
35
|
+
if (authToken) this._authToken = authToken;
|
|
36
36
|
|
|
37
37
|
this.socket = io(this.config.serverUrl + '/thinknsh', {
|
|
38
38
|
transports: ['websocket', 'polling'],
|
|
39
39
|
reconnection: true,
|
|
40
40
|
reconnectionAttempts: this.config.reconnectAttempts,
|
|
41
41
|
reconnectionDelay: this.config.reconnectDelay,
|
|
42
|
-
auth:
|
|
42
|
+
auth: this._authToken ? { token: this._authToken } : {},
|
|
43
43
|
});
|
|
44
44
|
|
|
45
|
-
const timeout = setTimeout(() =>
|
|
45
|
+
const timeout = setTimeout(() => {
|
|
46
|
+
reject(new Error('Connection timeout'));
|
|
47
|
+
}, 10000);
|
|
46
48
|
|
|
47
49
|
this.socket.on('connect', () => {
|
|
48
50
|
clearTimeout(timeout);
|
|
49
51
|
this.connected = true;
|
|
50
52
|
this.reconnectCount = 0;
|
|
51
53
|
|
|
54
|
+
// Announce user immediately on connect if we have one
|
|
52
55
|
if (this.currentUser) {
|
|
53
|
-
|
|
54
|
-
this.socket.emit('thinknsh:connected', {
|
|
55
|
-
userId: this.currentUser.userId,
|
|
56
|
-
userName: this.currentUser.name,
|
|
57
|
-
shellToken: authToken,
|
|
58
|
-
});
|
|
56
|
+
this._announceUser();
|
|
59
57
|
}
|
|
60
58
|
|
|
61
59
|
this.processPendingMessages();
|
|
62
60
|
this.emit('connected', { socketId: this.socket.id });
|
|
63
61
|
resolve({ success: true, socketId: this.socket.id });
|
|
64
62
|
});
|
|
65
|
-
// One-time listener for confirmation
|
|
66
|
-
// this.ws.once('notified', (data) => {
|
|
67
|
-
// console.log(chalk.green(`✅ Notification sent to ${data.sentTo} member(s) in "${data.roomName}"`));
|
|
68
|
-
// });
|
|
69
63
|
|
|
70
64
|
this.socket.on('connect_error', (error) => {
|
|
71
65
|
clearTimeout(timeout);
|
|
@@ -81,26 +75,14 @@ class WebSocketManager extends EventEmitter {
|
|
|
81
75
|
this.emit('disconnected', { reason });
|
|
82
76
|
});
|
|
83
77
|
|
|
84
|
-
this.socket.on('reconnect', (
|
|
78
|
+
this.socket.on('reconnect', () => {
|
|
85
79
|
this.connected = true;
|
|
86
|
-
this.emit('reconnected', {
|
|
87
|
-
|
|
88
|
-
// Re-announce user after reconnect
|
|
89
|
-
if (this.currentUser) {
|
|
90
|
-
this.socket.emit('thinknsh:connected', {
|
|
91
|
-
userId: this.currentUser.userId,
|
|
92
|
-
userName: this.currentUser.name,
|
|
93
|
-
shellToken: this._authToken,
|
|
94
|
-
});
|
|
95
|
-
}
|
|
80
|
+
this.emit('reconnected', {});
|
|
96
81
|
|
|
97
|
-
|
|
98
|
-
if (this.roomId && this.currentUser)
|
|
99
|
-
this._emitJoin(this.roomId);
|
|
100
|
-
}
|
|
82
|
+
if (this.currentUser) this._announceUser();
|
|
83
|
+
if (this.roomId && this.currentUser) this._emitJoin(this.roomId);
|
|
101
84
|
});
|
|
102
85
|
|
|
103
|
-
// ✅ Setup handlers only ONCE per socket instance
|
|
104
86
|
if (!this._handlersSetup) {
|
|
105
87
|
this.setupEventHandlers();
|
|
106
88
|
this._handlersSetup = true;
|
|
@@ -112,39 +94,68 @@ class WebSocketManager extends EventEmitter {
|
|
|
112
94
|
});
|
|
113
95
|
}
|
|
114
96
|
|
|
115
|
-
// ───
|
|
97
|
+
// ─── Announce user to server (thinknsh:connected) ─────────────────────────
|
|
98
|
+
|
|
99
|
+
_announceUser() {
|
|
100
|
+
if (!this.socket || !this.currentUser) return;
|
|
101
|
+
this.socket.emit('thinknsh:connected', {
|
|
102
|
+
userId: this.currentUser.userId,
|
|
103
|
+
userName: this.currentUser.name,
|
|
104
|
+
shellToken: this._authToken,
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// ─── Set user — called right after login ──────────────────────────────────
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Accepts any of these shapes and normalises to { userId, name, userType }:
|
|
112
|
+
* { _id, userId, name, email, userType } ← from api-client.getUser()
|
|
113
|
+
* { userId, name, userType } ← legacy
|
|
114
|
+
*/
|
|
115
|
+
setUser(user, token = null) {
|
|
116
|
+
if (!user) return;
|
|
117
|
+
|
|
118
|
+
if (token) this._authToken = token;
|
|
119
|
+
|
|
120
|
+
// Normalise — support both _id and userId
|
|
121
|
+
const id = (user.userId || user._id || '').toString();
|
|
122
|
+
this.currentUser = {
|
|
123
|
+
userId: id,
|
|
124
|
+
name: user.name || user.email || 'Unknown',
|
|
125
|
+
userType: user.userType || user.model || user.role || 'User',
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
// If already connected, announce immediately
|
|
129
|
+
if (this.connected && this.socket) {
|
|
130
|
+
this._announceUser();
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// ─── Event Handlers ───────────────────────────────────────────────────────
|
|
116
135
|
|
|
117
136
|
setupEventHandlers() {
|
|
118
137
|
|
|
119
|
-
// Terminal ready confirmed by server
|
|
120
138
|
this.socket.on('thinknsh:ready', (data) => {
|
|
139
|
+
this._serverReady = true;
|
|
121
140
|
this.emit('ready', data);
|
|
122
141
|
});
|
|
123
142
|
|
|
124
|
-
// ✅ Room join confirmed + history delivered
|
|
125
143
|
this.socket.on('thinknsh:joined', (data) => {
|
|
126
144
|
this.roomId = data.roomId;
|
|
127
|
-
|
|
128
|
-
// Emit history separately so shell.js can display it
|
|
129
|
-
if (data.history && data.history.length > 0) {
|
|
130
|
-
this.emit('messageHistory', data.history);
|
|
131
|
-
}
|
|
132
|
-
|
|
145
|
+
if (data.history?.length) this.emit('messageHistory', data.history);
|
|
133
146
|
this.emit('roomJoined', data);
|
|
134
147
|
});
|
|
135
148
|
|
|
136
|
-
// Incoming message from terminal users
|
|
137
149
|
this.socket.on('thinknsh:message', (data) => {
|
|
138
150
|
this.emit('message', {
|
|
139
151
|
username: data.name,
|
|
140
152
|
userId: data.userId,
|
|
141
153
|
message: data.message,
|
|
142
|
-
source:
|
|
154
|
+
source: 'shell',
|
|
143
155
|
timestamp: data.timestamp,
|
|
144
156
|
});
|
|
145
157
|
});
|
|
146
158
|
|
|
147
|
-
// Incoming message from web users
|
|
148
159
|
this.socket.on('chat-message', (data) => {
|
|
149
160
|
this.emit('message', {
|
|
150
161
|
username: data.name,
|
|
@@ -155,75 +166,55 @@ class WebSocketManager extends EventEmitter {
|
|
|
155
166
|
});
|
|
156
167
|
});
|
|
157
168
|
|
|
158
|
-
// User joined from terminal
|
|
159
169
|
this.socket.on('thinknsh:userJoined', (data) => {
|
|
160
170
|
this.emit('userJoined', { username: data.name, source: 'shell' });
|
|
161
171
|
});
|
|
162
172
|
|
|
163
|
-
// ✅ User left from terminal
|
|
164
173
|
this.socket.on('thinknsh:userLeft', (data) => {
|
|
165
174
|
this.emit('userLeft', { username: data.name, source: 'shell' });
|
|
166
175
|
});
|
|
167
176
|
|
|
168
|
-
// User joined from web
|
|
169
177
|
this.socket.on('user-joined', (name) => {
|
|
170
178
|
this.emit('userJoined', { username: name, source: 'web' });
|
|
171
179
|
});
|
|
172
180
|
|
|
173
|
-
// User left from web
|
|
174
181
|
this.socket.on('user-left', (name) => {
|
|
175
182
|
this.emit('userLeft', { username: name, source: 'web' });
|
|
176
183
|
});
|
|
177
184
|
|
|
178
|
-
// User list updated
|
|
179
185
|
this.socket.on('user-list', (users) => {
|
|
180
186
|
this.emit('userList', { users });
|
|
181
187
|
});
|
|
182
188
|
|
|
183
|
-
// ✅ Manual history fetch response
|
|
184
189
|
this.socket.on('thinknsh:history', (data) => {
|
|
185
|
-
|
|
186
|
-
this.emit('messageHistory', data.messages);
|
|
187
|
-
} else {
|
|
188
|
-
this.emit('messageHistory', []);
|
|
189
|
-
}
|
|
190
|
+
this.emit('messageHistory', data.messages?.length ? data.messages : []);
|
|
190
191
|
});
|
|
191
192
|
|
|
192
|
-
// Single new-notification listener
|
|
193
193
|
this.socket.on('new-notification', (data) => {
|
|
194
194
|
this.emit('notification', {
|
|
195
|
-
type: data.type
|
|
196
|
-
level: data.type
|
|
197
|
-
title: data.
|
|
198
|
-
message: data.message
|
|
199
|
-
meta: data.meta
|
|
195
|
+
type: data.type || 'info',
|
|
196
|
+
level: data.type || 'info',
|
|
197
|
+
title: data.title || 'Notification',
|
|
198
|
+
message: data.message || '',
|
|
199
|
+
meta: data.meta || {},
|
|
200
200
|
taskTitle: data.taskTitle || data.meta?.taskTitle || '',
|
|
201
201
|
assignedBy: data.assignedBy || data.meta?.assignedBy || '',
|
|
202
202
|
});
|
|
203
203
|
});
|
|
204
204
|
|
|
205
|
-
// Room activity feed
|
|
206
205
|
this.socket.on('room:activity', (data) => {
|
|
207
|
-
this.emit('roomActivity',
|
|
208
|
-
action: data.action,
|
|
209
|
-
label: data.label,
|
|
210
|
-
userName: data.userName,
|
|
211
|
-
meta: data.meta || {},
|
|
212
|
-
createdAt: data.createdAt || new Date(),
|
|
213
|
-
});
|
|
206
|
+
this.emit('roomActivity', data);
|
|
214
207
|
});
|
|
215
208
|
|
|
216
|
-
// Terminal status (online/offline)
|
|
217
209
|
this.socket.on('thinknsh:status', (data) => {
|
|
218
210
|
this.emit('shellStatus', data);
|
|
219
211
|
});
|
|
220
212
|
|
|
221
|
-
// Notification list response
|
|
222
213
|
this.socket.on('thinknsh:notifications', (data) => {
|
|
223
214
|
this.emit('notificationList', data.notifications);
|
|
224
215
|
});
|
|
225
216
|
|
|
226
|
-
// Server errors
|
|
217
|
+
// Server errors — emit as 'serverError' so shell.js can handle separately
|
|
227
218
|
this.socket.on('thinknsh:error', (data) => {
|
|
228
219
|
this.emit('serverError', data);
|
|
229
220
|
});
|
|
@@ -233,46 +224,64 @@ class WebSocketManager extends EventEmitter {
|
|
|
233
224
|
});
|
|
234
225
|
}
|
|
235
226
|
|
|
236
|
-
// ─── Set user (call after login) ──────────────────────────────────────────
|
|
237
|
-
|
|
238
|
-
setUser(user, token = null) {
|
|
239
|
-
this.currentUser = user;
|
|
240
|
-
if (token) this._authToken = token;
|
|
241
|
-
|
|
242
|
-
if (this.connected && this.socket) {
|
|
243
|
-
this.socket.emit('thinknsh:connected', {
|
|
244
|
-
userId: user.userId,
|
|
245
|
-
userName: user.name,
|
|
246
|
-
shellToken: token || this._authToken,
|
|
247
|
-
});
|
|
248
|
-
}
|
|
249
|
-
}
|
|
250
|
-
|
|
251
227
|
// ─── Join room ────────────────────────────────────────────────────────────
|
|
252
228
|
|
|
253
229
|
joinRoom(roomId) {
|
|
254
230
|
return new Promise((resolve, reject) => {
|
|
255
|
-
if (!this.connected || !this.socket)
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
231
|
+
if (!this.connected || !this.socket)
|
|
232
|
+
return reject(new Error('Not connected to server'));
|
|
233
|
+
if (!this.currentUser)
|
|
234
|
+
return reject(new Error('Not logged in — run: login'));
|
|
235
|
+
|
|
236
|
+
const timeout = setTimeout(() => {
|
|
237
|
+
this.socket.off('thinknsh:joined', onJoined);
|
|
238
|
+
this.socket.off('thinknsh:error', onError);
|
|
239
|
+
this.socket.off('thinknsh:ready', onReady);
|
|
240
|
+
reject(new Error('Join timeout'));
|
|
241
|
+
}, 8000);
|
|
242
|
+
|
|
243
|
+
const onJoined = (data) => {
|
|
261
244
|
clearTimeout(timeout);
|
|
245
|
+
this.socket.off('thinknsh:error', onError);
|
|
262
246
|
this.roomId = data.roomId;
|
|
263
247
|
resolve(data);
|
|
264
|
-
}
|
|
248
|
+
};
|
|
249
|
+
|
|
250
|
+
// onReady declared at top so onError can reference it regardless of branch
|
|
251
|
+
let onReady = null;
|
|
265
252
|
|
|
266
|
-
|
|
253
|
+
const onError = (data) => {
|
|
254
|
+
clearTimeout(timeout);
|
|
255
|
+
this.socket.off('thinknsh:joined', onJoined);
|
|
256
|
+
if (onReady) this.socket.off('thinknsh:ready', onReady);
|
|
257
|
+
reject(new Error(data.message || 'Join error'));
|
|
258
|
+
};
|
|
259
|
+
|
|
260
|
+
const doJoin = () => {
|
|
261
|
+
this.socket.once('thinknsh:joined', onJoined);
|
|
262
|
+
this.socket.once('thinknsh:error', onError);
|
|
263
|
+
this._emitJoin(roomId);
|
|
264
|
+
};
|
|
265
|
+
|
|
266
|
+
if (this._serverReady) {
|
|
267
|
+
doJoin();
|
|
268
|
+
} else {
|
|
269
|
+
onReady = () => {
|
|
270
|
+
this._serverReady = true;
|
|
271
|
+
doJoin();
|
|
272
|
+
};
|
|
273
|
+
this.socket.once('thinknsh:ready', onReady);
|
|
274
|
+
}
|
|
267
275
|
});
|
|
268
276
|
}
|
|
269
277
|
|
|
270
278
|
_emitJoin(roomId) {
|
|
279
|
+
if (!this.socket || !this.currentUser) return;
|
|
271
280
|
this.socket.emit('thinknsh:join', {
|
|
272
281
|
roomId,
|
|
273
282
|
userId: this.currentUser.userId,
|
|
274
283
|
name: this.currentUser.name,
|
|
275
|
-
userType: this.currentUser.userType
|
|
284
|
+
userType: this.currentUser.userType,
|
|
276
285
|
});
|
|
277
286
|
}
|
|
278
287
|
|
|
@@ -300,55 +309,43 @@ class WebSocketManager extends EventEmitter {
|
|
|
300
309
|
roomId: this.roomId,
|
|
301
310
|
userId: this.currentUser.userId,
|
|
302
311
|
name: this.currentUser.name,
|
|
303
|
-
userType: this.currentUser.userType
|
|
312
|
+
userType: this.currentUser.userType,
|
|
304
313
|
message,
|
|
305
314
|
});
|
|
306
315
|
|
|
307
316
|
return Promise.resolve({ success: true });
|
|
308
317
|
}
|
|
309
318
|
|
|
310
|
-
// ───
|
|
319
|
+
// ─── History ──────────────────────────────────────────────────────────────
|
|
311
320
|
|
|
312
321
|
getHistory(limit = 30, skip = 0) {
|
|
313
|
-
if (!this.connected || !this.socket) return;
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
this.socket.emit('thinknsh:getHistory', {
|
|
317
|
-
roomId: this.roomId,
|
|
318
|
-
limit,
|
|
319
|
-
skip,
|
|
320
|
-
});
|
|
322
|
+
if (!this.connected || !this.socket || !this.roomId) return;
|
|
323
|
+
this.socket.emit('thinknsh:getHistory', { roomId: this.roomId, limit, skip });
|
|
321
324
|
}
|
|
322
325
|
|
|
323
326
|
// ─── Notifications ────────────────────────────────────────────────────────
|
|
324
327
|
|
|
325
328
|
getNotifications() {
|
|
326
329
|
if (!this.connected || !this.currentUser) return;
|
|
327
|
-
this.socket.emit('thinknsh:getNotifications', {
|
|
328
|
-
userId: this.currentUser.userId
|
|
329
|
-
});
|
|
330
|
+
this.socket.emit('thinknsh:getNotifications', { userId: this.currentUser.userId });
|
|
330
331
|
}
|
|
331
332
|
|
|
332
|
-
|
|
333
|
+
sendNotification(notification, target = 'room') {
|
|
334
|
+
if (!this.connected || !this.socket)
|
|
335
|
+
return Promise.reject(new Error('Not connected'));
|
|
336
|
+
|
|
337
|
+
this.socket.emit('notification:send', {
|
|
338
|
+
type: notification.type || 'info',
|
|
339
|
+
title: notification.title || 'Notification',
|
|
340
|
+
message: notification.message,
|
|
341
|
+
data: notification.data || {},
|
|
342
|
+
target: target === 'room' ? this.roomId : target,
|
|
343
|
+
timestamp: new Date().toISOString()
|
|
344
|
+
});
|
|
333
345
|
|
|
334
|
-
|
|
335
|
-
if (!this.connected || !this.socket) {
|
|
336
|
-
return Promise.reject(new Error('Not connected'));
|
|
346
|
+
return Promise.resolve({ success: true });
|
|
337
347
|
}
|
|
338
348
|
|
|
339
|
-
const payload = {
|
|
340
|
-
type: notification.type || 'info',
|
|
341
|
-
title: notification.title || 'Notification',
|
|
342
|
-
message: notification.message,
|
|
343
|
-
data: notification.data || {},
|
|
344
|
-
target: target === 'room' ? this.roomId : target,
|
|
345
|
-
timestamp: new Date().toISOString()
|
|
346
|
-
};
|
|
347
|
-
|
|
348
|
-
this.socket.emit('notification:send', payload);
|
|
349
|
-
return Promise.resolve({ success: true });
|
|
350
|
-
}
|
|
351
|
-
|
|
352
349
|
markNotificationsRead(notificationIds = []) {
|
|
353
350
|
if (!this.connected || !this.currentUser) return;
|
|
354
351
|
this.socket.emit('thinknsh:markRead', {
|
|
@@ -359,43 +356,33 @@ sendNotification(notification, target = 'room') {
|
|
|
359
356
|
|
|
360
357
|
// ─── Helpers ──────────────────────────────────────────────────────────────
|
|
361
358
|
|
|
362
|
-
joinUserRoom(userId) {
|
|
363
|
-
if (!this.socket || !userId) return;
|
|
364
|
-
this.socket.emit('thinknsh:connected', {
|
|
365
|
-
userId,
|
|
366
|
-
userName: this.currentUser?.name || '',
|
|
367
|
-
shellToken: this._authToken || null,
|
|
368
|
-
});
|
|
369
|
-
}
|
|
370
|
-
|
|
371
|
-
ping() {
|
|
372
|
-
if (this.connected && this.socket) this.socket.emit('ping');
|
|
373
|
-
}
|
|
374
|
-
|
|
375
359
|
processPendingMessages() {
|
|
376
|
-
if (this.messageQueue.length
|
|
360
|
+
if (this.messageQueue.length && this.roomId && this.currentUser) {
|
|
377
361
|
this.messageQueue.forEach(msg => this.sendMessage(msg));
|
|
378
362
|
this.messageQueue = [];
|
|
379
363
|
}
|
|
380
364
|
}
|
|
381
365
|
|
|
382
|
-
sendTyping() {} // add later if needed
|
|
383
|
-
|
|
384
366
|
disconnect() {
|
|
385
367
|
if (this.socket) {
|
|
368
|
+
this.socket.removeAllListeners();
|
|
386
369
|
this.socket.disconnect();
|
|
387
370
|
this.socket = null;
|
|
388
371
|
this.connected = false;
|
|
389
372
|
this.currentUser = null;
|
|
390
373
|
this.roomId = null;
|
|
391
374
|
this._handlersSetup = false;
|
|
375
|
+
this._serverReady = false;
|
|
376
|
+
this._serverReady = false;
|
|
392
377
|
}
|
|
393
378
|
}
|
|
394
379
|
|
|
395
|
-
isConnected()
|
|
396
|
-
getCurrentRoom()
|
|
397
|
-
getSocketId()
|
|
398
|
-
getParticipants()
|
|
380
|
+
isConnected() { return this.connected && !!this.socket?.connected; }
|
|
381
|
+
getCurrentRoom() { return this.roomId; }
|
|
382
|
+
getSocketId() { return this.socket?.id || null; }
|
|
383
|
+
getParticipants(){ return Promise.resolve([]); }
|
|
384
|
+
sendTyping() {}
|
|
385
|
+
ping() { if (this.connected && this.socket) this.socket.emit('ping'); }
|
|
399
386
|
}
|
|
400
387
|
|
|
401
388
|
module.exports = WebSocketManager;
|