// In an isolated release flavor, verify a stale explicit tab ID never targets the active tab. // Usage: node dev-tools/native-stale-shortcut-check.mjs const port = Number(process.argv[2]); if (!Number.isInteger(port)) throw new Error('Invalid CDP port'); const sitePage = process.argv[3] ?? process.env.SITE_PAGE; if (!sitePage) throw new Error('A page of the site to open is required (argument 2 or SITE_PAGE)'); const list = await (await fetch(`http://127.0.0.1:${port}/json/list`)).json(); const target = list.find(item => item.type === 'page' && item.url.startsWith('http://tauri.localhost/')); if (!target) throw new Error('Shell CDP target not found'); const socket = new WebSocket(target.webSocketDebuggerUrl); await new Promise(resolve => { socket.onopen = resolve; }); let serial = 0; const pending = new Map(); socket.onmessage = event => { const message = JSON.parse(event.data); if (message.id) { pending.get(message.id)?.(message); pending.delete(message.id); } }; const evaluate = expression => new Promise((resolve, reject) => { const id = ++serial; const timer = setTimeout(() => { pending.delete(id); reject(new Error('Shell CDP timed out')); }, 30_000); pending.set(id, message => { clearTimeout(timer); if (message.result?.exceptionDetails) reject(new Error(JSON.stringify(message.result.exceptionDetails).slice(0, 500))); else resolve(message.result?.result?.value); }); socket.send(JSON.stringify({ id, method: 'Runtime.evaluate', params: { expression, awaitPromise: true, returnByValue: true } })); }); try { const result = await evaluate(`(async () => { const ids = () => [...document.querySelectorAll('.dv-tabs-container .dv-tab .bt-tab[data-panel-id]')] .map(tab => tab.dataset.panelId); const before = ids(); if (before.length !== 1) throw new Error('Expected one isolated initial tab'); await window.__TAURI__.event.emit('tab-open', { url: ${JSON.stringify(sitePage)}, background: true }); const waitFor = async count => { const deadline = performance.now() + 10_000; while (ids().length !== count && performance.now() < deadline) await new Promise(resolve => setTimeout(resolve, 50)); if (ids().length !== count) throw new Error('Timed out waiting for ' + count + ' tabs'); }; await waitFor(2); const created = ids().find(id => !before.includes(id)); await window.__TAURI__.event.emit('tab-shortcut', { id: created, shortcut: 'close-tab' }); await waitFor(1); for (const shortcut of ['close-tab', 'split-right', 'open-panel']) { await window.__TAURI__.event.emit('tab-shortcut', { id: created, shortcut }); await new Promise(resolve => setTimeout(resolve, 200)); if (ids().join() !== before.join()) throw new Error('Stale ' + shortcut + ' changed live tabs'); } return { before, created, after: ids(), staleShortcuts: ['close-tab', 'split-right', 'open-panel'] }; })()`); console.log(JSON.stringify(result)); } finally { socket.close(); }