1+ window . CreadorCraftLanAPI = class CreadorCraftLanAPI {
2+ static peerConnection ;
3+ static dataChannel ;
4+ static ICE_SERVERS = [
5+ { urls : "stun:stun.l.google.com:19302" } ,
6+ { urls : "stun:stun1.l.google.com:19302" }
7+ ] ;
8+ #prefix = "[CreadorCraftLanAPI] " ;
9+ #eventListenerscandidatefound = [ ] ;
10+ #eventListenersconnectionstatechange = [ ] ;
11+ #eventListenersdatachannel = [ ] ;
12+ #eventListenersdatachannelopen = [ ] ;
13+ #eventListenersresponsedata = [ ] ;
14+ #eventListenersclose = [ ] ;
15+ #eventListenerserror = [ ] ;
16+ candidates = [ ] ;
17+ async static createInicializer ( ) {
18+ let instance = new window . CreadorCraftLanAPI ( true ) ;
19+ let jsonres ;
20+ try {
21+ const offer = await window . CreadorCraftLanAPI . peerConnection . createOffer ( ) ;
22+ await window . CreadorCraftLanAPI . peerConnection . setLocalDescription ( offer ) ;
23+ jsonres = offer ;
24+ } catch ( e ) {
25+ console . error ( "[CreadorCraftLanAPI] Error al crear la oferta:" , e ) ;
26+ return null ;
27+ }
28+ return {
29+ keyJson : jsonres ,
30+ instance : instance
31+ } ;
32+ }
33+ async static createResponder ( offer ) {
34+ let instance = new window . CreadorCraftLanAPI ( false ) ;
35+ let jsonres ;
36+ try {
37+ const remooffer = new RTCSessionDescription ( offer ) ;
38+ await window . CreadorCraftLanAPI . peerConnection . setRemoteDescription ( remooffer ) ;
39+ const answer = await window . CreadorCraftLanAPI . peerConnection . createAnswer ( ) ;
40+ await window . CreadorCraftLanAPI . peerConnection . setLocalDescription ( answer ) ;
41+ jsonres = answer ;
42+ } catch ( e ) {
43+ console . error ( "[CreadorCraftLanAPI] Error al crear la respuesta:" , e ) ;
44+ return null ;
45+ }
46+ return {
47+ keyJson : jsonres ,
48+ instance : instance
49+ } ;
50+ }
51+ constructor ( isInitiator = false ) {
52+ if ( window . CreadorCraftLanAPI . peerConnection ) {
53+ console . warn ( this . #prefix+ "Ya Exite una conexión establecida!, reiniciando." ) ;
54+ window . CreadorCraftLanAPI . peerConnection . close ( ) ;
55+ }
56+ console . info ( this . #prefix+ "Creando conexión..." ) ;
57+ window . CreadorCraftLanAPI . peerConnection = new RTCPeerConnection ( { iceServers : window . CreadorCraftLanAPI . ICE_SERVERS } ) ;
58+ window . CreadorCraftLanAPI . peerConnection . onicecandidate = ( event ) => {
59+ if ( event . candidate ) {
60+ console . info ( this . #prefix+ "Candidato ICE Local generado:" , event . candidate ) ;
61+ this . #processEvents( "candidatefound" , event . candidate . toJSON ( ) ) ;
62+ this . candidates . push ( event . candidate . toJSON ( ) ) ;
63+ }
64+ } ;
65+ window . CreadorCraftLanAPI . peerConnection . oniceconnectionstatechange = ( ) => {
66+ console . info ( this . #prefix+ "Estado de conexión ICE: " + window . CreadorCraftLanAPI . peerConnection . iceConnectionState ) ;
67+ this . #processEvents( "connectionstatechange" , { connectionState : window . CreadorCraftLanAPI . peerConnection . iceConnectionState } ) ;
68+ } ;
69+ window . CreadorCraftLanAPI . peerConnection . ondatachannel = ( event ) => {
70+ window . CreadorCraftLanAPI . dataChannel = event . channel ;
71+ this . #processEvents( "datachannel" , event . channel ) ;
72+ #setupDataChannelListeners( ) ;
73+ } ;
74+ if ( isInitiator ) {
75+ window . CreadorCraftLanAPI . dataChannel = window . CreadorCraftLanAPI . peerConnection . createDataChannel ( "CreadorCraftLanChannel" ) ;
76+ #setupDataChannelListeners( ) ;
77+ }
78+ }
79+ #processEvents( eventName , data ) {
80+ let event = new CustomEvent ( eventName , {
81+ detail : data
82+ } ) ;
83+ this . dispatchEvent ( event ) ;
84+ }
85+ #setupDataChannelListeners( ) {
86+ if ( ! window . CreadorCraftLanAPI . dataChannel ) {
87+ console . warn ( this . #prefix+ "No hay un canal de datos disponible para configurar los listeners." ) ;
88+ return ;
89+ }
90+ window . CreadorCraftLanAPI . dataChannel . onopen = ( ) => {
91+ this . #processEvents( "datachannelopen" , { channel : window . CreadorCraftLanAPI . dataChannel } ) ;
92+ } ;
93+ window . CreadorCraftLanAPI . dataChannel . onmessage = ( event ) => {
94+ try {
95+ this . #processEvents( "responsedata" , JSON . parse ( event . data ) ) ;
96+ } catch ( e ) {
97+ this . #processEvents( "error" , e ) ;
98+ }
99+ } ;
100+ window . CreadorCraftLanAPI . dataChannel . onclose = ( ) => {
101+ this . #processEvents( "close" , { channel : window . CreadorCraftLanAPI . dataChannel } ) ;
102+ } ;
103+ window . CreadorCraftLanAPI . dataChannel . onerror = ( error ) => {
104+ this . #processEvents( "error" , error ) ;
105+ } ;
106+ }
107+ dispatchEvent ( event ) {
108+ let eventName = event . type ;
109+ if ( this [ "#eventListeners" + eventName ] ) {
110+ for ( let listener of this [ "#eventListeners" + eventName ] ) {
111+ if ( typeof listener === "function" ) {
112+ try {
113+ listener ( event ) ;
114+ } catch ( e ) {
115+ console . error ( this . #prefix+ "Error al ejecutar el listener:" , e ) ;
116+ }
117+ } else if ( listener . handleEvent ) {
118+ try {
119+ listener . handleEvent ( event ) ;
120+ } catch ( e ) {
121+ console . error ( this . #prefix+ "Error al ejecutar el listener con handleEvent:" , e ) ;
122+ }
123+ }
124+ }
125+ }
126+ }
127+ addEventListener ( eventName , listener ) {
128+ if ( ! this [ "#eventListeners" + eventName ] ) {
129+ console . warn ( this . #prefix+ "No Existe el evento '" + eventName + "'" ) ;
130+ return ;
131+ }
132+ if ( typeof listener !== "function" && ! listener . handleEvent ) {
133+ console . warn ( this . #prefix+ "El listener debe ser una función o un objeto con el método handleEvent." ) ;
134+ return ;
135+ }
136+ this [ "#eventListeners" + eventName ] . push ( listener ) ;
137+ }
138+ async addRemoteICECandidate ( candidate ) {
139+ await window . CreadorCraftLanAPI . peerConnection . addIceCandidate ( new RTCIceCandidate ( candidate ) ) ;
140+ }
141+ async acceptResponse ( respon ) {
142+ if ( ! window . CreadorCraftLanAPI . peerConnection ) {
143+ console . error ( this . #prefix+ "No hay una conexión establecida para aceptar la respuesta." ) ;
144+ return ;
145+ }
146+ try {
147+ const answer = new RTCSessionDescription ( respon ) ;
148+ await window . CreadorCraftLanAPI . peerConnection . setRemoteDescription ( answer ) ;
149+ } catch ( error ) {
150+ console . error ( this . #prefix+ "Error al aceptar la respuesta:" , error ) ;
151+ this . #processEvents( "error" , error ) ;
152+ }
153+ }
154+ sendDataPacket ( data ) {
155+ if ( ! window . CreadorCraftLanAPI . dataChannel || window . CreadorCraftLanAPI . dataChannel . readyState !== "open" ) {
156+ console . error ( this . #prefix+ "El canal de datos no está abierto o no existe." ) ;
157+ return ;
158+ }
159+ try {
160+ window . CreadorCraftLanAPI . dataChannel . send ( JSON . stringify ( data ) ) ;
161+ } catch ( error ) {
162+ console . error ( this . #prefix+ "Error al enviar el paquete de datos:" , error ) ;
163+ this . #processEvents( "error" , error ) ;
164+ }
165+ }
166+ } ;
0 commit comments