/** * Glare = both peers initiate at the same instant. The manager resolves * deterministically: the address with the lexically-larger value yields * to the smaller one's offer. */ import { afterEach, describe, expect, it } from 'bun:test'; import { MemoryRtcFactory } from '../src/memory-rtc.js'; import { MemoryShadeBridge, WebRtcSignalingChannel } from '../src/signaling.js'; import { WebRtcConnectionManager } from '../src/manager.js'; afterEach(() => { MemoryRtcFactory.reset(); }); describe('Glare resolution', () => { it('two simultaneous getOrCreate() calls converge on a single connection', async () => { const { a, b } = MemoryShadeBridge.linked('alice', 'bob'); const aliceSig = new WebRtcSignalingChannel(a); const bobSig = new WebRtcSignalingChannel(b); const factory = new MemoryRtcFactory(); const alice = new WebRtcConnectionManager({ factory, signaling: aliceSig }); const bob = new WebRtcConnectionManager({ factory, signaling: bobSig, receiver: { async onChunk() { return { lastSeq: 0 }; }, async onResumeQuery() { return null; }, }, }); // Both kick off at once. const [aConn, bConn] = await Promise.all([ alice.getOrCreate('bob'), bob.getOrCreate('alice'), ]); expect(aConn.state).toBe('connected'); expect(bConn.state).toBe('connected'); expect(alice.isConnected('bob')).toBe(true); expect(bob.isConnected('alice')).toBe(true); alice.destroy(); bob.destroy(); }); });