@limrun/ui 0.3.1 → 0.3.2

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.
package/dist/index.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});require('./index.css');const b=require("react/jsx-runtime"),T=require("react");function ne(i){var u,D,s="";if(typeof i=="string"||typeof i=="number")s+=i;else if(typeof i=="object")if(Array.isArray(i)){var l=i.length;for(u=0;u<l;u++)i[u]&&(D=ne(i[u]))&&(s&&(s+=" "),s+=D)}else for(D in i)i[D]&&(s&&(s+=" "),s+=D);return s}function _e(){for(var i,u,D=0,s="",l=arguments.length;D<l;D++)(i=arguments[D])&&(u=ne(i))&&(s&&(s+=" "),s+=u);return s}const j={INJECT_KEYCODE:0,INJECT_TOUCH_EVENT:2,SET_CLIPBOARD:9},F={ACTION_DOWN:0,ACTION_UP:1,ACTION_MOVE:2,ACTION_CANCEL:3,BUTTON_PRIMARY:1},e={ACTION_DOWN:0,ACTION_UP:1,META_NONE:0,META_SHIFT_ON:1,META_ALT_ON:2,META_CTRL_ON:4096,META_META_ON:65536,KEYCODE_0:7,KEYCODE_1:8,KEYCODE_2:9,KEYCODE_3:10,KEYCODE_4:11,KEYCODE_5:12,KEYCODE_6:13,KEYCODE_7:14,KEYCODE_8:15,KEYCODE_9:16,DPAD_UP:19,DPAD_DOWN:20,DPAD_LEFT:21,DPAD_RIGHT:22,KEYCODE_A:29,KEYCODE_B:30,KEYCODE_C:31,KEYCODE_D:32,KEYCODE_E:33,KEYCODE_F:34,KEYCODE_G:35,KEYCODE_H:36,KEYCODE_I:37,KEYCODE_J:38,KEYCODE_K:39,KEYCODE_L:40,KEYCODE_M:41,KEYCODE_N:42,KEYCODE_O:43,KEYCODE_P:44,KEYCODE_Q:45,KEYCODE_R:46,KEYCODE_S:47,KEYCODE_T:48,KEYCODE_U:49,KEYCODE_V:50,KEYCODE_W:51,KEYCODE_X:52,KEYCODE_Y:53,KEYCODE_Z:54,KEYCODE_COMMA:55,KEYCODE_PERIOD:56,KEYCODE_ALT_LEFT:57,KEYCODE_ALT_RIGHT:58,KEYCODE_SHIFT_LEFT:59,KEYCODE_SHIFT_RIGHT:60,KEYCODE_TAB:61,KEYCODE_SPACE:62,ENTER:66,DEL:67,KEYCODE_GRAVE:68,KEYCODE_MINUS:69,KEYCODE_EQUALS:70,KEYCODE_LEFT_BRACKET:71,KEYCODE_RIGHT_BRACKET:72,KEYCODE_BACKSLASH:73,KEYCODE_SEMICOLON:74,KEYCODE_APOSTROPHE:75,KEYCODE_SLASH:76,MENU:82,KEYCODE_PAGE_UP:92,KEYCODE_PAGE_DOWN:93,KEYCODE_ESCAPE:111,FORWARD_DEL:112,KEYCODE_CTRL_LEFT:113,KEYCODE_CTRL_RIGHT:114,KEYCODE_META_LEFT:117,KEYCODE_META_RIGHT:118,KEYCODE_MOVE_HOME:122,KEYCODE_MOVE_END:123,KEYCODE_INSERT:124,KEYCODE_F1:131,KEYCODE_F2:132,KEYCODE_F3:133,KEYCODE_F4:134,KEYCODE_F5:135,KEYCODE_F6:136,KEYCODE_F7:137,KEYCODE_F8:138,KEYCODE_F9:139,KEYCODE_F10:140,KEYCODE_F11:141,KEYCODE_F12:142,KEYCODE_NUMPAD_0:144,KEYCODE_NUMPAD_1:145,KEYCODE_NUMPAD_2:146,KEYCODE_NUMPAD_3:147,KEYCODE_NUMPAD_4:148,KEYCODE_NUMPAD_5:149,KEYCODE_NUMPAD_6:150,KEYCODE_NUMPAD_7:151,KEYCODE_NUMPAD_8:152,KEYCODE_NUMPAD_9:153,KEYCODE_NUMPAD_DIVIDE:154,KEYCODE_NUMPAD_MULTIPLY:155,KEYCODE_NUMPAD_SUBTRACT:156,KEYCODE_NUMPAD_ADD:157,KEYCODE_NUMPAD_DOT:158,KEYCODE_NUMPAD_COMMA:159,KEYCODE_NUMPAD_ENTER:160,KEYCODE_NUMPAD_EQUALS:161},re={KeyA:e.KEYCODE_A,KeyB:e.KEYCODE_B,KeyC:e.KEYCODE_C,KeyD:e.KEYCODE_D,KeyE:e.KEYCODE_E,KeyF:e.KEYCODE_F,KeyG:e.KEYCODE_G,KeyH:e.KEYCODE_H,KeyI:e.KEYCODE_I,KeyJ:e.KEYCODE_J,KeyK:e.KEYCODE_K,KeyL:e.KEYCODE_L,KeyM:e.KEYCODE_M,KeyN:e.KEYCODE_N,KeyO:e.KEYCODE_O,KeyP:e.KEYCODE_P,KeyQ:e.KEYCODE_Q,KeyR:e.KEYCODE_R,KeyS:e.KEYCODE_S,KeyT:e.KEYCODE_T,KeyU:e.KEYCODE_U,KeyV:e.KEYCODE_V,KeyW:e.KEYCODE_W,KeyX:e.KEYCODE_X,KeyY:e.KEYCODE_Y,KeyZ:e.KEYCODE_Z,Digit0:e.KEYCODE_0,Digit1:e.KEYCODE_1,Digit2:e.KEYCODE_2,Digit3:e.KEYCODE_3,Digit4:e.KEYCODE_4,Digit5:e.KEYCODE_5,Digit6:e.KEYCODE_6,Digit7:e.KEYCODE_7,Digit8:e.KEYCODE_8,Digit9:e.KEYCODE_9,Backquote:e.KEYCODE_GRAVE,Minus:e.KEYCODE_MINUS,Equal:e.KEYCODE_EQUALS,BracketLeft:e.KEYCODE_LEFT_BRACKET,BracketRight:e.KEYCODE_RIGHT_BRACKET,Backslash:e.KEYCODE_BACKSLASH,Semicolon:e.KEYCODE_SEMICOLON,Quote:e.KEYCODE_APOSTROPHE,Comma:e.KEYCODE_COMMA,Period:e.KEYCODE_PERIOD,Slash:e.KEYCODE_SLASH,Space:e.KEYCODE_SPACE,Tab:e.KEYCODE_TAB,Escape:e.KEYCODE_ESCAPE,ArrowUp:e.DPAD_UP,ArrowDown:e.DPAD_DOWN,ArrowLeft:e.DPAD_LEFT,ArrowRight:e.DPAD_RIGHT,Enter:e.ENTER,Backspace:e.DEL,Delete:e.FORWARD_DEL,Home:e.KEYCODE_MOVE_HOME,End:e.KEYCODE_MOVE_END,PageUp:e.KEYCODE_PAGE_UP,PageDown:e.KEYCODE_PAGE_DOWN,Insert:e.KEYCODE_INSERT,F1:e.KEYCODE_F1,F2:e.KEYCODE_F2,F3:e.KEYCODE_F3,F4:e.KEYCODE_F4,F5:e.KEYCODE_F5,F6:e.KEYCODE_F6,F7:e.KEYCODE_F7,F8:e.KEYCODE_F8,F9:e.KEYCODE_F9,F10:e.KEYCODE_F10,F11:e.KEYCODE_F11,F12:e.KEYCODE_F12,ShiftLeft:e.KEYCODE_SHIFT_LEFT,ShiftRight:e.KEYCODE_SHIFT_RIGHT,ControlLeft:e.KEYCODE_CTRL_LEFT,ControlRight:e.KEYCODE_CTRL_RIGHT,AltLeft:e.KEYCODE_ALT_LEFT,AltRight:e.KEYCODE_ALT_RIGHT,MetaLeft:e.KEYCODE_META_LEFT,MetaRight:e.KEYCODE_META_RIGHT,ContextMenu:e.MENU,Numpad0:e.KEYCODE_NUMPAD_0,Numpad1:e.KEYCODE_NUMPAD_1,Numpad2:e.KEYCODE_NUMPAD_2,Numpad3:e.KEYCODE_NUMPAD_3,Numpad4:e.KEYCODE_NUMPAD_4,Numpad5:e.KEYCODE_NUMPAD_5,Numpad6:e.KEYCODE_NUMPAD_6,Numpad7:e.KEYCODE_NUMPAD_7,Numpad8:e.KEYCODE_NUMPAD_8,Numpad9:e.KEYCODE_NUMPAD_9,NumpadDivide:e.KEYCODE_NUMPAD_DIVIDE,NumpadMultiply:e.KEYCODE_NUMPAD_MULTIPLY,NumpadSubtract:e.KEYCODE_NUMPAD_SUBTRACT,NumpadAdd:e.KEYCODE_NUMPAD_ADD,NumpadDecimal:e.KEYCODE_NUMPAD_DOT,NumpadComma:e.KEYCODE_NUMPAD_COMMA,NumpadEnter:e.KEYCODE_NUMPAD_ENTER,NumpadEqual:e.KEYCODE_NUMPAD_EQUALS};function Ce(i,u,D,s,l,A,o=1,c=0,d=0){const C=new ArrayBuffer(32),N=new DataView(C);let _=0;return N.setUint8(_,j.INJECT_TOUCH_EVENT),_+=1,N.setUint8(_,i),_+=1,N.setBigInt64(_,BigInt(u)),_+=8,N.setInt32(_,Math.round(l),!0),_+=4,N.setInt32(_,Math.round(A),!0),_+=4,N.setUint16(_,D,!0),_+=2,N.setUint16(_,s,!0),_+=2,N.setInt16(_,Math.round(o*65535),!0),_+=2,N.setInt32(_,c,!0),_+=4,N.setInt32(_,d,!0),C}function De(i,u=!0){const s=new TextEncoder().encode(i),l=new ArrayBuffer(14+s.length),A=new DataView(l);let o=0;return A.setUint8(o,j.SET_CLIPBOARD),o+=1,A.setBigInt64(o,BigInt(0),!1),o+=8,A.setUint8(o,u?1:0),o+=1,A.setUint32(o,s.length,!1),o+=4,new Uint8Array(l,o).set(s),l}function W(i,u,D=0,s=0){const l=new ArrayBuffer(14),A=new DataView(l);let o=0;return A.setUint8(o,j.INJECT_KEYCODE),o+=1,A.setUint8(o,i),o+=1,A.setInt32(o,u,!0),o+=4,A.setInt32(o,D,!0),o+=4,A.setInt32(o,s,!0),l}const g=(...i)=>{window.debugRemoteControl&&console.log(...i)},Y=(...i)=>{window.debugRemoteControl&&console.warn(...i)};function Oe(i){const u=i.code,D=re[u];if(!D)return Y(`Unknown event.code: ${u}, key: ${i.key}`),null;let s=e.META_NONE;const l=u>="KeyA"&&u<="KeyZ",A=i.getModifierState("CapsLock"),o=i.shiftKey;let c=o;return l&&(c=o!==A),c&&(s|=e.META_SHIFT_ON),i.ctrlKey&&(s|=e.META_CTRL_ON),i.altKey&&(s|=e.META_ALT_ON),i.metaKey&&(s|=e.META_META_ON),{keycode:D,metaState:s}}const Ke=T.forwardRef(({className:i,url:u,token:D,sessionId:s,openUrl:l},A)=>{const o=T.useRef(null),c=T.useRef(null),d=T.useRef(null),C=T.useRef(null),[N,_]=T.useState(!1),k=T.useRef(void 0),I=T.useRef(new Map),U=T.useRef(new Map),m=T.useRef(new Map),R=T.useMemo(()=>s||Math.random().toString(36).substring(2,15)+Math.random().toString(36).substring(2,15),[s]),O=n=>{g(n)},L=n=>{!C.current||C.current.readyState!=="open"||C.current.send(n)},S=n=>{if(n.preventDefault(),n.stopPropagation(),!C.current||C.current.readyState!=="open"||!o.current)return;const K=o.current,E=K.getBoundingClientRect(),t=K.videoWidth,r=K.videoHeight;if(!t||!r)return;const y=(a,f,p,M)=>{const h=E.width,v=E.height,$=t/r,se=h/v;let H=h,B=v;$>se?B=h/$:H=v*$;const ae=(h-H)/2,de=(v-B)/2,V=f-E.left-ae,G=p-E.top-de,x=V>=0&&V<=H&&G>=0&&G<=B;let J=0,q=0;x&&(J=Math.max(0,Math.min(t,V/H*t)),q=Math.max(0,Math.min(r,G/B*r)));let w=null,P=null,ue=1;const ee=F.BUTTON_PRIMARY;switch(M){case"down":x?(w=F.ACTION_DOWN,P={x:J,y:q},m.current.set(a,P),a===-1&&o.current?.focus()):m.current.delete(a);break;case"move":m.current.has(a)&&x&&(w=F.ACTION_MOVE,P={x:J,y:q},m.current.set(a,P));break;case"up":case"cancel":m.current.has(a)&&(w=M==="cancel"?F.ACTION_CANCEL:F.ACTION_UP,P=m.current.get(a),m.current.delete(a));break}if(w!==null&&P!==null){const te=Ce(w,a,t,r,P.x,P.y,ue,ee,ee);te&&L(te)}else(M==="up"||M==="cancel")&&m.current.delete(a)};if("touches"in n){const a=n.changedTouches;let f;switch(n.type){case"touchstart":f="down";break;case"touchmove":f="move";break;case"touchend":f="up";break;case"touchcancel":f="cancel";break;default:return}for(let p=0;p<a.length;p++){const M=a[p];y(M.identifier,M.clientX,M.clientY,f)}}else{let f=null;switch(n.type){case"mousedown":n.button===0&&(f="down");break;case"mousemove":m.current.has(-1)&&(f="move");break;case"mouseup":n.button===0&&(f="up");break;case"mouseleave":m.current.has(-1)&&(f="up");break}f&&y(-1,n.clientX,n.clientY,f)}},Q=n=>{if(n.preventDefault(),n.stopPropagation(),g("Keyboard event:",{type:n.type,key:n.key,keyCode:n.keyCode,code:n.code,target:n.target.tagName,focused:document.activeElement===o.current}),document.activeElement!==o.current){Y("Video element not focused, skipping keyboard event");return}if(!C.current||C.current.readyState!=="open"){Y("Data channel not ready for keyboard event:",C.current?.readyState);return}if(n.type==="keydown"){if(n.key.toLowerCase()==="v"&&(n.metaKey||n.ctrlKey)){g("Paste shortcut detected"),navigator.clipboard.readText().then(E=>{if(E){g("Pasting text via SET_CLIPBOARD:",E.substring(0,20)+(E.length>20?"...":""));const t=De(E,!0);L(t)}}).catch(E=>{console.error("Failed to read clipboard contents: ",E)});return}if(n.key.toLowerCase()==="m"&&(n.metaKey||n.ctrlKey)){g("Menu shortcut detected");const E=W(e.ACTION_DOWN,e.MENU,0,e.META_NONE);L(E);const t=W(e.ACTION_UP,e.MENU,0,e.META_NONE);L(t);return}}const K=Oe(n);if(K){const{keycode:E,metaState:t}=K,r=n.type==="keydown"?e.ACTION_DOWN:e.ACTION_UP;g(`Sending Keycode: key=${n.key}, code=${E}, action=${r}, meta=${t}`);const y=W(r,E,0,t);L(y)}else g(`Ignoring unhandled key event: type=${n.type}, key=${n.key}`)},oe=()=>{c.current&&c.current.readyState===WebSocket.OPEN&&c.current.send(JSON.stringify({type:"keepAlive",sessionId:R}))},X=()=>{k.current&&window.clearInterval(k.current),k.current=window.setInterval(oe,1e4)},Z=()=>{k.current&&(window.clearInterval(k.current),k.current=void 0)},z=()=>{document.hidden?Z():X()},ce=async()=>{try{c.current=new WebSocket(`${u}?token=${D}`),c.current.onerror=t=>{O("WebSocket error: "+t)},c.current.onclose=()=>{O("WebSocket closed")},await new Promise((t,r)=>{c.current&&(c.current.onopen=t,setTimeout(()=>r(new Error("WebSocket connection timeout")),5e3))});const K=await new Promise((t,r)=>{const y=setTimeout(()=>r(new Error("RTCConfiguration timeout")),5e3),a=f=>{try{const p=JSON.parse(f.data);p.type==="rtcConfiguration"&&(clearTimeout(y),c.current?.removeEventListener("message",a),t(p.rtcConfiguration))}catch(p){console.error("Error handling RTC configuration:",p),r(p)}};c.current?.addEventListener("message",a),c.current?.send(JSON.stringify({type:"requestRtcConfiguration",sessionId:R}))});d.current=new RTCPeerConnection(K),d.current.addTransceiver("audio",{direction:"recvonly"});const E=d.current.addTransceiver("video",{direction:"recvonly"});if(RTCRtpReceiver.getCapabilities){const t=RTCRtpReceiver.getCapabilities("video");if(t&&t.codecs){const y=t.codecs.sort((a,f)=>{const p=M=>{const h=M.mimeType.toLowerCase();return h.includes("vp9")?1:h.includes("h265")||h.includes("hevc")?2:h.includes("h264")||h.includes("avc")?3:4};return p(a)-p(f)});E.setCodecPreferences(y),g("Set codec preferences:",y.map(a=>a.mimeType).join(", "))}}if(C.current=d.current.createDataChannel("control",{ordered:!0,negotiated:!0,id:1}),C.current.onopen=()=>{if(O("Control channel opened"),c.current){for(let t=0;t<12;t++)setTimeout(()=>{c.current&&c.current.send(JSON.stringify({type:"requestFrame",sessionId:R}))},t*125);if(l)try{const t=decodeURIComponent(l);O("Opening URL"),c.current.send(JSON.stringify({type:"openUrl",url:t,sessionId:R}))}catch(t){console.error({error:t},"Error decoding URL, falling back to the original URL"),c.current.send(JSON.stringify({type:"openUrl",url:l,sessionId:R}))}}},C.current.onclose=()=>{O("Control channel closed")},C.current.onerror=t=>{console.error("Control channel error:",t),O("Control channel error: "+t)},d.current.onconnectionstatechange=()=>{O("Connection state: "+d.current?.connectionState),_(d.current?.connectionState==="connected")},d.current.oniceconnectionstatechange=()=>{O("ICE state: "+d.current?.iceConnectionState)},d.current.ontrack=t=>{O("Received remote track: "+t.track.kind),t.track.kind==="video"&&o.current&&(g(`[${new Date().toISOString()}] Video track received:`,t.track),o.current.srcObject=t.streams[0])},d.current.onicecandidate=t=>{if(t.candidate&&c.current){const r={type:"candidate",candidate:t.candidate.candidate,sdpMid:t.candidate.sdpMid,sdpMLineIndex:t.candidate.sdpMLineIndex,sessionId:R};c.current.send(JSON.stringify(r)),O("Sent ICE candidate")}else O("ICE candidate gathering completed")},c.current.onmessage=async t=>{let r;try{r=JSON.parse(t.data)}catch(y){Y("Error parsing message:",y);return}switch(O("Received: "+r.type),r.type){case"answer":if(!d.current){O("No peer connection, skipping answer");break}await d.current.setRemoteDescription(new RTCSessionDescription({type:"answer",sdp:r.sdp})),O("Set remote description");break;case"candidate":if(!d.current){O("No peer connection, skipping candidate");break}await d.current.addIceCandidate(new RTCIceCandidate({candidate:r.candidate,sdpMid:r.sdpMid,sdpMLineIndex:r.sdpMLineIndex})),O("Added ICE candidate");break;case"screenshot":if(typeof r.id!="string"||typeof r.dataUri!="string"){Y("Received invalid screenshot success message:",r);break}const y=I.current.get(r.id);if(!y){Y(`Received screenshot data for unknown or handled id: ${r.id}`);break}g(`Received screenshot data for id ${r.id}`),y({dataUri:r.dataUri}),I.current.delete(r.id),U.current.delete(r.id);break;case"screenshotError":if(typeof r.id!="string"||typeof r.message!="string"){Y("Received invalid screenshot error message:",r);break}const a=U.current.get(r.id);if(!a){Y(`Received screenshot error for unknown or handled id: ${r.id}`);break}Y(`Received screenshot error for id ${r.id}: ${r.message}`),a(new Error(r.message)),I.current.delete(r.id),U.current.delete(r.id);break;default:Y(`Received unhandled message type: ${r.type}`,r);break}},d.current){const t=await d.current.createOffer({offerToReceiveVideo:!0,offerToReceiveAudio:!1});await d.current.setLocalDescription(t),c.current&&c.current.send(JSON.stringify({type:"offer",sdp:t.sdp,sessionId:R})),O("Sent offer")}}catch(n){O("Error: "+n)}},Ee=()=>{c.current&&(c.current.close(),c.current=null),d.current&&(d.current.close(),d.current=null),o.current&&(o.current.srcObject=null),C.current&&(C.current.close(),C.current=null),_(!1),O("Stopped")};T.useEffect(()=>(ce(),document.hidden||X(),document.addEventListener("visibilitychange",z),()=>{Z(),Ee(),document.removeEventListener("visibilitychange",z)}),[u,D,s]);const ie=()=>{o.current&&o.current.focus()};return T.useImperativeHandle(A,()=>({openUrl:n=>{if(!c.current||c.current.readyState!==WebSocket.OPEN){Y("WebSocket not open, cannot send open_url command via ref.");return}try{const K=decodeURIComponent(n);O("Opening URL"),c.current.send(JSON.stringify({type:"openUrl",url:K,sessionId:R}))}catch(K){Y("Error decoding or sending URL via ref:",{error:K,url:n}),c.current.send(JSON.stringify({type:"openUrl",url:n,sessionId:R}))}},sendKeyEvent:n=>{if(!C.current||C.current.readyState!=="open"){Y("Data channel not ready for imperative key command:",C.current?.readyState);return}const K=re[n.code];if(!K){Y(`Unknown event.code for imperative command: ${n.code}`);return}let E=e.META_NONE;n.shiftKey&&(E|=e.META_SHIFT_ON),n.altKey&&(E|=e.META_ALT_ON),n.ctrlKey&&(E|=e.META_CTRL_ON),n.metaKey&&(E|=e.META_META_ON);const t=n.type==="keydown"?e.ACTION_DOWN:e.ACTION_UP;g(`Sending Imperative Key Command: code=${n.code}, keycode=${K}, action=${t}, meta=${E}`);const r=W(t,K,0,E);r&&L(r)},screenshot:()=>new Promise((n,K)=>{if(!c.current||c.current.readyState!==WebSocket.OPEN)return Y("WebSocket not open, cannot send screenshot command."),K(new Error("WebSocket is not connected or connection is not open."));const E=`ui-ss-${Date.now()}-${Math.random().toString(36).substring(2,9)}`,t={type:"screenshot",id:E};I.current.set(E,n),U.current.set(E,K),g("Sending screenshot request:",t);try{c.current.send(JSON.stringify(t))}catch(r){Y("Failed to send screenshot request immediately:",r),I.current.delete(E),U.current.delete(E),K(r);return}setTimeout(()=>{I.current.has(E)&&(Y(`Screenshot request timed out for id ${E}`),U.current.get(E)?.(new Error("Screenshot request timed out")),I.current.delete(E),U.current.delete(E))},3e4)})})),b.jsxs("div",{className:_e("rc-container",i),style:{touchAction:"none"},onMouseDown:S,onMouseMove:S,onMouseUp:S,onMouseLeave:S,onTouchStart:S,onTouchMove:S,onTouchEnd:S,onTouchCancel:S,children:[b.jsx("video",{ref:o,className:"rc-video",autoPlay:!0,playsInline:!0,muted:!0,tabIndex:0,style:{outline:"none",pointerEvents:"none"},onKeyDown:Q,onKeyUp:Q,onClick:ie,onFocus:()=>{o.current&&(o.current.style.outline="none")},onBlur:()=>{o.current&&(o.current.style.outline="none")}}),!N&&b.jsxs("div",{className:"rc-placeholder-wrapper",children:[b.jsx("div",{className:"rc-spinner"}),b.jsx("p",{className:"rc-placeholder-content",children:"Connecting..."})]})]})});exports.RemoteControl=Ke;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});require('./index.css');const b=require("react/jsx-runtime"),T=require("react");function ne(i){var u,D,s="";if(typeof i=="string"||typeof i=="number")s+=i;else if(typeof i=="object")if(Array.isArray(i)){var l=i.length;for(u=0;u<l;u++)i[u]&&(D=ne(i[u]))&&(s&&(s+=" "),s+=D)}else for(D in i)i[D]&&(s&&(s+=" "),s+=D);return s}function _e(){for(var i,u,D=0,s="",l=arguments.length;D<l;D++)(i=arguments[D])&&(u=ne(i))&&(s&&(s+=" "),s+=u);return s}const j={INJECT_KEYCODE:0,INJECT_TOUCH_EVENT:2,SET_CLIPBOARD:9},F={ACTION_DOWN:0,ACTION_UP:1,ACTION_MOVE:2,ACTION_CANCEL:3,BUTTON_PRIMARY:1},e={ACTION_DOWN:0,ACTION_UP:1,META_NONE:0,META_SHIFT_ON:1,META_ALT_ON:2,META_CTRL_ON:4096,META_META_ON:65536,KEYCODE_0:7,KEYCODE_1:8,KEYCODE_2:9,KEYCODE_3:10,KEYCODE_4:11,KEYCODE_5:12,KEYCODE_6:13,KEYCODE_7:14,KEYCODE_8:15,KEYCODE_9:16,DPAD_UP:19,DPAD_DOWN:20,DPAD_LEFT:21,DPAD_RIGHT:22,KEYCODE_A:29,KEYCODE_B:30,KEYCODE_C:31,KEYCODE_D:32,KEYCODE_E:33,KEYCODE_F:34,KEYCODE_G:35,KEYCODE_H:36,KEYCODE_I:37,KEYCODE_J:38,KEYCODE_K:39,KEYCODE_L:40,KEYCODE_M:41,KEYCODE_N:42,KEYCODE_O:43,KEYCODE_P:44,KEYCODE_Q:45,KEYCODE_R:46,KEYCODE_S:47,KEYCODE_T:48,KEYCODE_U:49,KEYCODE_V:50,KEYCODE_W:51,KEYCODE_X:52,KEYCODE_Y:53,KEYCODE_Z:54,KEYCODE_COMMA:55,KEYCODE_PERIOD:56,KEYCODE_ALT_LEFT:57,KEYCODE_ALT_RIGHT:58,KEYCODE_SHIFT_LEFT:59,KEYCODE_SHIFT_RIGHT:60,KEYCODE_TAB:61,KEYCODE_SPACE:62,ENTER:66,DEL:67,KEYCODE_GRAVE:68,KEYCODE_MINUS:69,KEYCODE_EQUALS:70,KEYCODE_LEFT_BRACKET:71,KEYCODE_RIGHT_BRACKET:72,KEYCODE_BACKSLASH:73,KEYCODE_SEMICOLON:74,KEYCODE_APOSTROPHE:75,KEYCODE_SLASH:76,MENU:82,KEYCODE_PAGE_UP:92,KEYCODE_PAGE_DOWN:93,KEYCODE_ESCAPE:111,FORWARD_DEL:112,KEYCODE_CTRL_LEFT:113,KEYCODE_CTRL_RIGHT:114,KEYCODE_META_LEFT:117,KEYCODE_META_RIGHT:118,KEYCODE_MOVE_HOME:122,KEYCODE_MOVE_END:123,KEYCODE_INSERT:124,KEYCODE_F1:131,KEYCODE_F2:132,KEYCODE_F3:133,KEYCODE_F4:134,KEYCODE_F5:135,KEYCODE_F6:136,KEYCODE_F7:137,KEYCODE_F8:138,KEYCODE_F9:139,KEYCODE_F10:140,KEYCODE_F11:141,KEYCODE_F12:142,KEYCODE_NUMPAD_0:144,KEYCODE_NUMPAD_1:145,KEYCODE_NUMPAD_2:146,KEYCODE_NUMPAD_3:147,KEYCODE_NUMPAD_4:148,KEYCODE_NUMPAD_5:149,KEYCODE_NUMPAD_6:150,KEYCODE_NUMPAD_7:151,KEYCODE_NUMPAD_8:152,KEYCODE_NUMPAD_9:153,KEYCODE_NUMPAD_DIVIDE:154,KEYCODE_NUMPAD_MULTIPLY:155,KEYCODE_NUMPAD_SUBTRACT:156,KEYCODE_NUMPAD_ADD:157,KEYCODE_NUMPAD_DOT:158,KEYCODE_NUMPAD_COMMA:159,KEYCODE_NUMPAD_ENTER:160,KEYCODE_NUMPAD_EQUALS:161},re={KeyA:e.KEYCODE_A,KeyB:e.KEYCODE_B,KeyC:e.KEYCODE_C,KeyD:e.KEYCODE_D,KeyE:e.KEYCODE_E,KeyF:e.KEYCODE_F,KeyG:e.KEYCODE_G,KeyH:e.KEYCODE_H,KeyI:e.KEYCODE_I,KeyJ:e.KEYCODE_J,KeyK:e.KEYCODE_K,KeyL:e.KEYCODE_L,KeyM:e.KEYCODE_M,KeyN:e.KEYCODE_N,KeyO:e.KEYCODE_O,KeyP:e.KEYCODE_P,KeyQ:e.KEYCODE_Q,KeyR:e.KEYCODE_R,KeyS:e.KEYCODE_S,KeyT:e.KEYCODE_T,KeyU:e.KEYCODE_U,KeyV:e.KEYCODE_V,KeyW:e.KEYCODE_W,KeyX:e.KEYCODE_X,KeyY:e.KEYCODE_Y,KeyZ:e.KEYCODE_Z,Digit0:e.KEYCODE_0,Digit1:e.KEYCODE_1,Digit2:e.KEYCODE_2,Digit3:e.KEYCODE_3,Digit4:e.KEYCODE_4,Digit5:e.KEYCODE_5,Digit6:e.KEYCODE_6,Digit7:e.KEYCODE_7,Digit8:e.KEYCODE_8,Digit9:e.KEYCODE_9,Backquote:e.KEYCODE_GRAVE,Minus:e.KEYCODE_MINUS,Equal:e.KEYCODE_EQUALS,BracketLeft:e.KEYCODE_LEFT_BRACKET,BracketRight:e.KEYCODE_RIGHT_BRACKET,Backslash:e.KEYCODE_BACKSLASH,Semicolon:e.KEYCODE_SEMICOLON,Quote:e.KEYCODE_APOSTROPHE,Comma:e.KEYCODE_COMMA,Period:e.KEYCODE_PERIOD,Slash:e.KEYCODE_SLASH,Space:e.KEYCODE_SPACE,Tab:e.KEYCODE_TAB,Escape:e.KEYCODE_ESCAPE,ArrowUp:e.DPAD_UP,ArrowDown:e.DPAD_DOWN,ArrowLeft:e.DPAD_LEFT,ArrowRight:e.DPAD_RIGHT,Enter:e.ENTER,Backspace:e.DEL,Delete:e.FORWARD_DEL,Home:e.KEYCODE_MOVE_HOME,End:e.KEYCODE_MOVE_END,PageUp:e.KEYCODE_PAGE_UP,PageDown:e.KEYCODE_PAGE_DOWN,Insert:e.KEYCODE_INSERT,F1:e.KEYCODE_F1,F2:e.KEYCODE_F2,F3:e.KEYCODE_F3,F4:e.KEYCODE_F4,F5:e.KEYCODE_F5,F6:e.KEYCODE_F6,F7:e.KEYCODE_F7,F8:e.KEYCODE_F8,F9:e.KEYCODE_F9,F10:e.KEYCODE_F10,F11:e.KEYCODE_F11,F12:e.KEYCODE_F12,ShiftLeft:e.KEYCODE_SHIFT_LEFT,ShiftRight:e.KEYCODE_SHIFT_RIGHT,ControlLeft:e.KEYCODE_CTRL_LEFT,ControlRight:e.KEYCODE_CTRL_RIGHT,AltLeft:e.KEYCODE_ALT_LEFT,AltRight:e.KEYCODE_ALT_RIGHT,MetaLeft:e.KEYCODE_META_LEFT,MetaRight:e.KEYCODE_META_RIGHT,ContextMenu:e.MENU,Numpad0:e.KEYCODE_NUMPAD_0,Numpad1:e.KEYCODE_NUMPAD_1,Numpad2:e.KEYCODE_NUMPAD_2,Numpad3:e.KEYCODE_NUMPAD_3,Numpad4:e.KEYCODE_NUMPAD_4,Numpad5:e.KEYCODE_NUMPAD_5,Numpad6:e.KEYCODE_NUMPAD_6,Numpad7:e.KEYCODE_NUMPAD_7,Numpad8:e.KEYCODE_NUMPAD_8,Numpad9:e.KEYCODE_NUMPAD_9,NumpadDivide:e.KEYCODE_NUMPAD_DIVIDE,NumpadMultiply:e.KEYCODE_NUMPAD_MULTIPLY,NumpadSubtract:e.KEYCODE_NUMPAD_SUBTRACT,NumpadAdd:e.KEYCODE_NUMPAD_ADD,NumpadDecimal:e.KEYCODE_NUMPAD_DOT,NumpadComma:e.KEYCODE_NUMPAD_COMMA,NumpadEnter:e.KEYCODE_NUMPAD_ENTER,NumpadEqual:e.KEYCODE_NUMPAD_EQUALS};function Ce(i,u,D,s,l,A,o=1,c=0,d=0){const C=new ArrayBuffer(32),N=new DataView(C);let _=0;return N.setUint8(_,j.INJECT_TOUCH_EVENT),_+=1,N.setUint8(_,i),_+=1,N.setBigInt64(_,BigInt(u)),_+=8,N.setInt32(_,Math.round(l),!0),_+=4,N.setInt32(_,Math.round(A),!0),_+=4,N.setUint16(_,D,!0),_+=2,N.setUint16(_,s,!0),_+=2,N.setInt16(_,Math.round(o*65535),!0),_+=2,N.setInt32(_,c,!0),_+=4,N.setInt32(_,d,!0),C}function De(i,u=!0){const s=new TextEncoder().encode(i),l=new ArrayBuffer(14+s.length),A=new DataView(l);let o=0;return A.setUint8(o,j.SET_CLIPBOARD),o+=1,A.setBigInt64(o,BigInt(0),!1),o+=8,A.setUint8(o,u?1:0),o+=1,A.setUint32(o,s.length,!1),o+=4,new Uint8Array(l,o).set(s),l}function W(i,u,D=0,s=0){const l=new ArrayBuffer(14),A=new DataView(l);let o=0;return A.setUint8(o,j.INJECT_KEYCODE),o+=1,A.setUint8(o,i),o+=1,A.setInt32(o,u,!0),o+=4,A.setInt32(o,D,!0),o+=4,A.setInt32(o,s,!0),l}const g=(...i)=>{window.debugRemoteControl&&console.log(...i)},Y=(...i)=>{window.debugRemoteControl&&console.warn(...i)};function Oe(i){const u=i.code,D=re[u];if(!D)return Y(`Unknown event.code: ${u}, key: ${i.key}`),null;let s=e.META_NONE;const l=u>="KeyA"&&u<="KeyZ",A=i.getModifierState("CapsLock"),o=i.shiftKey;let c=o;return l&&(c=o!==A),c&&(s|=e.META_SHIFT_ON),i.ctrlKey&&(s|=e.META_CTRL_ON),i.altKey&&(s|=e.META_ALT_ON),i.metaKey&&(s|=e.META_META_ON),{keycode:D,metaState:s}}const Ke=T.forwardRef(({className:i,url:u,token:D,sessionId:s,openUrl:l},A)=>{const o=T.useRef(null),c=T.useRef(null),d=T.useRef(null),C=T.useRef(null),[N,_]=T.useState(!1),k=T.useRef(void 0),I=T.useRef(new Map),U=T.useRef(new Map),m=T.useRef(new Map),R=T.useMemo(()=>s||Math.random().toString(36).substring(2,15)+Math.random().toString(36).substring(2,15),[s]),O=n=>{g(n)},L=n=>{!C.current||C.current.readyState!=="open"||C.current.send(n)},S=n=>{if(n.preventDefault(),n.stopPropagation(),!C.current||C.current.readyState!=="open"||!o.current)return;const K=o.current,E=K.getBoundingClientRect(),t=K.videoWidth,r=K.videoHeight;if(!t||!r)return;const y=(a,f,p,M)=>{const h=E.width,v=E.height,$=t/r,se=h/v;let H=h,B=v;$>se?B=h/$:H=v*$;const ae=(h-H)/2,de=(v-B)/2,V=f-E.left-ae,G=p-E.top-de,x=V>=0&&V<=H&&G>=0&&G<=B;let J=0,q=0;x&&(J=Math.max(0,Math.min(t,V/H*t)),q=Math.max(0,Math.min(r,G/B*r)));let w=null,P=null,ue=1;const ee=F.BUTTON_PRIMARY;switch(M){case"down":x?(w=F.ACTION_DOWN,P={x:J,y:q},m.current.set(a,P),a===-1&&o.current?.focus()):m.current.delete(a);break;case"move":m.current.has(a)&&x&&(w=F.ACTION_MOVE,P={x:J,y:q},m.current.set(a,P));break;case"up":case"cancel":m.current.has(a)&&(w=M==="cancel"?F.ACTION_CANCEL:F.ACTION_UP,P=m.current.get(a),m.current.delete(a));break}if(w!==null&&P!==null){const te=Ce(w,a,t,r,P.x,P.y,ue,ee,ee);te&&L(te)}else(M==="up"||M==="cancel")&&m.current.delete(a)};if("touches"in n){const a=n.changedTouches;let f;switch(n.type){case"touchstart":f="down";break;case"touchmove":f="move";break;case"touchend":f="up";break;case"touchcancel":f="cancel";break;default:return}for(let p=0;p<a.length;p++){const M=a[p];y(M.identifier,M.clientX,M.clientY,f)}}else{let f=null;switch(n.type){case"mousedown":n.button===0&&(f="down");break;case"mousemove":m.current.has(-1)&&(f="move");break;case"mouseup":n.button===0&&(f="up");break;case"mouseleave":m.current.has(-1)&&(f="up");break}f&&y(-1,n.clientX,n.clientY,f)}},Q=n=>{if(n.preventDefault(),n.stopPropagation(),g("Keyboard event:",{type:n.type,key:n.key,keyCode:n.keyCode,code:n.code,target:n.target.tagName,focused:document.activeElement===o.current}),document.activeElement!==o.current){Y("Video element not focused, skipping keyboard event");return}if(!C.current||C.current.readyState!=="open"){Y("Data channel not ready for keyboard event:",C.current?.readyState);return}if(n.type==="keydown"){if(n.key.toLowerCase()==="v"&&(n.metaKey||n.ctrlKey)){g("Paste shortcut detected"),navigator.clipboard.readText().then(E=>{if(E){g("Pasting text via SET_CLIPBOARD:",E.substring(0,20)+(E.length>20?"...":""));const t=De(E,!0);L(t)}}).catch(E=>{console.error("Failed to read clipboard contents: ",E)});return}if(n.key.toLowerCase()==="m"&&(n.metaKey||n.ctrlKey)){g("Menu shortcut detected");const E=W(e.ACTION_DOWN,e.MENU,0,e.META_NONE);L(E);const t=W(e.ACTION_UP,e.MENU,0,e.META_NONE);L(t);return}}const K=Oe(n);if(K){const{keycode:E,metaState:t}=K,r=n.type==="keydown"?e.ACTION_DOWN:e.ACTION_UP;g(`Sending Keycode: key=${n.key}, code=${E}, action=${r}, meta=${t}`);const y=W(r,E,0,t);L(y)}else g(`Ignoring unhandled key event: type=${n.type}, key=${n.key}`)},oe=()=>{c.current&&c.current.readyState===WebSocket.OPEN&&c.current.send(JSON.stringify({type:"keepAlive",sessionId:R}))},X=()=>{k.current&&window.clearInterval(k.current),k.current=window.setInterval(oe,1e4)},Z=()=>{k.current&&(window.clearInterval(k.current),k.current=void 0)},z=()=>{document.hidden?Z():X()},ce=async()=>{try{c.current=new WebSocket(`${u}?token=${D}`),c.current.onerror=t=>{O("WebSocket error: "+t)},c.current.onclose=()=>{O("WebSocket closed")},await new Promise((t,r)=>{c.current&&(c.current.onopen=t,setTimeout(()=>r(new Error("WebSocket connection timeout")),3e4))});const K=await new Promise((t,r)=>{const y=setTimeout(()=>r(new Error("RTCConfiguration timeout")),3e4),a=f=>{try{const p=JSON.parse(f.data);p.type==="rtcConfiguration"&&(clearTimeout(y),c.current?.removeEventListener("message",a),t(p.rtcConfiguration))}catch(p){console.error("Error handling RTC configuration:",p),r(p)}};c.current?.addEventListener("message",a),c.current?.send(JSON.stringify({type:"requestRtcConfiguration",sessionId:R}))});d.current=new RTCPeerConnection(K),d.current.addTransceiver("audio",{direction:"recvonly"});const E=d.current.addTransceiver("video",{direction:"recvonly"});if(RTCRtpReceiver.getCapabilities){const t=RTCRtpReceiver.getCapabilities("video");if(t&&t.codecs){const y=t.codecs.sort((a,f)=>{const p=M=>{const h=M.mimeType.toLowerCase();return h.includes("vp9")?1:h.includes("h265")||h.includes("hevc")?2:h.includes("h264")||h.includes("avc")?3:4};return p(a)-p(f)});E.setCodecPreferences(y),g("Set codec preferences:",y.map(a=>a.mimeType).join(", "))}}if(C.current=d.current.createDataChannel("control",{ordered:!0,negotiated:!0,id:1}),C.current.onopen=()=>{if(O("Control channel opened"),c.current){for(let t=0;t<12;t++)setTimeout(()=>{c.current&&c.current.send(JSON.stringify({type:"requestFrame",sessionId:R}))},t*125);if(l)try{const t=decodeURIComponent(l);O("Opening URL"),c.current.send(JSON.stringify({type:"openUrl",url:t,sessionId:R}))}catch(t){console.error({error:t},"Error decoding URL, falling back to the original URL"),c.current.send(JSON.stringify({type:"openUrl",url:l,sessionId:R}))}}},C.current.onclose=()=>{O("Control channel closed")},C.current.onerror=t=>{console.error("Control channel error:",t),O("Control channel error: "+t)},d.current.onconnectionstatechange=()=>{O("Connection state: "+d.current?.connectionState),_(d.current?.connectionState==="connected")},d.current.oniceconnectionstatechange=()=>{O("ICE state: "+d.current?.iceConnectionState)},d.current.ontrack=t=>{O("Received remote track: "+t.track.kind),t.track.kind==="video"&&o.current&&(g(`[${new Date().toISOString()}] Video track received:`,t.track),o.current.srcObject=t.streams[0])},d.current.onicecandidate=t=>{if(t.candidate&&c.current){const r={type:"candidate",candidate:t.candidate.candidate,sdpMid:t.candidate.sdpMid,sdpMLineIndex:t.candidate.sdpMLineIndex,sessionId:R};c.current.send(JSON.stringify(r)),O("Sent ICE candidate")}else O("ICE candidate gathering completed")},c.current.onmessage=async t=>{let r;try{r=JSON.parse(t.data)}catch(y){Y("Error parsing message:",y);return}switch(O("Received: "+r.type),r.type){case"answer":if(!d.current){O("No peer connection, skipping answer");break}await d.current.setRemoteDescription(new RTCSessionDescription({type:"answer",sdp:r.sdp})),O("Set remote description");break;case"candidate":if(!d.current){O("No peer connection, skipping candidate");break}await d.current.addIceCandidate(new RTCIceCandidate({candidate:r.candidate,sdpMid:r.sdpMid,sdpMLineIndex:r.sdpMLineIndex})),O("Added ICE candidate");break;case"screenshot":if(typeof r.id!="string"||typeof r.dataUri!="string"){Y("Received invalid screenshot success message:",r);break}const y=I.current.get(r.id);if(!y){Y(`Received screenshot data for unknown or handled id: ${r.id}`);break}g(`Received screenshot data for id ${r.id}`),y({dataUri:r.dataUri}),I.current.delete(r.id),U.current.delete(r.id);break;case"screenshotError":if(typeof r.id!="string"||typeof r.message!="string"){Y("Received invalid screenshot error message:",r);break}const a=U.current.get(r.id);if(!a){Y(`Received screenshot error for unknown or handled id: ${r.id}`);break}Y(`Received screenshot error for id ${r.id}: ${r.message}`),a(new Error(r.message)),I.current.delete(r.id),U.current.delete(r.id);break;default:Y(`Received unhandled message type: ${r.type}`,r);break}},d.current){const t=await d.current.createOffer({offerToReceiveVideo:!0,offerToReceiveAudio:!1});await d.current.setLocalDescription(t),c.current&&c.current.send(JSON.stringify({type:"offer",sdp:t.sdp,sessionId:R})),O("Sent offer")}}catch(n){O("Error: "+n)}},Ee=()=>{c.current&&(c.current.close(),c.current=null),d.current&&(d.current.close(),d.current=null),o.current&&(o.current.srcObject=null),C.current&&(C.current.close(),C.current=null),_(!1),O("Stopped")};T.useEffect(()=>(ce(),document.hidden||X(),document.addEventListener("visibilitychange",z),()=>{Z(),Ee(),document.removeEventListener("visibilitychange",z)}),[u,D,s]);const ie=()=>{o.current&&o.current.focus()};return T.useImperativeHandle(A,()=>({openUrl:n=>{if(!c.current||c.current.readyState!==WebSocket.OPEN){Y("WebSocket not open, cannot send open_url command via ref.");return}try{const K=decodeURIComponent(n);O("Opening URL"),c.current.send(JSON.stringify({type:"openUrl",url:K,sessionId:R}))}catch(K){Y("Error decoding or sending URL via ref:",{error:K,url:n}),c.current.send(JSON.stringify({type:"openUrl",url:n,sessionId:R}))}},sendKeyEvent:n=>{if(!C.current||C.current.readyState!=="open"){Y("Data channel not ready for imperative key command:",C.current?.readyState);return}const K=re[n.code];if(!K){Y(`Unknown event.code for imperative command: ${n.code}`);return}let E=e.META_NONE;n.shiftKey&&(E|=e.META_SHIFT_ON),n.altKey&&(E|=e.META_ALT_ON),n.ctrlKey&&(E|=e.META_CTRL_ON),n.metaKey&&(E|=e.META_META_ON);const t=n.type==="keydown"?e.ACTION_DOWN:e.ACTION_UP;g(`Sending Imperative Key Command: code=${n.code}, keycode=${K}, action=${t}, meta=${E}`);const r=W(t,K,0,E);r&&L(r)},screenshot:()=>new Promise((n,K)=>{if(!c.current||c.current.readyState!==WebSocket.OPEN)return Y("WebSocket not open, cannot send screenshot command."),K(new Error("WebSocket is not connected or connection is not open."));const E=`ui-ss-${Date.now()}-${Math.random().toString(36).substring(2,9)}`,t={type:"screenshot",id:E};I.current.set(E,n),U.current.set(E,K),g("Sending screenshot request:",t);try{c.current.send(JSON.stringify(t))}catch(r){Y("Failed to send screenshot request immediately:",r),I.current.delete(E),U.current.delete(E),K(r);return}setTimeout(()=>{I.current.has(E)&&(Y(`Screenshot request timed out for id ${E}`),U.current.get(E)?.(new Error("Screenshot request timed out")),I.current.delete(E),U.current.delete(E))},3e4)})})),b.jsxs("div",{className:_e("rc-container",i),style:{touchAction:"none"},onMouseDown:S,onMouseMove:S,onMouseUp:S,onMouseLeave:S,onTouchStart:S,onTouchMove:S,onTouchEnd:S,onTouchCancel:S,children:[b.jsx("video",{ref:o,className:"rc-video",autoPlay:!0,playsInline:!0,muted:!0,tabIndex:0,style:{outline:"none",pointerEvents:"none"},onKeyDown:Q,onKeyUp:Q,onClick:ie,onFocus:()=>{o.current&&(o.current.style.outline="none")},onBlur:()=>{o.current&&(o.current.style.outline="none")}}),!N&&b.jsxs("div",{className:"rc-placeholder-wrapper",children:[b.jsx("div",{className:"rc-spinner"}),b.jsx("p",{className:"rc-placeholder-content",children:"Connecting..."})]})]})});exports.RemoteControl=Ke;
package/dist/index.js CHANGED
@@ -462,10 +462,10 @@ const Te = Ce(
462
462
  }, c.current.onclose = () => {
463
463
  O("WebSocket closed");
464
464
  }, await new Promise((t, r) => {
465
- c.current && (c.current.onopen = t, setTimeout(() => r(new Error("WebSocket connection timeout")), 5e3));
465
+ c.current && (c.current.onopen = t, setTimeout(() => r(new Error("WebSocket connection timeout")), 3e4));
466
466
  });
467
467
  const K = await new Promise((t, r) => {
468
- const p = setTimeout(() => r(new Error("RTCConfiguration timeout")), 5e3), a = (f) => {
468
+ const p = setTimeout(() => r(new Error("RTCConfiguration timeout")), 3e4), a = (f) => {
469
469
  try {
470
470
  const y = JSON.parse(f.data);
471
471
  y.type === "rtcConfiguration" && (clearTimeout(p), c.current?.removeEventListener("message", a), t(y.rtcConfiguration));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@limrun/ui",
3
- "version": "0.3.1",
3
+ "version": "0.3.2",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -452,13 +452,13 @@ export const RemoteControl = forwardRef<RemoteControlHandle, RemoteControlProps>
452
452
  await new Promise((resolve, reject) => {
453
453
  if (wsRef.current) {
454
454
  wsRef.current.onopen = resolve;
455
- setTimeout(() => reject(new Error('WebSocket connection timeout')), 5000);
455
+ setTimeout(() => reject(new Error('WebSocket connection timeout')), 30000);
456
456
  }
457
457
  });
458
458
 
459
459
  // Request RTCConfiguration
460
460
  const rtcConfigPromise = new Promise<RTCConfiguration>((resolve, reject) => {
461
- const timeoutId = setTimeout(() => reject(new Error('RTCConfiguration timeout')), 5000);
461
+ const timeoutId = setTimeout(() => reject(new Error('RTCConfiguration timeout')), 30000);
462
462
 
463
463
  const messageHandler = (event: MessageEvent) => {
464
464
  try {