@minicode-dev/chat 0.1.11 → 0.1.13

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.
Files changed (33) hide show
  1. package/README.md +102 -6
  2. package/assets/sounds/effects/avalanche.mp3 +0 -0
  3. package/dist/chunks/{TanksGameCard-B47ZQcSr.js → TanksGameCard-GrqmdwJ7.js} +2 -2
  4. package/dist/chunks/{TanksGameCard-B47ZQcSr.js.map → TanksGameCard-GrqmdwJ7.js.map} +1 -1
  5. package/dist/chunks/TanksLiveGameCard-DSmQcUMh.js +1225 -0
  6. package/dist/chunks/TanksLiveGameCard-DSmQcUMh.js.map +1 -0
  7. package/dist/chunks/{WebRtcLab-lijo_Rta.js → WebRtcLab-ClRSYt4E.js} +2 -2
  8. package/dist/chunks/{WebRtcLab-lijo_Rta.js.map → WebRtcLab-ClRSYt4E.js.map} +1 -1
  9. package/dist/chunks/avalancheScene3d-Dnl2E3EA.js +1878 -0
  10. package/dist/chunks/avalancheScene3d-Dnl2E3EA.js.map +1 -0
  11. package/dist/chunks/createLiveScene-819NWv84.js +365 -0
  12. package/dist/chunks/createLiveScene-819NWv84.js.map +1 -0
  13. package/dist/chunks/createPeerLink-DBVs_yvQ.js +1136 -0
  14. package/dist/chunks/createPeerLink-DBVs_yvQ.js.map +1 -0
  15. package/dist/chunks/{createTankScene-CV7Brxmt.js → createTankScene-6asWHKFf.js} +120 -119
  16. package/dist/chunks/{createTankScene-CV7Brxmt.js.map → createTankScene-6asWHKFf.js.map} +1 -1
  17. package/dist/chunks/fx-BNJvJYOu.js +871 -0
  18. package/dist/chunks/fx-BNJvJYOu.js.map +1 -0
  19. package/dist/chunks/tank-DIn6Jyt8.js +605 -0
  20. package/dist/chunks/tank-DIn6Jyt8.js.map +1 -0
  21. package/dist/index.js +1581 -1184
  22. package/dist/index.js.map +1 -1
  23. package/dist/styles.css +1 -1
  24. package/index.d.ts +23 -3
  25. package/package.json +1 -1
  26. package/dist/chunks/TanksLiveGameCard-BNJqWt1z.js +0 -915
  27. package/dist/chunks/TanksLiveGameCard-BNJqWt1z.js.map +0 -1
  28. package/dist/chunks/createLiveScene-CJQtq54t.js +0 -364
  29. package/dist/chunks/createLiveScene-CJQtq54t.js.map +0 -1
  30. package/dist/chunks/createPeerLink-CL7VZuHS.js +0 -480
  31. package/dist/chunks/createPeerLink-CL7VZuHS.js.map +0 -1
  32. package/dist/chunks/fx-BHsl4S_J.js +0 -1470
  33. package/dist/chunks/fx-BHsl4S_J.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createPeerLink-DBVs_yvQ.js","names":["ID","WEBRTC_PREFIX","MAX_SIGNAL_LENGTH","SIGNAL_TYPES","ID$1","MAX_CANDIDATES","isWebrtcMessage","text","validData","d","t","c","isValidSignal","signal","encodeSignal","decodeSignal","newSignalId","MAX_SERVERS","MAX_URLS","MAX_SECRET_LENGTH","MAX_TTL_SECONDS","object","value","own","key","error","message","secret","rejectPermanentSecrets","entry","validHost","host","part","label","validateUrl","match","parseExpiry","values","source","field","seconds","now","parseManualTurnConfig","input","root","stack","depth","config","count","hasTurn","iceServers","server","urls","turn","output","expirations","ttlSeconds","expiresAt","result","ID","MAX_COMPLETED","fixedError","reasons","b64","bytes","unb64","max","policy","createManualTurnSharing","selfId","peerId","roomId","peerTab","active","destroyed","queue","completed","state","publish","patch","onChange","current","tx","available","cryptoImpl","tabId","nextId","aad","from","to","op","remember","clear","fail","notifyPeer","send","reason","replyTo","data","sendSignal","make","timeoutMs","initiatedHere","finish","keys","pair","derive","raw","publicKey","remoteKey","encrypt","iv","cipher","decrypt","payload","validExpiry","apply","applyConfig","rejectOther","process","old","authority","reply","encrypted","applied","commitConfig","cause","iceTransportPolicy","promise","resolve","reject","bound","ensurePeer","sid","DEFAULT_ICE_SERVERS","RETRY_MS","MAX_TRIES","HELLO_EVERY_MS","HELLO_GIVE_UP_MS","ICE_BATCH_MS","DISCONNECTED_GRACE_MS","CONNECT_TIMEOUT_MS","PING_EVERY_MS","HEARTBEAT_TIMEOUT_MS","MAX_RESTARTS","MAX_RECONNECTS","MAX_BUFFERED","MAX_SEEN","emptyMoveStats","ROUTE_LABELS","createPeerLink","signaling","activeIceServers","activeIcePolicy","credentialExpiresAt","boundPeerTab","boundSid","manual","controlOutbox","peerWaiters","configurationAuthority","servers","url","listening","listen","session","reconnects","reconnectTimer","endedSid","seen","emit","snapshot","setPhase","phase","log","rawSend","failed","s","mid","reliable","retry","handleFrame","frame","manualBusy","call","sendControl","clearControls","bindPeer","waiter","healthy","recreatePeer","restartIce","armConnectTimeout","scheduleReconnect","unsubscribe","newSession","teardown","bye","recover","timer","channel","autoReconnect","delay","wasCaller","bindState","createPc","RTCPeerConnectionImpl","pc","ufrag","candidate","currentUfrag","flushLocalIce","event","onIceState","onChannelOpen","lose","onMoveMessage","onEventMessage","generations","item","gen","batch","i","addRemoteIce","candidates","flushPendingIce","ready","makeOffer","offer","iceRestart","manualCommit","maybeConnected","ice","refreshStats","ping","tick","sendRaw","onEvent","packet","seq","m","onMove","expected","report","byId","local","remote","relay","type","onAck","control","onHello","glare","onReady","onOffer","answer","onAnswer","onIce","onBye","shouldCall","hello","options","sent"],"sources":["../../src/net/webrtc/protocol.js","../../src/net/webrtc/manualTurnConfig.js","../../src/net/webrtc/manualTurnSharing.js","../../src/net/webrtc/createPeerLink.js"],"sourcesContent":["// WebRTC signaling frames carried inside ordinary CHAT_MESSAGE text, the same idea\n// as LIRA_GAME_V1:. The chat backend only relays them; the sender is the\n// server-stamped user_id of the envelope, never a field of the payload.\n//\n// LIRA_WEBRTC_V1:{\"v\":1,\"t\":\"offer\",\"sid\":\"…\",\"gen\":0,\"mid\":\"…\",\"from\":\"tab\",\"to\":\"tab\",\"d\":{…}}\n//\n// t: hello (call, to = null) | ready (reply to hello) | offer | answer | ice | ack | bye\n// sid: session id chosen by the caller; gen: negotiation round (ICE restarts);\n// mid: message id for ACK/dedupe; from/to: tab ids, so several tabs of one user\n// and the server echo to the sender are told apart; at: sender clock (ms), only\n// compared with earlier frames of the same tab to spot late, stale calls.\n\nexport const WEBRTC_PREFIX = 'LIRA_WEBRTC_V1:';\n// Backend limit for CHAT_MESSAGE.message (Django audit). Frames above it are refused locally.\nexport const MAX_SIGNAL_LENGTH = 10000;\nexport const SIGNAL_TYPES = ['hello', 'ready', 'offer', 'answer', 'ice', 'ack', 'bye', 'turn'];\n\nconst ID = /^[A-Za-z0-9_-]{4,64}$/;\nconst MAX_CANDIDATES = 32;\n\nexport const isWebrtcMessage = (text) => typeof text === 'string' && text.startsWith(WEBRTC_PREFIX);\n\nconst validData = (t, d) => {\n if (d == null) return ['hello', 'ready', 'bye'].includes(t);\n if (typeof d !== 'object' || Array.isArray(d)) return false;\n switch (t) {\n case 'offer':\n case 'answer':\n return typeof d.sdp === 'string' && d.sdp.length > 0;\n case 'ice':\n return Array.isArray(d.c) && d.c.length <= MAX_CANDIDATES\n && d.c.every((c) => c === null || (c && typeof c.candidate === 'string'));\n case 'turn':\n if (!['key_request', 'key_reply', 'proposal', 'prepare', 'prepared', 'commit', 'committed', 'done', 'reject', 'reconnect'].includes(d.op)) return false;\n if (['key_request', 'key_reply'].includes(d.op)) return typeof d.publicKey === 'string' && /^[A-Za-z0-9+/=]{80,100}$/.test(d.publicKey);\n if (['proposal', 'prepare'].includes(d.op)) return typeof d.iv === 'string' && /^[A-Za-z0-9+/=]{16}$/.test(d.iv) && typeof d.cipher === 'string' && d.cipher.length <= 8200 && /^[A-Za-z0-9+/=]+$/.test(d.cipher);\n if (d.recreate !== undefined && typeof d.recreate !== 'boolean') return false;\n return d.reason === undefined || ['busy', 'invalid', 'expired', 'unavailable', 'timeout'].includes(d.reason);\n case 'ack':\n return typeof d.of === 'string' && ID.test(d.of);\n default:\n return true;\n }\n};\n\nexport function isValidSignal(signal) {\n return Boolean(signal) && typeof signal === 'object'\n && signal.v === 1\n && SIGNAL_TYPES.includes(signal.t)\n && typeof signal.sid === 'string' && ID.test(signal.sid)\n && typeof signal.mid === 'string' && ID.test(signal.mid)\n && typeof signal.from === 'string' && ID.test(signal.from)\n && (signal.to == null || (typeof signal.to === 'string' && ID.test(signal.to)))\n && Number.isInteger(signal.gen ?? 0) && (signal.gen ?? 0) >= 0\n && (signal.at == null || Number.isFinite(signal.at))\n && validData(signal.t, signal.d);\n}\n\n/** Returns the frame text, or null when it would exceed MAX_SIGNAL_LENGTH. */\nexport function encodeSignal(signal) {\n const text = WEBRTC_PREFIX + JSON.stringify({ v: 1, ...signal });\n return text.length <= MAX_SIGNAL_LENGTH ? text : null;\n}\n\nexport function decodeSignal(text) {\n if (!isWebrtcMessage(text) || text.length > MAX_SIGNAL_LENGTH) return null;\n try {\n const signal = JSON.parse(text.slice(WEBRTC_PREFIX.length));\n return isValidSignal(signal) ? signal : null;\n } catch {\n return null;\n }\n}\n\nexport const newSignalId = () => {\n try {\n if (globalThis.crypto?.randomUUID) return globalThis.crypto.randomUUID().replace(/-/g, '').slice(0, 20);\n } catch { /* fallback below */ }\n return `${Date.now().toString(36)}${Math.random().toString(36).slice(2, 12)}`;\n};\n\n// Normalizes a chat frame (flat or nested in data/payload) to { userId, roomId, text }.\nexport function readChatFrame(frame) {\n if (!frame || typeof frame !== 'object') return null;\n const nested = frame.data ?? frame.payload;\n const body = nested && typeof nested === 'object' ? { ...nested, ...frame } : frame;\n const text = frame.message ?? frame.text ?? nested?.message ?? nested?.text;\n if (typeof text !== 'string') return null;\n return { userId: String(body.user_id ?? ''), roomId: String(body.room_id ?? ''), text };\n}\n","/** Validate pasted temporary ICE credentials. Never retain or report the original input. */\nexport const MAX_MANUAL_TURN_LENGTH = 6000;\nconst MAX_SERVERS = 8;\nconst MAX_URLS = 16;\nconst MAX_SECRET_LENGTH = 512;\nconst MAX_TTL_SECONDS = 48 * 60 * 60;\nconst object = value => value !== null && typeof value === 'object' && !Array.isArray(value);\nconst own = (value, key) => Object.prototype.hasOwnProperty.call(value, key);\nconst error = message => { throw new Error(message); };\nconst secret = value => typeof value === 'string' && value.trim().length > 0\n && value.length <= MAX_SECRET_LENGTH && !/[\\u0000-\\u001f\\u007f]/.test(value);\n\nfunction rejectPermanentSecrets(value) {\n if (!object(value) && !Array.isArray(value)) return;\n for (const [key, entry] of Object.entries(value)) {\n // API authentication belongs in the operator's terminal, never in this modal.\n if (/^(?:api[_-]?(?:token|key|secret)|authorization|bearer|token|secret|secret[_-]?key|access[_-]?token|refresh[_-]?token|turn[_-]?key[_-]?api[_-]?token)$/i.test(key)) {\n error('No pegues tokens API ni secretos permanentes. Utiliza solamente credenciales TURN temporales.');\n }\n rejectPermanentSecrets(entry);\n }\n}\n\nfunction validHost(host) {\n if (host.startsWith('[')) {\n try { return host.endsWith(']') && new URL(`http://${host}/`).hostname.startsWith('['); }\n catch { return false; }\n }\n if (host.length > 253) return false;\n if (/^[\\d.]+$/.test(host)) return host.split('.').length === 4\n && host.split('.').every(part => /^(?:0|[1-9]\\d{0,2})$/.test(part) && Number(part) <= 255);\n return host.split('.').every(label => /^[a-z\\d](?:[a-z\\d-]{0,61}[a-z\\d])?$/i.test(label));\n}\n\nfunction validateUrl(value) {\n if (typeof value !== 'string' || value.length > 512 || /\\s/.test(value)) error('Hay una URL ICE inválida. Usa URLs stun:, stuns:, turn: o turns:.');\n const match = /^(stun|stuns|turn|turns):((?:\\[[a-f\\d:.]+\\])|(?:[a-z\\d.-]+))(?::(\\d{1,5}))?(?:\\?transport=(udp|tcp))?$/i.exec(value);\n if (!match || !validHost(match[2]) || (match[3] !== undefined && (Number(match[3]) < 1 || Number(match[3]) > 65535))\n || (match[4] && !/^turns?$/i.test(match[1]))) {\n error('Hay una URL ICE inválida. Revisa el servidor, puerto y transporte UDP o TCP.');\n }\n return /^turns?$/i.test(match[1]);\n}\n\nfunction parseExpiry(source, now) {\n const values = [];\n if (own(source, 'expiresAt') && source.expiresAt !== null) {\n const value = typeof source.expiresAt === 'string' ? Date.parse(source.expiresAt) : source.expiresAt;\n if (!Number.isSafeInteger(value) || !Number.isFinite(new Date(value).getTime())) error('La fecha de expiración no es válida.');\n values.push(value);\n }\n for (const field of ['expiresIn', 'ttl']) {\n if (!own(source, field) || source[field] === null) continue;\n const seconds = source[field];\n if (!Number.isInteger(seconds) || seconds < 1 || seconds > MAX_TTL_SECONDS) error('El TTL debe estar entre 1 y 172800 segundos.');\n values.push(now + seconds * 1000);\n }\n return values;\n}\n\n/**\n * Accepts Cloudflare's { iceServers } response or a { result: { iceServers } } envelope.\n * expiresAt is ISO text or Unix milliseconds; expiresIn/ttl/ttlSeconds are remaining seconds.\n * Without supplied expiry metadata, expiration remains unknown. No username inference.\n */\nexport function parseManualTurnConfig(input, { ttlSeconds, now = Date.now() } = {}) {\n if (!Number.isSafeInteger(now) || !Number.isFinite(new Date(now).getTime())) error('No se pudo comprobar la vigencia de la configuración.');\n let text;\n try { text = typeof input === 'string' ? input : JSON.stringify(input); }\n catch { error('La configuración debe ser un objeto JSON válido.'); }\n if (typeof text !== 'string' || !text.trim()) error('Pega la configuración JSON de TURN.');\n if (text.length > MAX_MANUAL_TURN_LENGTH || new TextEncoder().encode(text).length > MAX_MANUAL_TURN_LENGTH) error('La configuración es demasiado grande (máximo 6000 caracteres).');\n let root;\n try { root = JSON.parse(text); }\n catch { error('El JSON no es válido. Copia la respuesta completa de credenciales TURN.'); }\n if (!object(root)) error('La configuración debe contener un objeto iceServers.');\n // Reject pathological nesting before walking arbitrary JSON fields.\n const stack = [[root, 0]];\n while (stack.length) {\n const [value, depth] = stack.pop();\n if (depth > 8) error('La configuración JSON contiene demasiados niveles.');\n if (object(value) || Array.isArray(value)) for (const entry of Object.values(value)) if (entry && typeof entry === 'object') stack.push([entry, depth + 1]);\n }\n rejectPermanentSecrets(root);\n if (root.success === false) error('La respuesta del proveedor indica un error. Obtén credenciales TURN válidas.');\n const config = object(root.result) ? root.result : root;\n if (!Array.isArray(config.iceServers) || config.iceServers.length < 1 || config.iceServers.length > MAX_SERVERS) error('iceServers debe contener entre 1 y 8 servidores ICE.');\n let count = 0;\n let hasTurn = false;\n const iceServers = config.iceServers.map(server => {\n if (!object(server)) error('Cada servidor ICE debe ser un objeto con URLs válidas.');\n const urls = typeof server.urls === 'string' ? [server.urls] : server.urls;\n if (!Array.isArray(urls) || !urls.length || urls.length > MAX_URLS) error('Cada servidor debe incluir al menos una URL ICE válida.');\n count += urls.length;\n if (count > MAX_URLS) error('La configuración admite hasta 16 URLs ICE.');\n const turn = urls.map(validateUrl).some(Boolean);\n const output = { urls: [...new Set(urls)] };\n if (turn) {\n hasTurn = true;\n if (!secret(server.username) || !secret(server.credential)) error('Cada servidor TURN necesita username y credential temporales válidos.');\n if (server.credentialType !== undefined && server.credentialType !== 'password') error('Solo se admiten credenciales TURN de tipo password.');\n output.username = server.username;\n output.credential = server.credential;\n }\n return output;\n });\n if (!hasTurn) error('La configuración solo contiene STUN. Incluye al menos un servidor TURN con sus credenciales.');\n const expirations = [...parseExpiry(root, now), ...(config === root ? [] : parseExpiry(config, now))];\n if (ttlSeconds !== undefined && ttlSeconds !== null && ttlSeconds !== '') {\n if (!Number.isInteger(ttlSeconds) || ttlSeconds < 1 || ttlSeconds > MAX_TTL_SECONDS) error('El TTL debe estar entre 1 y 172800 segundos.');\n expirations.push(now + ttlSeconds * 1000);\n }\n const expiresAt = expirations.length ? Math.min(...expirations) : null;\n if (expiresAt !== null && !Number.isFinite(new Date(expiresAt).getTime())) error('La fecha de expiración no es válida.');\n if (expiresAt !== null && expiresAt <= now) error('Las credenciales TURN han expirado. Genera y pega una configuración nueva.');\n const result = { iceServers, expiresAt };\n if (new TextEncoder().encode(JSON.stringify(result)).length > MAX_MANUAL_TURN_LENGTH) error('La configuración es demasiado grande para compartirla de forma segura.');\n return result;\n}\n","import { parseManualTurnConfig } from './manualTurnConfig.js';\n\nconst ID = /^[a-z\\d_-]{4,64}$/i;\nconst MAX_COMPLETED = 32;\nconst fixedError = 'No se pudo sincronizar la conexión alternativa. Revisa las credenciales e inténtalo de nuevo.';\nconst reasons = {\n busy: 'El otro jugador ya está configurando una conexión alternativa. Espera a que termine.',\n timeout: 'El otro jugador no confirmó la configuración a tiempo. Mantengan abierta la partida e inténtalo de nuevo.',\n expired: 'Las credenciales TURN han expirado. Genera y pega una configuración nueva.',\n unavailable: 'No se pudo preparar el intercambio seguro. Usa HTTPS y mantén abierta la partida.',\n invalid: fixedError,\n};\nconst b64 = bytes => btoa(String.fromCharCode(...new Uint8Array(bytes)));\nconst unb64 = (text, max) => {\n if (typeof text !== 'string' || text.length > max || text.length % 4 || !/^[a-z\\d+/]+={0,2}$/i.test(text)) throw new Error(fixedError);\n return Uint8Array.from(atob(text), c => c.charCodeAt(0));\n};\nconst policy = value => {\n if (value !== 'all' && value !== 'relay') throw new Error('La política ICE debe ser all o relay.');\n return value;\n};\n\n/**\n * Ephemeral ECDH/AES-GCM control plane, independent of a particular PeerConnection.\n * Only sanitized states leave onChange; credentials and private keys never leave memory.\n * sendSignal carries reliable, addressed `turn` frames through the existing private relay.\n */\nexport function createManualTurnSharing({\n authority, selfId, peerId, roomId, tabId, sendSignal, applyConfig, commitConfig,\n onChange = () => {}, ensurePeer, cryptoImpl = globalThis.crypto, timeoutMs = 20000,\n}) {\n selfId = String(selfId); peerId = String(peerId); roomId = String(roomId);\n let peerTab = null;\n let active = null;\n let destroyed = false;\n let queue = Promise.resolve();\n const completed = new Map();\n let state = { status: 'idle', shared: false, received: false, expiresAt: null, error: null };\n const publish = patch => {\n state = { ...state, ...patch };\n if (!destroyed) onChange({ ...state });\n };\n const current = tx => !destroyed && active === tx && !tx.closed;\n const available = () => {\n if (!cryptoImpl?.subtle || !cryptoImpl?.getRandomValues || !ID.test(tabId) || !roomId || !selfId || !peerId || selfId === peerId) throw new Error(reasons.unavailable);\n };\n const nextId = () => [...cryptoImpl.getRandomValues(new Uint8Array(16))].map(value => value.toString(16).padStart(2, '0')).join('');\n const aad = (tx, from, to, op) => new TextEncoder().encode(JSON.stringify([roomId, ...[selfId, peerId].sort(), tx.sid, from, to, op]));\n const remember = tx => {\n completed.set(tx.sid, { peerTab: tx.peerTab, replies: tx.replies });\n if (completed.size > MAX_COMPLETED) completed.delete(completed.keys().next().value);\n };\n const clear = tx => {\n clearTimeout(tx.timer);\n tx.closed = true;\n tx.config = tx.keyPair = tx.sharedKey = null;\n if (active === tx) active = null;\n };\n const fail = (tx, reason = 'invalid', notifyPeer = false) => {\n if (!current(tx)) return;\n if (notifyPeer && tx.peerTab) send(tx, { op: 'reject', reason });\n remember(tx);\n clear(tx);\n publish({ status: 'failed', error: reasons[reason] || fixedError });\n tx.reject?.(new Error(reasons[reason] || fixedError));\n };\n const send = (tx, data, replyTo) => {\n if (destroyed || !tx.peerTab) return;\n if (replyTo) tx.replies.set(replyTo, data);\n try {\n const result = sendSignal(tx.sid, data, tx.peerTab);\n if (result === false || result === null) fail(tx, 'unavailable');\n else if (result && typeof result.then === 'function') void result.catch(() => fail(tx, 'unavailable'));\n } catch { fail(tx, 'unavailable'); }\n };\n const make = (sid, initiatedHere, config = null) => {\n const tx = { sid, initiatedHere, peerTab, config, stage: 'starting', replies: new Map(), keyPair: null, sharedKey: null, closed: false, timer: null };\n active = tx;\n tx.timer = setTimeout(() => fail(tx, 'timeout', true), timeoutMs);\n publish({ status: initiatedHere && !peerTab ? 'waiting_peer' : 'sharing', shared: false, received: false, expiresAt: config?.expiresAt ?? null, error: null });\n return tx;\n };\n const finish = tx => {\n if (!current(tx)) return;\n const expiresAt = tx.config?.expiresAt ?? null;\n remember(tx);\n clear(tx);\n publish({ status: 'synchronized', shared: true, received: state.received, expiresAt, error: null });\n tx.resolve?.({ expiresAt });\n };\n const keys = async tx => {\n const pair = await cryptoImpl.subtle.generateKey({ name: 'ECDH', namedCurve: 'P-256' }, false, ['deriveKey']);\n if (!current(tx)) return null;\n tx.keyPair = pair;\n tx.publicKey = b64(await cryptoImpl.subtle.exportKey('raw', pair.publicKey));\n return tx.publicKey;\n };\n const derive = async (tx, publicKey) => {\n const raw = unb64(publicKey, 100);\n if (raw.length !== 65 || raw[0] !== 4) throw new Error(fixedError);\n const remoteKey = await cryptoImpl.subtle.importKey('raw', raw, { name: 'ECDH', namedCurve: 'P-256' }, false, []);\n const key = await cryptoImpl.subtle.deriveKey({ name: 'ECDH', public: remoteKey }, tx.keyPair.privateKey, { name: 'AES-GCM', length: 256 }, false, ['encrypt', 'decrypt']);\n if (current(tx)) tx.sharedKey = key;\n };\n const encrypt = async (tx, op) => {\n if (!tx.sharedKey || !tx.config) throw new Error(fixedError);\n const iv = cryptoImpl.getRandomValues(new Uint8Array(12));\n const bytes = new TextEncoder().encode(JSON.stringify(tx.config));\n const cipher = await cryptoImpl.subtle.encrypt({ name: 'AES-GCM', iv, additionalData: aad(tx, tabId, tx.peerTab, op) }, tx.sharedKey, bytes);\n return { op, iv: b64(iv), cipher: b64(cipher) };\n };\n const decrypt = async (tx, data) => {\n if (!tx.sharedKey) throw new Error(fixedError);\n const iv = unb64(data.iv, 20);\n if (iv.length !== 12) throw new Error(fixedError);\n const bytes = await cryptoImpl.subtle.decrypt({ name: 'AES-GCM', iv, additionalData: aad(tx, tx.peerTab, tabId, data.op) }, tx.sharedKey, unb64(data.cipher, 8200));\n const payload = JSON.parse(new TextDecoder().decode(bytes));\n const parsed = parseManualTurnConfig(payload);\n return { ...parsed, iceTransportPolicy: policy(payload.iceTransportPolicy) };\n };\n const validExpiry = tx => {\n if (tx.config?.expiresAt !== null && tx.config?.expiresAt <= Date.now()) throw new Error(reasons.expired);\n };\n const apply = async tx => {\n validExpiry(tx);\n publish({ status: 'applying', expiresAt: tx.config.expiresAt });\n return await applyConfig(tx.config);\n };\n const rejectOther = (signal, reason) => {\n try {\n const result = sendSignal(signal.sid, { op: 'reject', reason }, signal.from);\n if (result?.then) void result.catch(() => {});\n } catch { /* No secret or provider error may enter logs. */ }\n };\n\n async function process(signal) {\n if (destroyed || !signal || !ID.test(signal.sid) || signal.to !== tabId || signal.from !== peerTab || !signal.d || typeof signal.d !== 'object') return;\n const data = signal.d;\n const old = completed.get(signal.sid);\n if (old) {\n if (old.peerTab === signal.from && old.replies.has(data.op)) send({ sid: signal.sid, peerTab: old.peerTab, replies: old.replies }, old.replies.get(data.op));\n return;\n }\n let tx = active;\n if (data.op === 'key_request') {\n if (tx && tx.sid !== signal.sid) {\n // The authoritative player's local proposal wins simultaneous submissions.\n if (authority || !tx.initiatedHere) { rejectOther(signal, 'busy'); return; }\n fail(tx, 'busy');\n tx = null;\n }\n if (tx) {\n const reply = tx.replies.get('key_request');\n if (reply) send(tx, reply);\n return;\n }\n try {\n available();\n tx = make(signal.sid, false);\n tx.peerTab = signal.from;\n await keys(tx);\n if (!current(tx)) return;\n await derive(tx, data.publicKey);\n if (!current(tx)) return;\n tx.stage = authority ? 'await_proposal' : 'await_prepare';\n send(tx, { op: 'key_reply', publicKey: tx.publicKey }, 'key_request');\n } catch { if (tx) fail(tx, 'invalid', true); else rejectOther(signal, 'unavailable'); }\n return;\n }\n if (!tx || tx.sid !== signal.sid || tx.peerTab !== signal.from) return;\n try {\n switch (data.op) {\n case 'reject': fail(tx, Object.prototype.hasOwnProperty.call(reasons, data.reason) ? data.reason : 'invalid'); return;\n case 'key_reply': {\n if (!tx.initiatedHere || tx.stage !== 'await_key') return;\n await derive(tx, data.publicKey);\n if (!current(tx)) return;\n const op = authority ? 'prepare' : 'proposal';\n const encrypted = await encrypt(tx, op);\n if (!current(tx)) return;\n tx.stage = authority ? 'await_prepared' : 'await_prepare';\n publish({ status: 'sharing', shared: true });\n send(tx, encrypted, 'key_reply');\n return;\n }\n case 'proposal': {\n if (!authority) return;\n if (tx.stage !== 'await_proposal') { const reply = tx.replies.get('proposal'); if (reply) send(tx, reply); return; }\n tx.config = await decrypt(tx, data);\n if (!current(tx)) return;\n publish({ status: 'sharing', received: true, expiresAt: tx.config.expiresAt });\n const encrypted = await encrypt(tx, 'prepare');\n if (!current(tx)) return;\n tx.stage = 'await_prepared';\n send(tx, encrypted, 'proposal');\n return;\n }\n case 'prepare': {\n if (authority) return;\n if (tx.stage !== 'await_prepare') { const reply = tx.replies.get('prepare'); if (reply) send(tx, reply); return; }\n tx.config = await decrypt(tx, data);\n if (!current(tx)) return;\n publish({ received: true, expiresAt: tx.config.expiresAt });\n const applied = await apply(tx);\n if (!current(tx)) return;\n tx.stage = 'await_commit';\n send(tx, { op: 'prepared', recreate: applied?.recreate === true }, 'prepare');\n return;\n }\n case 'prepared': {\n if (!authority) return;\n if (tx.stage !== 'await_prepared') { const reply = tx.replies.get('prepared'); if (reply) send(tx, reply); return; }\n await apply(tx);\n if (!current(tx)) return;\n tx.recreatePeer = data.recreate === true;\n tx.stage = 'await_committed';\n send(tx, { op: 'commit' }, 'prepared');\n return;\n }\n case 'commit': {\n if (authority) return;\n if (tx.stage !== 'await_commit') { const reply = tx.replies.get('commit'); if (reply) send(tx, reply); return; }\n validExpiry(tx);\n tx.stage = 'await_done';\n send(tx, { op: 'committed' }, 'commit');\n return;\n }\n case 'committed': {\n if (!authority || tx.stage !== 'await_committed') return;\n validExpiry(tx);\n tx.stage = 'committing';\n await commitConfig({ iceTransportPolicy: tx.config.iceTransportPolicy, recreatePeer: tx.recreatePeer === true });\n if (!current(tx)) return;\n send(tx, { op: 'done' }, 'committed');\n finish(tx);\n return;\n }\n case 'done': if (!authority && tx.stage === 'await_done') finish(tx); return;\n default: return;\n }\n } catch (cause) { fail(tx, cause?.message === reasons.expired ? 'expired' : 'invalid', true); }\n }\n\n return {\n configure(input, { ttlSeconds, iceTransportPolicy = 'all' } = {}) {\n if (destroyed) return Promise.reject(new Error(reasons.unavailable));\n if (active) return Promise.reject(new Error(reasons.busy));\n let config;\n try { available(); config = { ...parseManualTurnConfig(input, { ttlSeconds }), iceTransportPolicy: policy(iceTransportPolicy) }; }\n catch (cause) { publish({ status: 'failed', error: cause.message }); return Promise.reject(cause); }\n const tx = make(nextId(), true, config);\n const promise = new Promise((resolve, reject) => { tx.resolve = resolve; tx.reject = reject; });\n void (async () => {\n try {\n const bound = peerTab || await ensurePeer?.();\n if (!current(tx)) return;\n if (!ID.test(bound)) throw new Error(reasons.unavailable);\n if (peerTab && peerTab !== bound) throw new Error(reasons.unavailable);\n peerTab = bound;\n tx.peerTab = bound;\n const publicKey = await keys(tx);\n if (!current(tx)) return;\n tx.stage = 'await_key';\n publish({ status: 'sharing' });\n send(tx, { op: 'key_request', publicKey });\n } catch { fail(tx, 'unavailable', true); }\n })();\n return promise;\n },\n bindPeer(value) {\n if (destroyed || !value || !ID.test(value)) return;\n if (peerTab && peerTab !== value) {\n if (active) fail(active, 'unavailable');\n completed.clear();\n }\n peerTab = value;\n if (active && !active.peerTab) active.peerTab = value;\n },\n handleSignal(signal) {\n queue = queue.then(() => process(signal)).catch(() => {});\n return queue;\n },\n failTransfer(sid) { if (active?.sid === sid) fail(active, 'timeout', true); },\n getState() { return { ...state }; },\n destroy() {\n if (destroyed) return;\n destroyed = true;\n if (active) { const tx = active; clear(tx); tx.reject?.(new Error(reasons.unavailable)); }\n completed.clear(); peerTab = null;\n state = { status: 'idle', shared: false, received: false, expiresAt: null, error: null };\n },\n };\n}\n","// One WebRTC link between two chat users, signaled through the chat itself.\n//\n// Signaling: LIRA_WEBRTC_V1: frames (protocol.js) sent as ordinary CHAT_MESSAGE\n// text in the users' private room. The relay echoes frames to every tab of both\n// users, may duplicate them after a reconnect and gives no delivery guarantee, so:\n// - frames carry tab ids (from/to): own echoes and other tabs are ignored;\n// - every frame except hello/ack is ACKed and retransmitted until ACKed;\n// - duplicates are dropped by message id; ICE that arrives before its\n// description waits in a queue; stale sessions/generations are ignored.\n// Session: caller sends hello (repeated until answered); the first tab of the\n// peer that answers ready is bound, gets the offer and the others a bye.\n// Simultaneous calls resolve by tab id (the lower one keeps calling).\n//\n// Data: two negotiated DataChannels (no ondatachannel race):\n// move id 0, unordered, maxRetransmits 0 — latest position wins;\n// events id 1, ordered and reliable — pings, hits, game events.\n// Recovery: ICE 'failed' (or 'disconnected' for 3 s) triggers an ICE restart by\n// the caller; no traffic for HEARTBEAT_TIMEOUT_MS ends the session and the caller\n// starts a new one (autoReconnect, with backoff).\n\nimport { createManualTurnSharing } from './manualTurnSharing.js';\n\nimport { encodeSignal, decodeSignal, isWebrtcMessage, newSignalId } from './protocol.js';\n\nexport const DEFAULT_ICE_SERVERS = [{ urls: ['stun:stun.l.google.com:19302', 'stun:stun.cloudflare.com:3478'] }];\n\nconst RETRY_MS = 1200;\nconst MAX_TRIES = 6;\nconst HELLO_EVERY_MS = 2000;\nconst HELLO_GIVE_UP_MS = 30000;\nconst ICE_BATCH_MS = 80;\nconst DISCONNECTED_GRACE_MS = 3000;\nconst CONNECT_TIMEOUT_MS = 20000;\nconst PING_EVERY_MS = 1000;\nconst HEARTBEAT_TIMEOUT_MS = 10000;\nconst MAX_RESTARTS = 2;\nconst MAX_RECONNECTS = 5;\nconst MAX_BUFFERED = 16 * 1024;\nconst MAX_SEEN = 500;\n\nconst emptyMoveStats = () => ({ sent: 0, dropped: 0, received: 0, firstSeq: null, maxSeq: 0, outOfOrder: 0, lossPct: 0, hzIn: 0, hzOut: 0, windowIn: 0, windowOut: 0 });\n\nconst ROUTE_LABELS = { host: 'directa (host)', srflx: 'directa (NAT vía STUN)', prflx: 'directa (NAT)', relay: 'TURN (relay)' };\n\nexport function createPeerLink({\n signaling,\n selfId,\n peerId,\n roomId = null,\n tabId = newSignalId(),\n iceServers = DEFAULT_ICE_SERVERS,\n iceTransportPolicy = 'all',\n autoReconnect = true,\n configurationAuthority,\n listen = true,\n RTCPeerConnectionImpl = globalThis.RTCPeerConnection,\n onChange = () => {},\n onMove = () => {},\n onEvent = () => {},\n log = () => {},\n} = {}) {\n if (!signaling?.send || !signaling?.subscribe) throw new Error('createPeerLink: signaling { send, subscribe } requerido');\n selfId = String(selfId);\n peerId = String(peerId);\n\n let activeIceServers = iceServers;\n let activeIcePolicy = iceTransportPolicy;\n let credentialExpiresAt = null;\n let boundPeerTab = null;\n let boundSid = null;\n let manual;\n const controlOutbox = new Map();\n const peerWaiters = new Set();\n const authority = configurationAuthority ?? (selfId < peerId);\n const hasTurn = servers => (servers || []).some(server => [server.urls].flat().some(url => /^turns?:/i.test(String(url))));\n let listening = listen;\n let destroyed = false;\n let session = null;\n let reconnects = 0;\n let reconnectTimer = null;\n let endedSid = null; // last session that ended without the peer's bye\n const seen = new Set();\n const state = {\n phase: 'idle', role: null, sid: null, gen: 0, tabId, peerTab: null,\n ice: 'new', connection: 'new', signalingState: 'stable', gathering: 'new',\n route: null, rtt: null, statsRtt: null, reconnects: 0, restarts: 0, error: null,\n move: emptyMoveStats(),\n signals: { sent: 0, received: 0, sendFailures: 0, retransmits: 0, duplicates: 0, ignored: 0, invalid: 0, tooLarge: 0, maxLength: 0 },\n events: { sent: 0, received: 0 },\n turnConfigured: hasTurn(activeIceServers),\n manualTurn: { status: 'idle', shared: false, received: false, expiresAt: null, error: null },\n candidates: { local: 0, remote: 0, accepted: 0, rejected: 0, localRelay: 0, remoteRelay: 0 },\n iceErrors: [], channels: { move: 'closed', events: 'closed' },\n startedAt: null, connectedAt: null,\n };\n\n const emit = () => { if (!destroyed) onChange(snapshot()); };\n const snapshot = () => ({ ...state, route: state.route && { ...state.route }, move: { ...state.move }, signals: { ...state.signals }, events: { ...state.events }, manualTurn: { ...state.manualTurn }, candidates: { ...state.candidates }, iceErrors: state.iceErrors.map(error => ({ ...error })), channels: { move: session?.move?.readyState ?? 'closed', events: session?.events?.readyState ?? 'closed' }, elapsedMs: state.startedAt == null ? 0 : Math.max(0, (state.connectedAt ?? Date.now()) - state.startedAt) });\n const setPhase = (phase, error = null) => {\n state.phase = phase;\n state.error = error;\n log(`fase: ${phase}${error ? ` (${error})` : ''}`);\n emit();\n };\n\n // ---- signaling --------------------------------------------------------\n\n const rawSend = (text) => {\n const failed = () => {\n if (!destroyed) { state.signals.sendFailures += 1; emit(); }\n return false;\n };\n try {\n return Promise.resolve(signaling.send(text)).then((result) => result === false ? failed() : true, failed);\n } catch {\n return Promise.resolve(failed());\n }\n };\n\n const sendSignal = (s, t, d, { to = s?.peerTab ?? null, reliable = true, gen = s?.gen ?? 0, sid = s?.sid } = {}) => {\n const mid = newSignalId();\n const text = encodeSignal({ t, sid, gen, mid, at: Date.now(), from: tabId, to, d: d ?? undefined });\n if (!text) {\n state.signals.tooLarge += 1;\n log(`señal ${t} supera el límite y no se envía`);\n if (s) fail(s, 'signal_too_large');\n return null;\n }\n state.signals.sent += 1;\n state.signals.maxLength = Math.max(state.signals.maxLength, text.length);\n void rawSend(text);\n if (reliable && s) {\n const entry = { text, tries: 1, timer: null, gen, peerTab: to, sid };\n const retry = () => {\n if (s.closed || !s.outbox.has(mid)) return;\n if (entry.tries >= MAX_TRIES) {\n s.outbox.delete(mid);\n log(`señal ${t} sin ACK tras ${MAX_TRIES} intentos`);\n if (t !== 'bye') fail(s, 'signal_timeout');\n return;\n }\n entry.tries += 1;\n state.signals.retransmits += 1;\n void rawSend(text);\n entry.timer = setTimeout(retry, RETRY_MS);\n };\n entry.timer = setTimeout(retry, RETRY_MS);\n s.outbox.set(mid, entry);\n }\n return mid;\n };\n\n const remember = (key) => {\n if (seen.has(key)) return false;\n seen.add(key);\n if (seen.size > MAX_SEEN) seen.delete(seen.values().next().value);\n return true;\n };\n\n const handleFrame = (frame) => {\n if (destroyed || !frame || !isWebrtcMessage(frame.text)) return;\n if (roomId != null && frame.roomId && String(frame.roomId) !== String(roomId)) return;\n const signal = decodeSignal(frame.text);\n if (!signal) { state.signals.invalid += 1; return; }\n // Own echoes, own other tabs and third parties never drive this link.\n if (String(frame.userId) !== peerId || signal.from === tabId || (signal.to && signal.to !== tabId)) {\n state.signals.ignored += 1;\n return;\n }\n if (signal.t === 'turn' && (signal.to !== tabId || signal.from !== boundPeerTab)) { state.signals.ignored += 1; return; }\n state.signals.received += 1;\n if (signal.t !== 'hello' && signal.t !== 'ack') {\n // ACK even duplicates: the first ACK may be the one that got lost.\n sendSignal(null, 'ack', { of: signal.mid }, { to: signal.from, reliable: false, sid: signal.sid, gen: signal.gen });\n }\n if (!remember(`${signal.from}:${signal.mid}`)) { state.signals.duplicates += 1; emit(); return; }\n switch (signal.t) {\n case 'ack': onAck(signal); break;\n case 'hello': onHello(signal); break;\n case 'ready': onReady(signal); break;\n case 'offer': void onOffer(signal); break;\n case 'answer': void onAnswer(signal); break;\n case 'ice': onIce(signal); break;\n case 'bye': onBye(signal); break;\n case 'turn':\n if (signal.d.op === 'reconnect') {\n if (authority && signal.sid === boundSid && state.phase !== 'connected' && !manualBusy()) call();\n } else void manual.handleSignal(signal);\n break;\n default: break;\n }\n // After dispatch, so the frame that binds the peer tab (hello/ready) counts too.\n if (session && signal.sid === session.sid && signal.from === session.peerTab && signal.at) {\n session.peerAt = Math.max(session.peerAt, signal.at);\n }\n };\n\n // Manual TURN control survives a failed PC. Only encrypted, tab-targeted frames\n // enter this reliable outbox; it never retains plaintext ICE credentials.\n const sendControl = (sid, data, to) => {\n if (destroyed || !to || to !== boundPeerTab) return null;\n const mid = newSignalId();\n const text = encodeSignal({ t: 'turn', sid, gen: 0, mid, at: Date.now(), from: tabId, to, d: data });\n if (!text) throw new Error('La configuración es demasiado grande para compartir.');\n const entry = { sid, peerTab: to, text, tries: 1, timer: null };\n const retry = () => {\n if (destroyed || !controlOutbox.has(mid)) return;\n if (entry.tries >= MAX_TRIES) {\n clearControls(sid); manual.failTransfer(sid); return;\n }\n entry.tries++; state.signals.retransmits++; void rawSend(text);\n entry.timer = setTimeout(retry, RETRY_MS);\n };\n controlOutbox.set(mid, entry);\n state.signals.sent++; state.signals.maxLength = Math.max(state.signals.maxLength, text.length);\n void rawSend(text); entry.timer = setTimeout(retry, RETRY_MS); emit();\n return mid;\n };\n const clearControls = sid => {\n for (const [mid, entry] of controlOutbox) if (!sid || entry.sid === sid) { clearTimeout(entry.timer); controlOutbox.delete(mid); }\n };\n const bindPeer = (peerTab, sid) => {\n if (boundPeerTab && boundPeerTab !== peerTab) clearControls();\n boundPeerTab = peerTab; boundSid = sid; manual.bindPeer(peerTab);\n for (const waiter of peerWaiters) { clearTimeout(waiter.timer); waiter.resolve(peerTab); }\n peerWaiters.clear();\n };\n const ensurePeer = () => {\n if (boundPeerTab) return Promise.resolve(boundPeerTab);\n return new Promise((resolve, reject) => {\n const waiter = { resolve, reject, timer: null };\n waiter.timer = setTimeout(() => { peerWaiters.delete(waiter); reject(new Error('El otro jugador no está disponible. Abre la partida en ambos dispositivos.')); }, HELLO_GIVE_UP_MS);\n peerWaiters.add(waiter);\n if (authority && !session) call();\n });\n };\n const applyIceConfig = ({ iceServers: servers, iceTransportPolicy: policy, expiresAt }) => {\n if (destroyed || (expiresAt != null && expiresAt <= Date.now())) throw new Error('Las credenciales TURN han expirado.');\n activeIceServers = servers; activeIcePolicy = policy; credentialExpiresAt = expiresAt;\n state.turnConfigured = hasTurn(servers);\n const s = session;\n if (s?.pc && !s.closed) {\n try {\n if (typeof s.pc.setConfiguration !== 'function') throw new Error('unsupported');\n s.pc.setConfiguration({ iceServers: servers, iceTransportPolicy: policy });\n s.recreateForConfig = false;\n } catch { s.recreateForConfig = true; }\n }\n emit();\n return { recreate: Boolean(s?.recreateForConfig) };\n };\n const commitIceConfig = ({ recreatePeer = false } = {}) => {\n if (destroyed || !authority) return;\n if (credentialExpiresAt != null && credentialExpiresAt <= Date.now()) throw new Error('Las credenciales TURN han expirado.');\n const s = session;\n const healthy = state.phase === 'connected' && ['connected', 'completed'].includes(s?.pc?.iceConnectionState) && s?.move?.readyState === 'open' && s?.events?.readyState === 'open';\n if (s) s.deferredRestart = false;\n if (healthy && activeIcePolicy === 'all' && !s.recreateForConfig && !recreatePeer) return;\n clearTimeout(reconnectTimer); reconnectTimer = null;\n if (s && !s.closed && !s.recreateForConfig && !recreatePeer && s.role === 'caller' && s.pc?.signalingState === 'stable') { s.restarts = 0; restartIce(s, { manualCommit: true }); }\n else call();\n };\n manual = createManualTurnSharing({ authority, selfId, peerId, roomId, tabId,\n sendSignal: sendControl, applyConfig: applyIceConfig, commitConfig: commitIceConfig, ensurePeer,\n onChange(value) {\n state.manualTurn = value;\n if (['waiting_peer', 'sharing', 'applying'].includes(value.status)) {\n clearTimeout(reconnectTimer); reconnectTimer = null;\n if (session) { clearTimeout(session.connectTimer); clearTimeout(session.disconnectTimer); }\n } else if (['failed', 'synchronized'].includes(value.status) && !destroyed) {\n if (session?.deferredRestart) { session.deferredRestart = false; restartIce(session); }\n if (state.phase !== 'connected') {\n if (session) armConnectTimeout(session);\n else if (authority) scheduleReconnect(state.error ?? 'connection_recovery');\n }\n }\n emit();\n },\n });\n const unsubscribe = signaling.subscribe(handleFrame);\n\n // ---- session lifecycle ------------------------------------------------\n\n const newSession = (role, sid = newSignalId(), peerTab = null) => ({\n role, sid, peerTab, gen: 0, localGen: 0, remoteGen: -1, makingOffer: false, pc: null, move: null, events: null, closed: false,\n outbox: new Map(), pendingIce: [], localIce: [], iceTimer: null, helloTimer: null, helloStarted: Date.now(),\n disconnectTimer: null, connectTimer: null, pingTimer: null, statsTimer: null, tickTimer: null,\n lastSeen: Date.now(), pingSeq: 0, moveSeq: 0, restarts: 0, open: 0, peerAt: 0,\n });\n\n const teardown = (s, { bye = false, recover = false } = {}) => {\n if (!s || s.closed) return;\n if (bye && s.peerTab) sendSignal(s, 'bye', recover ? { recover: true } : null, { reliable: false });\n s.closed = true;\n [s.iceTimer, s.disconnectTimer, s.connectTimer].forEach((timer) => clearTimeout(timer));\n [s.helloTimer, s.pingTimer, s.statsTimer, s.tickTimer].forEach((timer) => clearInterval(timer));\n s.outbox.forEach((entry) => clearTimeout(entry.timer));\n s.outbox.clear();\n [s.move, s.events].forEach((channel) => {\n if (!channel) return;\n channel.onopen = channel.onclose = channel.onmessage = channel.onerror = null;\n try { channel.close(); } catch { /* already closed */ }\n });\n if (s.pc) {\n s.pc.onicecandidate = s.pc.oniceconnectionstatechange = s.pc.onconnectionstatechange = null;\n s.pc.onsignalingstatechange = s.pc.onicegatheringstatechange = s.pc.onicecandidateerror = null;\n try { s.pc.close(); } catch { /* already closed */ }\n }\n if (session === s) session = null;\n };\n\n const manualBusy = () => ['waiting_peer', 'sharing', 'applying'].includes(state.manualTurn.status);\n const scheduleReconnect = (reason) => {\n if (manualBusy()) { setPhase('reconnecting', reason); return; }\n if (destroyed || !autoReconnect || reconnectTimer) return;\n if (reconnects >= MAX_RECONNECTS) { setPhase('failed', `${reason}; sin más reintentos`); return; }\n const delay = Math.min(8000, 1000 * 2 ** reconnects);\n reconnects += 1;\n state.reconnects = reconnects;\n setPhase('reconnecting', reason);\n reconnectTimer = setTimeout(() => { reconnectTimer = null; if (!destroyed && !session) call(); }, delay);\n };\n\n const fail = (s, reason) => {\n if (s.closed) return;\n const wasCaller = s.role === 'caller';\n endedSid = s.sid;\n teardown(s, { bye: true, recover: true });\n if (wasCaller) scheduleReconnect(reason);\n else setPhase(listening ? 'listening' : 'idle', reason);\n };\n\n const bindState = (s) => {\n state.role = s.role;\n state.sid = s.sid;\n state.gen = s.gen;\n state.peerTab = s.peerTab;\n state.ice = 'new';\n state.connection = 'new';\n state.signalingState = 'stable';\n state.gathering = 'new';\n state.route = null;\n state.rtt = null;\n state.statsRtt = null;\n state.restarts = 0;\n state.move = emptyMoveStats();\n state.connectedAt = null;\n state.startedAt ??= Date.now();\n };\n\n // ---- peer connection --------------------------------------------------\n\n const armConnectTimeout = s => {\n clearTimeout(s.connectTimer);\n s.connectTimer = setTimeout(() => { if (!s.closed && (s.move?.readyState !== 'open' || s.events?.readyState !== 'open' || !['connected', 'completed'].includes(s.pc?.iceConnectionState))) fail(s, 'connect_timeout'); }, CONNECT_TIMEOUT_MS);\n };\n const createPc = (s) => {\n if (!RTCPeerConnectionImpl) { fail(s, 'webrtc_unavailable'); return null; }\n let pc;\n try { pc = new RTCPeerConnectionImpl({ iceServers: activeIceServers, iceTransportPolicy: activeIcePolicy }); }\n catch { fail(s, 'peer_creation_failed'); return null; }\n s.pc = pc;\n pc.onicecandidate = ({ candidate }) => {\n if (s.closed) return;\n const ufrag = candidate?.usernameFragment;\n const currentUfrag = /^a=ice-ufrag:(.+)$/m.exec(pc.localDescription?.sdp ?? '')?.[1]?.trim();\n if (ufrag && currentUfrag && ufrag !== currentUfrag) return;\n if (candidate) { state.candidates.local++; if (/ typ relay(?: |$)/.test(candidate.candidate ?? '')) state.candidates.localRelay++; }\n if (s.localIce.length >= 128) flushLocalIce(s);\n s.localIce.push({ gen: s.localGen, candidate: candidate ? candidate.toJSON?.() ?? candidate : null });\n if (!s.iceTimer) s.iceTimer = setTimeout(() => flushLocalIce(s), ICE_BATCH_MS);\n };\n pc.onicecandidateerror = event => {\n if (s.closed) return;\n state.iceErrors = [...state.iceErrors.slice(-9), { code: Number(event.errorCode) || 0, stage: 'gathering' }]; emit();\n };\n pc.onicegatheringstatechange = () => { state.gathering = pc.iceGatheringState; emit(); };\n pc.onsignalingstatechange = () => { state.signalingState = pc.signalingState; emit(); };\n pc.onconnectionstatechange = () => { state.connection = pc.connectionState; emit(); };\n pc.oniceconnectionstatechange = () => onIceState(s);\n s.move = pc.createDataChannel('move', { negotiated: true, id: 0, ordered: false, maxRetransmits: 0 });\n s.events = pc.createDataChannel('events', { negotiated: true, id: 1, ordered: true });\n [s.move, s.events].forEach((channel) => {\n channel.onopen = () => onChannelOpen(s);\n channel.onclose = () => { if (!s.closed && state.phase === 'connected') lose(s, 'canal cerrado'); };\n });\n s.move.onmessage = (event) => onMoveMessage(s, event.data);\n s.events.onmessage = (event) => onEventMessage(s, event.data);\n armConnectTimeout(s);\n return pc;\n };\n\n const flushLocalIce = (s) => {\n clearTimeout(s.iceTimer); s.iceTimer = null;\n if (s.closed || !s.localIce.length) return;\n const generations = new Map();\n for (const item of s.localIce.splice(0)) {\n if (!generations.has(item.gen)) generations.set(item.gen, []);\n generations.get(item.gen).push(item.candidate);\n }\n for (const [gen, batch] of generations) for (let i = 0; i < batch.length; i += 16) sendSignal(s, 'ice', { c: batch.slice(i, i + 16) }, { gen });\n };\n\n const addRemoteIce = async (s, candidates) => {\n for (const candidate of candidates) {\n try {\n if (s.closed) return;\n await s.pc.addIceCandidate(candidate);\n if (candidate) state.candidates.accepted++;\n emit();\n } catch (error) {\n state.candidates.rejected++;\n state.iceErrors = [...state.iceErrors.slice(-9), { code: 0, stage: 'remote_candidate' }]; emit();\n }\n }\n };\n\n const flushPendingIce = (s) => {\n const ready = s.pendingIce.filter((item) => item.gen === s.gen);\n s.pendingIce = s.pendingIce.filter((item) => item.gen > s.gen);\n ready.forEach((item) => void addRemoteIce(s, item.c));\n };\n\n const makeOffer = async (s, iceRestart = false) => {\n if (s.closed || s.makingOffer) return;\n s.makingOffer = true;\n try {\n const offer = await s.pc.createOffer(iceRestart ? { iceRestart: true } : undefined);\n if (s.closed) return;\n await s.pc.setLocalDescription(offer);\n if (s.closed) return;\n s.localGen = s.gen;\n sendSignal(s, 'offer', { sdp: s.pc.localDescription.sdp });\n } catch (error) {\n fail(s, 'offer_failed');\n } finally { s.makingOffer = false; }\n };\n\n const restartIce = (s, { manualCommit = false } = {}) => {\n if (manualBusy() && !manualCommit) { s.deferredRestart = true; return; }\n if (s.closed || s.role !== 'caller' || s.makingOffer || s.pc?.signalingState !== 'stable') return;\n if (credentialExpiresAt != null && credentialExpiresAt <= Date.now()) { fail(s, 'turn_credentials_expired'); return; }\n if (s.restarts >= MAX_RESTARTS) { lose(s, 'ICE no se recupera'); return; }\n flushLocalIce(s);\n s.restarts += 1;\n state.restarts = s.restarts;\n s.gen += 1;\n state.gen = s.gen;\n state.connectedAt = null; state.route = null;\n armConnectTimeout(s);\n setPhase('restarting');\n void makeOffer(s, true);\n };\n\n const maybeConnected = s => {\n if (s.closed || session !== s || !['connected', 'completed'].includes(s.pc?.iceConnectionState)\n || s.move?.readyState !== 'open' || s.events?.readyState !== 'open') return;\n clearTimeout(s.connectTimer);\n if (state.phase !== 'connected') { state.connectedAt = Date.now(); setPhase('connected'); }\n };\n const onIceState = (s) => {\n if (s.closed) return;\n const ice = s.pc.iceConnectionState;\n state.ice = ice;\n clearTimeout(s.disconnectTimer);\n if (ice === 'connected' || ice === 'completed') {\n maybeConnected(s);\n void refreshStats(s);\n } else if (ice === 'disconnected') {\n if (state.phase === 'connected') setPhase('reconnecting');\n if (!manualBusy()) armConnectTimeout(s);\n s.disconnectTimer = setTimeout(() => restartIce(s), DISCONNECTED_GRACE_MS);\n } else if (ice === 'failed') {\n if (state.phase === 'connected') setPhase('reconnecting', 'ice_failed');\n if (!manualBusy()) armConnectTimeout(s);\n restartIce(s);\n }\n emit();\n };\n\n const onChannelOpen = (s) => {\n if (s.closed || s.move?.readyState !== 'open' || s.events?.readyState !== 'open') return;\n if (s.open === 2) return;\n s.open = 2;\n state.connectedAt = Date.now();\n clearTimeout(s.connectTimer);\n reconnects = 0;\n s.lastSeen = Date.now();\n s.pingTimer = setInterval(() => ping(s), PING_EVERY_MS);\n s.statsTimer = setInterval(() => void refreshStats(s), 2000);\n s.tickTimer = setInterval(() => tick(s), 1000);\n setPhase('connected');\n void refreshStats(s);\n };\n\n // A session that stops hearing the peer is over; the caller starts a new one.\n const lose = (s, reason) => fail(s, reason);\n\n // ---- data -------------------------------------------------------------\n\n const ping = (s) => {\n if (Date.now() - s.lastSeen > HEARTBEAT_TIMEOUT_MS) { if (manualBusy()) { s.deferredRestart = true; return; } lose(s, 'heartbeat_timeout'); return; }\n sendRaw(s.events, JSON.stringify({ k: 'ping', n: ++s.pingSeq, ts: performance.now() }));\n };\n\n const sendRaw = (channel, text) => {\n if (channel?.readyState !== 'open') return false;\n try { channel.send(text); return true; } catch { return false; }\n };\n\n const onEventMessage = (s, data) => {\n s.lastSeen = Date.now();\n let message;\n try { message = JSON.parse(data); } catch { return; }\n if (message?.k === 'ping') sendRaw(s.events, JSON.stringify({ k: 'pong', ts: message.ts }));\n else if (message?.k === 'pong') { state.rtt = Math.round((performance.now() - message.ts) * 10) / 10; }\n else if (message?.k === 'app') { state.events.received += 1; onEvent(message.d); }\n };\n\n const onMoveMessage = (s, data) => {\n s.lastSeen = Date.now();\n let packet;\n try { packet = JSON.parse(data); } catch { return; }\n if (!Array.isArray(packet) || !Number.isInteger(packet[0])) return;\n const [seq, , payload] = packet;\n const m = state.move;\n m.received += 1;\n m.windowIn += 1;\n if (m.firstSeq == null) m.firstSeq = seq;\n if (seq < m.maxSeq) { m.outOfOrder += 1; return; } // stale position: counted, not applied\n m.maxSeq = seq;\n onMove(payload, { seq });\n };\n\n const tick = (s) => {\n const m = state.move;\n m.hzIn = m.windowIn;\n m.hzOut = m.windowOut;\n m.windowIn = 0;\n m.windowOut = 0;\n const expected = m.firstSeq == null ? 0 : m.maxSeq - m.firstSeq + 1;\n m.lossPct = expected > 0 ? Math.max(0, Math.round((1 - m.received / expected) * 1000) / 10) : 0;\n if (!s.closed) emit();\n };\n\n const refreshStats = async (s) => {\n if (s.closed || !s.pc?.getStats) return;\n try {\n const report = await s.pc.getStats();\n const byId = new Map();\n report.forEach((entry) => byId.set(entry.id, entry));\n let pair = null;\n report.forEach((entry) => {\n if (entry.type === 'transport' && entry.selectedCandidatePairId) pair = byId.get(entry.selectedCandidatePairId);\n });\n if (!pair) report.forEach((entry) => { if (entry.type === 'candidate-pair' && (entry.selected || entry.nominated) && entry.state === 'succeeded') pair = entry; });\n if (!pair) return;\n const local = byId.get(pair.localCandidateId);\n const remote = byId.get(pair.remoteCandidateId);\n const relay = local?.candidateType === 'relay' || remote?.candidateType === 'relay';\n const type = relay ? 'relay' : (local?.candidateType ?? 'host');\n state.route = {\n local: local?.candidateType ?? null,\n remote: remote?.candidateType ?? null,\n protocol: local?.protocol ?? null,\n relayProtocol: local?.relayProtocol ?? null,\n relay,\n label: ROUTE_LABELS[type] ?? type,\n };\n if (typeof pair.currentRoundTripTime === 'number') state.statsRtt = Math.round(pair.currentRoundTripTime * 10000) / 10;\n emit();\n } catch { /* stats are optional */ }\n };\n\n // ---- signal handlers ----------------------------------------------------\n\n const onAck = (signal) => {\n const control = controlOutbox.get(signal.d.of);\n if (control && control.sid === signal.sid && control.peerTab === signal.from && signal.to === tabId) { clearTimeout(control.timer); controlOutbox.delete(signal.d.of); return; }\n if (session?.sid !== signal.sid || session?.peerTab !== signal.from) return;\n const entry = session?.outbox.get(signal.d.of);\n if (entry && entry.gen !== signal.gen) return;\n if (!entry) return;\n clearTimeout(entry.timer);\n session.outbox.delete(signal.d.of);\n };\n\n const onHello = (signal) => {\n if (session && session.sid === signal.sid) return;\n // A second tab must not steal an already bound match. A real reload first\n // releases the old session through bye/heartbeat or its bounded timeout.\n if (session?.peerTab && session.peerTab !== signal.from) { state.signals.ignored++; return; }\n // A late hello from a call the bound tab already dropped (glare, reorder).\n if (session && session.peerTab === signal.from && (signal.at ?? 0) <= session.peerAt) return;\n const glare = session?.role === 'caller' && !session.peerTab;\n // Both called at once: the lower tab id keeps calling, the other answers.\n if (glare && tabId < signal.from) return;\n if (!listening && !glare) { state.signals.ignored += 1; return; }\n // Otherwise the peer started over (reload, lost session): the new call replaces ours.\n if (session) teardown(session, { bye: !glare, recover: true });\n const s = newSession('answerer', signal.sid, signal.from);\n session = s;\n bindState(s);\n bindPeer(signal.from, s.sid);\n if (!createPc(s)) return;\n sendSignal(s, 'ready', null);\n setPhase('negotiating');\n };\n\n const onReady = (signal) => {\n const s = session;\n if (!s || s.role !== 'caller' || s.sid !== signal.sid) return;\n if (s.peerTab && s.peerTab !== signal.from) {\n // Another tab of the peer answered later: release it.\n sendSignal(s, 'bye', null, { to: signal.from, reliable: false });\n return;\n }\n if (s.peerTab) return;\n s.peerTab = signal.from;\n state.peerTab = signal.from;\n bindPeer(signal.from, s.sid);\n clearInterval(s.helloTimer);\n if (!createPc(s)) return;\n setPhase('negotiating');\n void makeOffer(s);\n };\n\n const onOffer = async (signal) => {\n const s = session;\n if (!s || s.role !== 'answerer' || s.sid !== signal.sid || s.peerTab !== signal.from || signal.gen < s.gen) return;\n if (signal.gen > s.gen) { state.route = null; state.connectedAt = null; armConnectTimeout(s); setPhase('restarting'); }\n s.gen = signal.gen;\n state.gen = s.gen;\n try {\n await s.pc.setRemoteDescription({ type: 'offer', sdp: signal.d.sdp });\n if (s.closed) return;\n s.remoteGen = signal.gen;\n flushPendingIce(s);\n const answer = await s.pc.createAnswer();\n if (s.closed) return;\n await s.pc.setLocalDescription(answer);\n if (s.closed) return;\n s.localGen = s.gen;\n sendSignal(s, 'answer', { sdp: s.pc.localDescription.sdp });\n maybeConnected(s);\n } catch (error) {\n fail(s, 'answer_failed');\n }\n };\n\n const onAnswer = async (signal) => {\n const s = session;\n if (!s || s.role !== 'caller' || s.sid !== signal.sid || s.peerTab !== signal.from || signal.gen !== s.gen) return;\n if (s.pc.signalingState !== 'have-local-offer') return;\n try {\n await s.pc.setRemoteDescription({ type: 'answer', sdp: signal.d.sdp });\n if (s.closed) return;\n s.remoteGen = signal.gen;\n flushPendingIce(s);\n // An ICE restart over a working path may never leave 'connected'.\n maybeConnected(s);\n } catch (error) {\n fail(s, 'remote_answer_failed');\n }\n };\n\n const onIce = (signal) => {\n const s = session;\n if (!s || s.sid !== signal.sid || s.peerTab !== signal.from || signal.gen < s.gen) return;\n state.candidates.remote += signal.d.c.filter(Boolean).length;\n state.candidates.remoteRelay += signal.d.c.filter(candidate => / typ relay(?: |$)/.test(candidate?.candidate ?? '')).length;\n if (signal.gen > s.gen || s.remoteGen !== signal.gen || !s.pc?.remoteDescription) {\n if (s.pendingIce.length >= 64) { fail(s, 'candidate_queue_full'); return; }\n s.pendingIce.push({ gen: signal.gen, c: signal.d.c }); // arrived before its offer/answer\n emit(); return;\n }\n void addRemoteIce(s, signal.d.c);\n };\n\n const onBye = (signal) => {\n if (signal.d?.recover === true) {\n const s = session;\n if (!s || s.sid !== signal.sid || s.peerTab !== signal.from) return;\n const shouldCall = configurationAuthority === undefined ? s.role === 'caller' : authority;\n endedSid = s.sid; teardown(s);\n if (shouldCall) scheduleReconnect('peer_restarting'); else setPhase(listening ? 'listening' : 'idle');\n return;\n }\n // The channel may close before the bye arrives through the chat: the peer left\n // on purpose, so the reconnection that started meanwhile is cancelled.\n if (signal.sid === endedSid && (reconnectTimer || (session?.role === 'caller' && !session.peerTab))) {\n clearTimeout(reconnectTimer);\n reconnectTimer = null;\n reconnects = 0;\n if (session) teardown(session);\n setPhase(listening ? 'listening' : 'idle', 'el rival cerró la conexión');\n return;\n }\n const s = session;\n if (!s || s.sid !== signal.sid) return;\n if (s.peerTab && s.peerTab !== signal.from) return;\n teardown(s);\n setPhase(listening ? 'listening' : 'idle', 'el rival cerró la conexión');\n };\n\n // ---- public API -------------------------------------------------------\n\n function call() {\n if (destroyed) return;\n clearTimeout(reconnectTimer);\n reconnectTimer = null;\n if (session) teardown(session, { bye: true, recover: true });\n if (credentialExpiresAt != null && credentialExpiresAt <= Date.now()) { setPhase('failed', 'turn_credentials_expired'); return; }\n const s = newSession('caller');\n session = s;\n bindState(s);\n setPhase('calling');\n const hello = () => {\n if (s.closed || s.peerTab) return;\n if (Date.now() - s.helloStarted > HELLO_GIVE_UP_MS) {\n teardown(s);\n setPhase('failed', 'el rival no respondió');\n return;\n }\n sendSignal(s, 'hello', null, { to: null, reliable: false });\n };\n hello();\n s.helloTimer = setInterval(hello, HELLO_EVERY_MS);\n }\n\n if (listening) setPhase('listening');\n\n return {\n tabId,\n configureTurn(input, options) { return manual.configure(input, options); },\n clearManualTurn() {\n manual.destroy(); clearControls(); activeIceServers = iceServers; activeIcePolicy = iceTransportPolicy; credentialExpiresAt = null;\n try { session?.pc?.setConfiguration?.({ iceServers: [], iceTransportPolicy: 'all' }); } catch { /* Existing channel may finish without new allocations. */ }\n state.manualTurn = { status: 'idle', shared: false, received: false, expiresAt: null, error: null };\n state.turnConfigured = hasTurn(iceServers); emit();\n },\n requestReconnect() {\n if (destroyed || state.phase === 'connected') return;\n if (configurationAuthority === false && boundPeerTab && boundSid) sendControl(boundSid, { op: 'reconnect' }, boundPeerTab);\n else { reconnects = 0; call(); }\n },\n /** Starts a new session as caller (the peer must be listening). */\n connect() { reconnects = 0; call(); },\n /** Accept (true) or ignore (false) incoming calls. */\n setListening(value) {\n listening = Boolean(value);\n if (!session) setPhase(listening ? 'listening' : 'idle');\n },\n /** Latest-wins position update over the unreliable channel. */\n sendMove(payload) {\n const s = session;\n if (!s || s.move?.readyState !== 'open') return false;\n if (s.move.bufferedAmount > MAX_BUFFERED) { state.move.dropped += 1; return false; }\n const sent = sendRaw(s.move, JSON.stringify([++s.moveSeq, Date.now(), payload]));\n if (sent) { state.move.sent += 1; state.move.windowOut += 1; }\n return sent;\n },\n /** Reliable, ordered game event. */\n sendEvent(payload) {\n const sent = sendRaw(session?.events, JSON.stringify({ k: 'app', d: payload }));\n if (sent) state.events.sent += 1;\n return sent;\n },\n /** Forces an ICE restart (caller) — for tests. */\n restartIce() { if (session) restartIce(session); },\n getState: snapshot,\n /** Ends the session (bye to the peer) but keeps listening. */\n hangup() {\n clearTimeout(reconnectTimer);\n reconnectTimer = null;\n if (session) teardown(session, { bye: true });\n setPhase(listening ? 'listening' : 'idle');\n },\n /** Full cleanup: session, timers and the signaling subscription. */\n destroy() {\n if (destroyed) return;\n clearTimeout(reconnectTimer);\n if (session) teardown(session, { bye: true });\n destroyed = true;\n manual.destroy(); clearControls();\n activeIceServers = []; credentialExpiresAt = null;\n for (const waiter of peerWaiters) { clearTimeout(waiter.timer); waiter.reject(new Error('La partida terminó.')); } peerWaiters.clear();\n unsubscribe?.();\n },\n };\n}\n\nexport default createPeerLink;\n"],"mappings":"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"}