thinkpool-pair 0.6.22 → 0.6.23
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/bridge.mjs +18 -3
- package/package.json +1 -1
package/bridge.mjs
CHANGED
|
@@ -536,6 +536,16 @@ channel
|
|
|
536
536
|
const t = terms.get(payload.term)
|
|
537
537
|
if (t && !t.attached) { try { t.term.resize(Math.max(payload.cols, 80), Math.max(payload.rows, 20)); announce() } catch { /* noop */ } }
|
|
538
538
|
})
|
|
539
|
+
.on('broadcast', { event: 'session-deleted' }, async () => {
|
|
540
|
+
// The room was deleted from the dashboard. Close the bridge — and if we're a
|
|
541
|
+
// background service, uninstall ourselves first so the supervisor doesn't
|
|
542
|
+
// restart us into a room that no longer exists.
|
|
543
|
+
process.stderr.write('\n ◆ this room was deleted — closing the bridge.\n')
|
|
544
|
+
if (process.env.THINKPOOL_PAIR_AUTOUPDATE === '1') {
|
|
545
|
+
try { const svc = await import('./service.mjs'); svc.uninstallService(room) } catch { /* noop */ }
|
|
546
|
+
}
|
|
547
|
+
shutdown()
|
|
548
|
+
})
|
|
539
549
|
.on('broadcast', { event: 'term-open' }, ({ payload }) => {
|
|
540
550
|
if (!payload?.id || !payload?.cmd) return
|
|
541
551
|
// Multi-bridge rooms: a targeted open is for ONE machine. Untargeted
|
|
@@ -781,7 +791,7 @@ if (process.env.THINKPOOL_PAIR_AUTOUPDATE === '1' && VERSION) {
|
|
|
781
791
|
}, 60000).unref()
|
|
782
792
|
}
|
|
783
793
|
|
|
784
|
-
function shutdown() {
|
|
794
|
+
async function shutdown() {
|
|
785
795
|
if (shuttingDown) return
|
|
786
796
|
shuttingDown = true
|
|
787
797
|
clearInterval(flushTimer)
|
|
@@ -789,11 +799,16 @@ function shutdown() {
|
|
|
789
799
|
const bye = Buffer.from('\r\n[ shared session ended ]\r\n', 'utf8').toString('base64')
|
|
790
800
|
for (const id of terms.keys()) bcast('pty-out', { term: id, b64: bye })
|
|
791
801
|
} catch { /* noop */ }
|
|
792
|
-
|
|
802
|
+
// Leave presence EXPLICITLY before exiting so the web room flips to dormant
|
|
803
|
+
// immediately. Previously we removeChannel()'d and process.exit()'d on the next
|
|
804
|
+
// line — the leave frame never flushed, so the web only noticed via the realtime
|
|
805
|
+
// heartbeat timeout (tens of seconds later) and looked stuck "live".
|
|
806
|
+
try { await channel.untrack() } catch { /* noop */ }
|
|
807
|
+
try { await supabase.removeChannel(channel) } catch { /* noop */ }
|
|
793
808
|
for (const t of terms.values()) { try { t.term.kill() } catch { /* noop */ } }
|
|
794
809
|
for (const s of sessions.values()) { try { s.session.end() } catch { /* noop */ } }
|
|
795
810
|
detachLocal()
|
|
796
|
-
process.exit(0)
|
|
811
|
+
setTimeout(() => process.exit(0), 250) // small grace for the leave/close frames to flush over the socket
|
|
797
812
|
}
|
|
798
813
|
process.on('SIGINT', shutdown)
|
|
799
814
|
process.on('SIGTERM', shutdown)
|