AITURK IDE 1.0.0-beta.17: telefon kodu yayini yeniden denenir

Uzun sure acik kalan IDE'de "Telefon ekle" ilk istegi olu bir keep-alive
baglantisinda kaybedebiliyordu; bulusma kaydi yayinlanamayinca kod yolu bes
dakika boyunca "Kodla baglanma su an kullanilamiyor" kaliyordu (QR calisiyordu).

- publishPairOffer: en cok 4 deneme (0,5 / 1,5 / 3 sn); ag hatasi, 5xx ve 429
  yeniden denenir, 422 kalicidir; yaniti kaybolan denemeden sonraki 409 kaydin
  yerinde oldugu anlamina gelir (iptal jetonu yoktur, kayit kendiliginden biter).
- Pencerede "Yeniden dene": ayni kod ve QR ile kaydi yeniden yayinlar.
- Role oturumu kaydi ve "Giris yap" baslangici icin tek ek deneme (zaman asimi
  yeniden denenmez).
- Gunluge yalniz "pair offer published / failed after N tries" duser; kod,
  lookup ve jeton yazilmaz.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01B8ppceaR5s6cvMnm7uGRnf
This commit is contained in:
yilsemandClaude Opus 5.5 committed 2026-10-05 14:27:59 +03:00
1 parent 2ed9a6b2de
commit 58dbb4523b
13 files changed
+729 -76

No files matched your search

@@ -28,6 +28,7 @@ import {
createRelayClient,
encodeRelayFrame,
isRelayId,
MOBILE_NETWORK_RETRY_DELAY_MS,
parseRelaySession,
registerRelaySession,
RELAY_BACKOFF_MS,
@@ -925,10 +926,15 @@ describe('relay client', () => {
})
it('a failing registration is a fixed code (no upstream text) and is retried; renew() swaps the registration only when the new one is stored', async () => {
const h = clientHarness({ sessions: ['throw', 429, 500, 201, 500, 201] })
const h = clientHarness({ sessions: ['throw', 'throw', 429, 500, 201, 500, 201] })
h.client.start()
await h.settle()
// A thrown network error gets one more try 0.5 s later; until then nothing is reported as failed.
expect(h.client.state()).toEqual({ status: 'connecting', code: null })
h.fire(500)
await h.settle()
expect(h.fetches).toHaveLength(2)
expect(h.client.state()).toEqual({ status: 'failed', code: 'register_failed' })
expect(h.sockets).toHaveLength(0)
h.fire(2000)
@@ -982,6 +988,60 @@ describe('relay client', () => {
broken.stop()
})
it('registration: a thrown network error is tried once more after 0.5 s; an HTTP answer or a timeout is not', async () => {
const h = clientHarness({ sessions: ['throw', 201] })
const pending = h.client.ensureRegistered()
await h.settle()
expect(h.fetches).toHaveLength(1)
expect(h.timers.map(timer => timer.ms)).toEqual([MOBILE_NETWORK_RETRY_DELAY_MS])
expect(MOBILE_NETWORK_RETRY_DELAY_MS).toBe(500)
h.fire(500)
expect(await pending).toBe(RELAY_IDS[0])
expect(h.fetches).toHaveLength(2)
expect(h.fetches[1].init.signal).not.toBe(h.fetches[0].init.signal)
expect(h.saved).toEqual([{ credentials: { relayId: RELAY_IDS[0], hostToken: HOST_TOKENS[0] }, reissued: false }])
// The function itself: exactly one extra try, only for a thrown error.
const sleeps: number[] = []
const run = async (outcomes: (number | 'throw' | 'timeout')[]) => {
let calls = 0
const result = await registerRelaySession(
async () => {
const outcome = outcomes[calls++] ?? 201
if (outcome === 'throw') {
throw new TypeError('fetch failed')
}
if (outcome === 'timeout') {
throw new DOMException('The operation was aborted due to timeout', 'TimeoutError')
}
return { status: outcome, json: async () => ({ relayId: RELAY_IDS[0], hostToken: HOST_TOKENS[0] }) }
},
{
sleep: async ms => {
sleeps.push(ms)
}
}
)
return { result, calls }
}
expect(await run(['throw', 201])).toEqual({ result: { relayId: RELAY_IDS[0], hostToken: HOST_TOKENS[0] }, calls: 2 })
expect(await run(['throw', 'throw', 201])).toEqual({ result: { error: 'register_failed' }, calls: 2 })
expect(await run(['throw', 429])).toEqual({ result: { error: 'rate_limited' }, calls: 2 })
expect(sleeps).toEqual([500, 500, 500])
expect(await run([500, 201])).toEqual({ result: { error: 'register_failed' }, calls: 1 })
expect(await run([429, 201])).toEqual({ result: { error: 'rate_limited' }, calls: 1 })
expect(await run(['timeout', 201])).toEqual({ result: { error: 'register_failed' }, calls: 1 })
expect(sleeps).toHaveLength(3)
})
it('streams: opened / close, bytes copied untouched in ≤ 64 KiB frames, unknown ids ignored, stream and buffer limits', async () => {
const h = clientHarness({ stored: { relayId: RELAY_IDS[0], hostToken: HOST_TOKENS[0] } })