feat: Enforce exclusive auto-request (one client at a time)
Server is now source of truth for autoRequest. When a client enables it, all other clients lose it. Broadcast includes autoRequest per client, frontend syncs from server state on each torch-update.
This commit is contained in:
@@ -9,6 +9,7 @@ interface TorchClient {
|
||||
ws: any
|
||||
id: string
|
||||
name: string
|
||||
autoRequest: boolean
|
||||
userAgent: string
|
||||
hostname: string
|
||||
connectedAt: Date
|
||||
@@ -29,6 +30,7 @@ function broadcastTorchState(broadcast: (message: string, filter?: (ws: any) =>
|
||||
const clientList = Array.from(torchClients.values()).map(c => ({
|
||||
id: c.id,
|
||||
name: c.name,
|
||||
autoRequest: c.autoRequest,
|
||||
userAgent: c.userAgent,
|
||||
hostname: c.hostname,
|
||||
connectedAt: c.connectedAt.toISOString(),
|
||||
@@ -53,6 +55,7 @@ export function handleTorchConnect(ws: any, broadcast: (message: string, filter?
|
||||
ws,
|
||||
id,
|
||||
name: 'Anonymous',
|
||||
autoRequest: false,
|
||||
userAgent: 'Unknown',
|
||||
hostname: 'Unknown',
|
||||
connectedAt: new Date()
|
||||
@@ -73,8 +76,16 @@ export function handleTorchMessage(ws: any, data: any, broadcast: (message: stri
|
||||
client.hostname = data.hostname || 'Unknown'
|
||||
client.name = data.name || 'Anonymous'
|
||||
|
||||
// Claim autoRequest exclusively (only one client at a time)
|
||||
if (data.autoRequest) {
|
||||
for (const [, c] of torchClients) {
|
||||
if (c.id !== client.id) c.autoRequest = false
|
||||
}
|
||||
client.autoRequest = true
|
||||
}
|
||||
|
||||
// Auto-grant torch if requested and no one holds it
|
||||
if (data.autoRequest && torchHolderId === null) {
|
||||
if (client.autoRequest && torchHolderId === null) {
|
||||
torchHolderId = client.id
|
||||
console.log(`[Torch] Auto-granted torch to ${client.name} (${client.id})`)
|
||||
}
|
||||
@@ -87,7 +98,21 @@ export function handleTorchMessage(ws: any, data: any, broadcast: (message: stri
|
||||
hasTorch
|
||||
}))
|
||||
|
||||
console.log(`[Torch] Registered: ${client.name} (${client.id}) (torch: ${hasTorch})`)
|
||||
console.log(`[Torch] Registered: ${client.name} (${client.id}) (torch: ${hasTorch}, autoRequest: ${client.autoRequest})`)
|
||||
broadcastTorchState(broadcast)
|
||||
break
|
||||
}
|
||||
|
||||
case 'set-auto-request': {
|
||||
const value = !!data.value
|
||||
if (value) {
|
||||
// Exclusive: clear autoRequest from all other clients
|
||||
for (const [, c] of torchClients) {
|
||||
if (c.id !== client.id) c.autoRequest = false
|
||||
}
|
||||
}
|
||||
client.autoRequest = value
|
||||
console.log(`[Torch] Auto-request ${value ? 'claimed by' : 'released by'}: ${client.name} (${client.id})`)
|
||||
broadcastTorchState(broadcast)
|
||||
break
|
||||
}
|
||||
|
||||
@@ -78,7 +78,7 @@ export function startSyncServer() {
|
||||
const data = JSON.parse(message.toString())
|
||||
|
||||
// Route to appropriate handler based on message type
|
||||
if (data.type?.startsWith('torch-') || ['register', 'request', 'release', 'transfer', 'update-name'].includes(data.type)) {
|
||||
if (data.type?.startsWith('torch-') || ['register', 'request', 'release', 'transfer', 'update-name', 'set-auto-request'].includes(data.type)) {
|
||||
handleTorchMessage(ws, data, broadcast)
|
||||
}
|
||||
// Git doesn't expect messages from client
|
||||
|
||||
Reference in New Issue
Block a user