Araç çubuğu:
- Socket ID → kopyalanabilir kart (tıkla → clipboard, yeşil flash)
- "Ana" butonu kaldırıldı (kafakarıştırıcıydı, Miller kolon kendisi navigasyon sağlıyor)
- Durum mesajı sağda kaldı
Modal sistemi (_showModal):
- Başlık + label'lı input alanları + İptal/Tamam butonları
- Arka plana tıkla veya ✕ ile kapat
- Enter → onayla, Esc → kapat
- İlk alana otomatik focus
Eşler kolonu:
- "ID ile ara" → prompt() yerine modal
- Alan: Socket ID, placeholder: 'xxxxxxxx-xxxx-…'
Odalar kolonu:
- "Oda Oluştur" (primary buton) → modal
- Alanlar: oda adı + opsiyonel şifre
- Oluşturunca oda kolonunu yeniler
style.css:
- .mwse-id-card + __label/__value/__copy + --copied
- .mwse-modal-overlay / .mwse-modal / __header/__body/__field/__footer/__input/__close
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
sdk/index.js — bağlantı hatası düzeltildi:
- new MWSE() options=undefined → TypeError patlaması
- constructor(options) → opts = { endpoint:'auto', ...options }
- Artık new MWSE() / new MWSE('ws://host') / new MWSE({…}) hepsi çalışıyor
public/studio/Studio.js — tamamen yeniden yazıldı:
Eşler kolonu:
- mwse.pairs'ten gerçek eşleri gösteriyor
- Her eş için: Video+Ses / Sesli Ara / Ekran Paylaş / Kamera Seç /
Mikrofon Seç / Dosya Gönder / Aktif Akışlar / Eşleşmeyi Bitir
- "ID ile ara" → prompt ile direkt peer ID girerek requestPair()
Odalar kolonu: mwse.rooms'tan oda + üye listesi
Cihazlar kolonu:
- MediaSources.devices() ile kamera ve mikrofon listesi
- Her cihaza tıkla → seçili eşe akış başlat veya önizle (floating video)
- İzin İste butonu → izin alındıktan sonra listeyi yenile
Akışlar kolonu: peer.rtc._streams.list() canlı gösterimi
Kalite kolonu: Yüksek/Orta/Düşük preset + mute/stop
Araç çubuğu: socket ID, durum mesajı, Ana butonu (popTo(0))
Gelen track'ler: audio otomatik çalınır, status bar bildirir
Cihaz önizleme: floating video element (✕ ile kapatılır)
public/studio/app.js: studio.mount() await ile çağrılıyor
go test -race ./... — yeşil
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- /script → /sdk/index.js ES modül import örnekleri
- WebRTC API kullanım örneği (connect/addStream/track/sendFile)
- Studio UI kullanım örneği
- Env değişkenleri tablosu (MWSE_HOST/PORT/PUBLIC_DIR/SDK_DIR vs.)
- Mimari şeması: sdk/webrtc/ ve sdk/studio/ alt klasörleriyle güncellendi
- Durum tablosu: sanal IP alt ağı, WebRTC kütüphanesi, Studio UI eklendi
- TypeScript / npm / Parcel referansları kaldırıldı
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
sdk/webrtc/CanvasCompositor.js (#38):
- Gelen video track'lerini tek canvas'ta birleştirme (grid/pip/side-by-side/focus)
- OffscreenCanvas öncelikli (DOM gerektirmiyor), yoksa <canvas> kullanır
- setFPS(), setLayout(), setFocus() ile runtime kontrol
- stream() → MediaStream; StreamManager.addStream('composite', ...) ile gönderilir
- setEncodings() ile bitrate/fps zaten StreamManager üzerinden destekleniyor
sdk/webrtc/index.js: CanvasCompositor re-export eklendi
public/demos/ (#34): Tüm demo'lar yeni SDK API'sine güncellendi:
- <script src="/script"> → <script type="module"> import MWSE from '/sdk/index.js'
- new MWSE() (endpoint otomatik import.meta.url'den alınıyor)
- rtc.connect({ polite }) ile perfect negotiation polite/impolite tayini
- rtc.addStream() / rtc.on('track') yeni API
- rtc.on('failed') durumu gösteriliyor
- window.send() module scope sorununu çözüyor (onclick handler)
go test -race ./... — tüm testler yeşil
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
sdk/webrtc/ — kapsamlı RTCEngine kütüphanesi:
- PeerConnection.js: RTCPeerConnection wrapper; connectionstatechange +
iceconnectionstatechange her ikisi de izleniyor (eski 'bağlantı kopsa
fark etmez' hatası bu şekilde önleniyor)
- Negotiator.js: perfect negotiation (RFC 8829); polite/impolite roller,
teklif çakışması rollback, ICE adayları sıraya alınıyor
- StreamManager.js: addStream/replaceTrack/removeStream/setEncodings —
runtime'da track ekle/çıkar/değiştir, yeniden müzakere gerekmiyor
- DataChannel.js: birincil veri kanalı, bağlantı canlıyken kapanırsa
otomatik yeniden oluşturulur, açılana kadar mesaj kuyruğu
- MediaSources.js: camera/microphone/screen/cameraAndMic fabrika metodları,
AudioBuffer→MediaStream, canvas.captureStream, AudioContext mix bus
- FileSender.js: en fazla 5 paralel DataChannel üzerinden dosya transferi,
progress olayı, 16 KB chunk + bufferedAmountLow akış kontrolü
- index.js (RTCEngine): tüm alt sistemleri koordine eder; ICE restart
exponential backoff (1s→2s→4s); Peer.js ile geriye dönük uyumlu
sdk/WebRTC.js → ./webrtc/index.js'e ince re-export (Peer.js değişmedi)
sdk/studio/ — masaüstü-first Miller-kolon UI (#47):
- Column.js: başlık + arama filtresi + öğe listesi
- ColumnView.js: yatay kayan kolon yöneticisi, popTo() ile derine git
- index.js (Studio): Server→Groups→Peers→Devices→Streams→Quality hiyerarşisi;
WebRTC bağlantısını otomatik başlatır (polite = küçük socketId)
- style.css: koyu masaüstü teması, aktif öğe vurgusu, ilerleme çubuğu
internal/services/ippressure.go — rastgele atama + sub-network (#40/#41):
- lockIP/lockNumber/lockCode: önce 256 rastgele deneme, sonra sıralı yedek;
yüksek bağlantı sayısında O(1) ortalama atama
- SubNet: /24 sanal alt ağ (10.A.B.0/24); Alloc/Release/Whois metodları
- alloc|release|whois APSubNet + APSubNetIP HTTP handler'ları eklendi
- Bağlantı kesildiğinde subnet IP'leri ve prefix otomatik serbest bırakılıyor
sdk/IPPressure.js: allocSubNet/releaseSubNet/allocSubNetIP/releaseSubNetIP/
querySubNetIP metodları eklendi
go test -race ./... — tüm testler yeşil
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Sinyalleşme (offer/answer/ICE) ayrı bir engine kavramı değil; SDK bunları
{type:':rtcpack:', payload} olarak pack/to üzerinden tüneller (Node ile aynı,
sunucuda RTC handler'ı yok). Engine bu paketleri her iki yönde de payload'ı
incelemeden aynen taşır. Test: TestWebRTCSignalingRelay.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Engine: dispatcher handler nil dönerse yanıt göndermez (nil = yanıt yok /
cevap out-of-band gelecek). Bu, request/to'nun erken [null,id,'E'] ile
ezilmesini önler; gerçek cevap response/to ile aynı id üzerinden gelir.
SDK: EventPool.only() WOM yolu eklendi (waiter bırakmaz); Peer.send ve
Room.send handshake'siz dalı request() yerine only() kullanır. Public API
değişmedi.
Test: TestServerNoReplyOnNilResult, TestRequestResponseRoundTrip,
TestTunnelDoesNotLeakSourceAddress, TestTunnelLargePayloadIntact. go test -race yeşil.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
CLAUDE.md (operating contract), todo.md (roadmap), tools/gitea CLI ve
.gitea-auth.example.json depoya eklendi. Gerçek .gitea-auth.json gitignore'da.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>