thinkpool-pair 0.6.21 → 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 +25 -4
- 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
|
|
@@ -770,12 +780,18 @@ if (process.env.THINKPOOL_PAIR_AUTOUPDATE === '1' && VERSION) {
|
|
|
770
780
|
const a = core(latest), b = core(VERSION)
|
|
771
781
|
let newer = false
|
|
772
782
|
for (let i = 0; i < 3; i++) { if ((a[i] || 0) > (b[i] || 0)) { newer = true; break } if ((a[i] || 0) < (b[i] || 0)) break }
|
|
773
|
-
if (newer) process.stderr.write(
|
|
783
|
+
if (newer) process.stderr.write(
|
|
784
|
+
`\n ◆ thinkpool-pair ${latest} is out (you're on ${VERSION}).\n` +
|
|
785
|
+
` To update: stop this bridge (Ctrl-C), then rerun:\n` +
|
|
786
|
+
` npx thinkpool-pair@latest ${room}\n` +
|
|
787
|
+
` Your session resumes on restart (you'll be asked to continue it).\n` +
|
|
788
|
+
` For hands-off updates with no interruption, install the background\n` +
|
|
789
|
+
` service: npx thinkpool-pair@latest install-service ${room}\n`)
|
|
774
790
|
} catch { /* offline — never block the session */ }
|
|
775
791
|
}, 60000).unref()
|
|
776
792
|
}
|
|
777
793
|
|
|
778
|
-
function shutdown() {
|
|
794
|
+
async function shutdown() {
|
|
779
795
|
if (shuttingDown) return
|
|
780
796
|
shuttingDown = true
|
|
781
797
|
clearInterval(flushTimer)
|
|
@@ -783,11 +799,16 @@ function shutdown() {
|
|
|
783
799
|
const bye = Buffer.from('\r\n[ shared session ended ]\r\n', 'utf8').toString('base64')
|
|
784
800
|
for (const id of terms.keys()) bcast('pty-out', { term: id, b64: bye })
|
|
785
801
|
} catch { /* noop */ }
|
|
786
|
-
|
|
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 */ }
|
|
787
808
|
for (const t of terms.values()) { try { t.term.kill() } catch { /* noop */ } }
|
|
788
809
|
for (const s of sessions.values()) { try { s.session.end() } catch { /* noop */ } }
|
|
789
810
|
detachLocal()
|
|
790
|
-
process.exit(0)
|
|
811
|
+
setTimeout(() => process.exit(0), 250) // small grace for the leave/close frames to flush over the socket
|
|
791
812
|
}
|
|
792
813
|
process.on('SIGINT', shutdown)
|
|
793
814
|
process.on('SIGTERM', shutdown)
|