@fyresmith/hive-server 3.0.0 → 3.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/lib/socketHandler.js +47 -0
- package/package.json +1 -1
package/lib/socketHandler.js
CHANGED
|
@@ -19,6 +19,12 @@ const socketToFiles = new Map();
|
|
|
19
19
|
*/
|
|
20
20
|
const userBySocket = new Map();
|
|
21
21
|
|
|
22
|
+
/**
|
|
23
|
+
* claimedFiles: file path → { socketId, userId, username, color }
|
|
24
|
+
* @type {Map<string, object>}
|
|
25
|
+
*/
|
|
26
|
+
const claimedFiles = new Map();
|
|
27
|
+
|
|
22
28
|
function respond(cb, payload) {
|
|
23
29
|
if (typeof cb === 'function') cb(payload);
|
|
24
30
|
}
|
|
@@ -184,6 +190,38 @@ export function attachHandlers(io, getActiveRooms, broadcastFileUpdated, forceCl
|
|
|
184
190
|
}
|
|
185
191
|
});
|
|
186
192
|
|
|
193
|
+
// -----------------------------------------------------------------------
|
|
194
|
+
// file-claim
|
|
195
|
+
// -----------------------------------------------------------------------
|
|
196
|
+
socket.on('file-claim', ({ relPath } = {}, cb) => {
|
|
197
|
+
if (!isAllowedPath(relPath)) return respond(cb, { ok: false, error: 'Not allowed' });
|
|
198
|
+
const claimUser = userBySocket.get(socket.id);
|
|
199
|
+
if (!claimUser) return;
|
|
200
|
+
claimedFiles.set(relPath, { socketId: socket.id, ...claimUser });
|
|
201
|
+
io.emit('file-claimed', { relPath, user: claimUser });
|
|
202
|
+
respond(cb, { ok: true });
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
// -----------------------------------------------------------------------
|
|
206
|
+
// file-unclaim
|
|
207
|
+
// -----------------------------------------------------------------------
|
|
208
|
+
socket.on('file-unclaim', ({ relPath } = {}, cb) => {
|
|
209
|
+
const claim = claimedFiles.get(relPath);
|
|
210
|
+
if (claim?.socketId !== socket.id) return respond(cb, { ok: false, error: 'Not your claim' });
|
|
211
|
+
claimedFiles.delete(relPath);
|
|
212
|
+
io.emit('file-unclaimed', { relPath, userId: userBySocket.get(socket.id)?.id });
|
|
213
|
+
respond(cb, { ok: true });
|
|
214
|
+
});
|
|
215
|
+
|
|
216
|
+
// -----------------------------------------------------------------------
|
|
217
|
+
// user-status-changed
|
|
218
|
+
// -----------------------------------------------------------------------
|
|
219
|
+
socket.on('user-status-changed', ({ status } = {}) => {
|
|
220
|
+
const statusUser = userBySocket.get(socket.id);
|
|
221
|
+
if (!statusUser) return;
|
|
222
|
+
socket.broadcast.emit('user-status-changed', { userId: statusUser.id, status });
|
|
223
|
+
});
|
|
224
|
+
|
|
187
225
|
// -----------------------------------------------------------------------
|
|
188
226
|
// presence-file-opened
|
|
189
227
|
// -----------------------------------------------------------------------
|
|
@@ -219,6 +257,15 @@ export function attachHandlers(io, getActiveRooms, broadcastFileUpdated, forceCl
|
|
|
219
257
|
socket.broadcast.emit('presence-file-closed', { relPath, user });
|
|
220
258
|
}
|
|
221
259
|
socketToFiles.delete(socket.id);
|
|
260
|
+
|
|
261
|
+
// Release all file claims held by this socket
|
|
262
|
+
for (const [relPath, claim] of claimedFiles) {
|
|
263
|
+
if (claim.socketId === socket.id) {
|
|
264
|
+
claimedFiles.delete(relPath);
|
|
265
|
+
io.emit('file-unclaimed', { relPath, userId: claim.id });
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
|
|
222
269
|
userBySocket.delete(socket.id);
|
|
223
270
|
socket.broadcast.emit('user-left', { user });
|
|
224
271
|
});
|