vue-streaming 2.0.1 → 2.0.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/WebSocketStream.vue_vue_type_script_setup_true_lang-D5IiGqMS.cjs +2 -0
- package/dist/WebSocketStream.vue_vue_type_script_setup_true_lang-D5IiGqMS.cjs.map +1 -0
- package/dist/WebSocketStream.vue_vue_type_script_setup_true_lang-D5yjtuTd.js +1240 -0
- package/dist/WebSocketStream.vue_vue_type_script_setup_true_lang-D5yjtuTd.js.map +1 -0
- package/dist/components/index.cjs +1 -1
- package/dist/components/index.js +3 -2
- package/dist/composables/index.cjs +1 -1
- package/dist/composables/index.js +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.js +53 -51
- package/dist/useWebSocket--HDylHpA.cjs +4 -0
- package/dist/useWebSocket--HDylHpA.cjs.map +1 -0
- package/dist/useWebSocket-C3JPFBmy.js +1328 -0
- package/dist/useWebSocket-C3JPFBmy.js.map +1 -0
- package/dist/utils/index.cjs +1 -1
- package/dist/utils/index.cjs.map +1 -1
- package/dist/utils/index.js +48 -38
- package/dist/utils/index.js.map +1 -1
- package/dist/vue-streaming.css +1 -1
- package/package.json +9 -2
- package/dist/WebSocketStream.vue_vue_type_script_setup_true_lang-BzBWoH8H.js +0 -1083
- package/dist/WebSocketStream.vue_vue_type_script_setup_true_lang-BzBWoH8H.js.map +0 -1
- package/dist/WebSocketStream.vue_vue_type_script_setup_true_lang-C7Kci1ME.cjs +0 -2
- package/dist/WebSocketStream.vue_vue_type_script_setup_true_lang-C7Kci1ME.cjs.map +0 -1
- package/dist/useWebSocket-8VThnC_J.cjs +0 -4
- package/dist/useWebSocket-8VThnC_J.cjs.map +0 -1
- package/dist/useWebSocket-D1Rqm0H7.js +0 -1278
- package/dist/useWebSocket-D1Rqm0H7.js.map +0 -1
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";var O=Object.create;var T=Object.defineProperty;var I=Object.getOwnPropertyDescriptor;var U=Object.getOwnPropertyNames;var j=Object.getPrototypeOf,W=Object.prototype.hasOwnProperty;var q=(g,C,S,t)=>{if(C&&typeof C=="object"||typeof C=="function")for(let n of U(C))!W.call(g,n)&&n!==S&&T(g,n,{get:()=>C[n],enumerable:!(t=I(C,n))||t.enumerable});return g};var F=(g,C,S)=>(S=g!=null?O(j(g)):{},q(C||!g||!g.__esModule?T(S,"default",{value:g,enumerable:!0}):S,g));const e=require("vue"),P=require("./useWebSocket--HDylHpA.cjs"),G={class:"hls-player"},J={class:"hls-player__video-container"},Q=["controls","muted","loop","poster"],K={key:0,class:"hls-player__overlay"},X={key:1,class:"hls-player__overlay hls-player__overlay--error"},Y={class:"hls-player__error"},Z={key:0,class:"hls-player__controls"},ee={class:"hls-player__quality"},te=["value"],ne=["value"],oe={class:"hls-player__stats"},re={key:0},ae=e.defineComponent({__name:"HLSPlayer",props:{src:{},autoPlay:{type:Boolean,default:!0},controls:{type:Boolean,default:!0},muted:{type:Boolean,default:!1},loop:{type:Boolean,default:!1},poster:{},lowLatency:{type:Boolean,default:!1},startLevel:{default:-1},videoClass:{}},emits:["ready","play","pause","ended","error","levelChange","timeUpdate","stateChange"],setup(g,{expose:C,emit:S}){const t=g,n=S,u=e.ref(null),y={url:t.src,autoPlay:t.autoPlay,lowLatencyMode:t.lowLatency,startLevel:t.startLevel},h={onManifestLoaded:E=>{n("ready")},onLevelSwitched:E=>{n("levelChange",E)},onPlaybackStarted:()=>{n("play")},onPlaybackEnded:()=>{n("ended")},onError:E=>{n("error",E)}},{state:a,isPlaying:l,isBuffering:v,levels:s,currentLevel:c,autoLevelEnabled:m,currentTime:_,duration:i,buffered:r,volume:f,muted:o,stats:w,error:d,isSupported:p,attach:b,play:B,pause:R,stop:k,seek:V,setLevel:x,setVolume:z,toggleMute:M,destroy:H}=P.useHLS(y,h);e.watch(a,E=>{n("stateChange",E)}),e.watch(_,E=>{n("timeUpdate",E)});function A(E){if(!isFinite(E))return"0:00";const N=Math.floor(E/60),$=Math.floor(E%60);return`${N}:${$.toString().padStart(2,"0")}`}const L=e.computed(()=>c.value<0||c.value>=s.value.length?null:s.value[c.value]);return e.onMounted(async()=>{if(u.value)try{await b(u.value)}catch(E){console.error("[HLSPlayer] Failed to attach:",E)}}),e.watch(()=>t.src,async E=>{u.value&&E&&(H(),load(E),await b(u.value))}),C({play:B,pause:R,stop:k,seek:V,setLevel:x,setVolume:z,toggleMute:M,state:a,levels:s,currentLevel:c,stats:w}),(E,N)=>(e.openBlock(),e.createElementBlock("div",G,[e.createElementVNode("div",J,[e.createElementVNode("video",{ref_key:"videoRef",ref:u,class:e.normalizeClass(["hls-player__video",E.videoClass]),controls:E.controls,muted:E.muted,loop:E.loop,poster:E.poster,playsinline:""},null,10,Q),e.unref(v)?(e.openBlock(),e.createElementBlock("div",K,[...N[1]||(N[1]=[e.createElementVNode("div",{class:"hls-player__spinner"},null,-1)])])):e.createCommentVNode("",!0),e.unref(d)?(e.openBlock(),e.createElementBlock("div",X,[e.createElementVNode("div",Y,[e.createElementVNode("span",null,"⚠️ "+e.toDisplayString(e.unref(d).message),1)])])):e.createCommentVNode("",!0)]),e.unref(s).length>1?(e.openBlock(),e.createElementBlock("div",Z,[e.createElementVNode("div",ee,[N[3]||(N[3]=e.createElementVNode("label",null,"Quality:",-1)),e.createElementVNode("select",{value:e.unref(c),onChange:N[0]||(N[0]=$=>e.unref(x)(Number($.target.value)))},[N[2]||(N[2]=e.createElementVNode("option",{value:-1},"Auto",-1)),(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(e.unref(s),$=>(e.openBlock(),e.createElementBlock("option",{key:$.index,value:$.index},e.toDisplayString($.height)+"p ("+e.toDisplayString(Math.round($.bitrate/1e3))+"kbps) ",9,ne))),128))],40,te)]),e.createElementVNode("div",oe,[L.value?(e.openBlock(),e.createElementBlock("span",re,e.toDisplayString(L.value.width)+"x"+e.toDisplayString(L.value.height),1)):e.createCommentVNode("",!0),e.createElementVNode("span",null,e.toDisplayString(Math.round(e.unref(w).bandwidth/1e6*10)/10)+" Mbps",1),e.createElementVNode("span",null,e.toDisplayString(A(e.unref(_)))+" / "+e.toDisplayString(A(e.unref(i))),1)])])):e.createCommentVNode("",!0)]))}}),D=(g,C)=>{const S=g.__vccOpts||g;for(const[t,n]of C)S[t]=n;return S},se=D(ae,[["__scopeId","data-v-2f6c6aae"]]),le={class:"pointcloud-viewer"},ce={key:0,class:"pointcloud-viewer__overlay"},ie={key:1,class:"pointcloud-viewer__overlay pointcloud-viewer__overlay--error"},ue={class:"pointcloud-viewer__stats"},de={key:0},fe=e.defineComponent({__name:"PointCloudViewer",props:{points:{},pointSize:{default:.02},pointColor:{default:65280},usePointColors:{type:Boolean,default:!0},cameraPosition:{default:()=>({x:5,y:5,z:5})},autoRotate:{type:Boolean,default:!1},autoRotateSpeed:{default:1},backgroundColor:{default:1973790},showAxes:{type:Boolean,default:!1},showGrid:{type:Boolean,default:!0},bounds:{}},emits:["ready","click","error"],setup(g,{expose:C,emit:S}){const t=g,n=S,u=e.ref(null),y=e.ref(!0),h=e.ref(null);let a=null,l=null,v=null,s=null,c=null,m=null,_=null,i=null;async function r(){if(u.value)try{a=await import("three");const{OrbitControls:p}=await import("three/examples/jsm/controls/OrbitControls.js"),b=u.value,B=b.clientWidth,R=b.clientHeight;if(l=new a.Scene,l.background=new a.Color(t.backgroundColor),v=new a.PerspectiveCamera(75,B/R,.1,1e3),v.position.set(t.cameraPosition.x,t.cameraPosition.y,t.cameraPosition.z),s=new a.WebGLRenderer({antialias:!0}),s.setSize(B,R),s.setPixelRatio(window.devicePixelRatio),b.appendChild(s.domElement),c=new p(v,s.domElement),c.autoRotate=t.autoRotate,c.autoRotateSpeed=t.autoRotateSpeed,t.showGrid){const k=new a.GridHelper(10,10,4473924,3355443);l.add(k)}if(t.showAxes){const k=new a.AxesHelper(5);l.add(k)}i=new ResizeObserver(()=>{if(!v||!s||!u.value)return;const k=u.value.clientWidth,V=u.value.clientHeight;v.aspect=k/V,v.updateProjectionMatrix(),s.setSize(k,V)}),i.observe(b),o(),y.value=!1,n("ready")}catch(p){const b=p instanceof Error?p:new Error(String(p));h.value=b,n("error",b),console.error("[PointCloudViewer] Failed to initialize:",p)}}function f(){if(!a||!l||(m&&(l.remove(m),m.geometry.dispose(),m.material.dispose(),m=null),t.points.length===0))return;const p=new a.BufferGeometry,b=new Float32Array(t.points.length*3),B=new Float32Array(t.points.length*3);for(let k=0;k<t.points.length;k++){const V=t.points[k];if(b[k*3]=V.x,b[k*3+1]=V.y,b[k*3+2]=V.z,t.usePointColors&&V.r!==void 0)B[k*3]=V.r,B[k*3+1]=V.g??0,B[k*3+2]=V.b??0;else{const x=new a.Color(t.pointColor);B[k*3]=x.r,B[k*3+1]=x.g,B[k*3+2]=x.b}}p.setAttribute("position",new a.BufferAttribute(b,3)),p.setAttribute("color",new a.BufferAttribute(B,3));const R=new a.PointsMaterial({size:t.pointSize,vertexColors:!0,sizeAttenuation:!0});if(m=new a.Points(p,R),l.add(m),t.bounds&&v){const k={x:(t.bounds.min.x+t.bounds.max.x)/2,y:(t.bounds.min.y+t.bounds.max.y)/2,z:(t.bounds.min.z+t.bounds.max.z)/2},V=Math.max(t.bounds.max.x-t.bounds.min.x,t.bounds.max.y-t.bounds.min.y,t.bounds.max.z-t.bounds.min.z);v.position.set(k.x+V*1.5,k.y+V*1.5,k.z+V*1.5),v.lookAt(k.x,k.y,k.z)}}function o(){_=requestAnimationFrame(o),c&&c.update(),s&&l&&v&&s.render(l,v)}function w(){_&&(cancelAnimationFrame(_),_=null),i&&(i.disconnect(),i=null),m&&l&&(l.remove(m),m.geometry.dispose(),m.material.dispose()),c&&c.dispose(),s&&(s.dispose(),u.value&&s.domElement.parentNode&&u.value.removeChild(s.domElement)),l=null,v=null,s=null,c=null,m=null}e.watch(()=>t.points,f,{deep:!0}),e.watch([()=>t.pointSize,()=>t.pointColor,()=>t.usePointColors],f),e.watch(()=>t.autoRotate,p=>{c&&(c.autoRotate=p)}),e.watch(()=>t.autoRotateSpeed,p=>{c&&(c.autoRotateSpeed=p)}),e.onMounted(()=>{r()}),e.onUnmounted(()=>{w()});const d=e.computed(()=>({pointCount:t.points.length,hasColors:t.points.length>0&&t.points[0].r!==void 0}));return C({updatePointCloud:f,stats:d}),(p,b)=>(e.openBlock(),e.createElementBlock("div",le,[e.createElementVNode("div",{ref_key:"containerRef",ref:u,class:"pointcloud-viewer__canvas"},null,512),y.value?(e.openBlock(),e.createElementBlock("div",ce,[...b[0]||(b[0]=[e.createElementVNode("div",{class:"pointcloud-viewer__spinner"},null,-1),e.createElementVNode("span",null,"Loading viewer...",-1)])])):e.createCommentVNode("",!0),h.value?(e.openBlock(),e.createElementBlock("div",ie,[e.createElementVNode("span",null,"⚠️ "+e.toDisplayString(h.value.message),1),b[1]||(b[1]=e.createElementVNode("small",null,"Make sure 'three' package is installed",-1))])):e.createCommentVNode("",!0),e.createElementVNode("div",ue,[e.createElementVNode("span",null,"Points: "+e.toDisplayString(d.value.pointCount.toLocaleString()),1),d.value.hasColors?(e.openBlock(),e.createElementBlock("span",de,"🎨 Colored")):e.createCommentVNode("",!0)])]))}}),pe=D(fe,[["__scopeId","data-v-68a99745"]]),me={class:"stream-viewer"},ve={class:"stream-viewer__header"},ye={class:"stream-viewer__stats"},_e={key:0,class:"stream-viewer__errors"},he={class:"stream-viewer__actions"},ge={key:0,class:"stream-viewer__timestamp"},we={class:"stream-viewer__data"},be={key:0,class:"stream-viewer__empty"},Ce=e.defineComponent({__name:"StreamViewer",props:{data:{},type:{default:"auto"},maxLines:{default:100},autoScroll:{type:Boolean,default:!0},showTimestamps:{type:Boolean,default:!0},paused:{type:Boolean,default:!1},formatter:{}},emits:["clear","pause"],setup(g,{expose:C,emit:S}){const t=g,n=S,u=e.ref([]),y=e.ref(null);let h=0;function a(r){if(t.formatter)return t.formatter(r);if(r==null)return String(r);switch(t.type==="auto"?l(r):t.type){case"json":try{return JSON.stringify(r,null,2)}catch{return String(r)}case"binary":return r instanceof ArrayBuffer?`Binary: ${new Uint8Array(r).length} bytes`:String(r);default:return String(r)}}function l(r){return r instanceof ArrayBuffer||r instanceof Uint8Array?"binary":typeof r=="object"?"json":"text"}function v(r,f="data"){if(t.paused)return;const o={id:h++,timestamp:new Date,data:a(r),type:f};u.value=[...u.value,o].slice(-t.maxLines),t.autoScroll&&s()}function s(){requestAnimationFrame(()=>{y.value&&(y.value.scrollTop=y.value.scrollHeight)})}function c(){u.value=[],n("clear")}function m(){n("pause",!t.paused)}function _(r){return r.toLocaleTimeString("en-US",{hour12:!1,hour:"2-digit",minute:"2-digit",second:"2-digit",fractionalSecondDigits:3})}e.watch(()=>t.data,r=>{r!==void 0&&v(r)});const i=e.computed(()=>({total:u.value.length,errors:u.value.filter(r=>r.type==="error").length}));return C({addLog:v,clear:c,logs:u,stats:i}),(r,f)=>(e.openBlock(),e.createElementBlock("div",me,[e.createElementVNode("div",ve,[e.createElementVNode("div",ye,[e.createElementVNode("span",null,"Lines: "+e.toDisplayString(i.value.total),1),i.value.errors>0?(e.openBlock(),e.createElementBlock("span",_e," Errors: "+e.toDisplayString(i.value.errors),1)):e.createCommentVNode("",!0)]),e.createElementVNode("div",he,[e.createElementVNode("button",{onClick:m,class:e.normalizeClass(["stream-viewer__btn",{"stream-viewer__btn--active":r.paused}])},e.toDisplayString(r.paused?"▶ Resume":"⏸ Pause"),3),e.createElementVNode("button",{onClick:c,class:"stream-viewer__btn"},"🗑 Clear")])]),e.createElementVNode("div",{ref_key:"containerRef",ref:y,class:"stream-viewer__content"},[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(u.value,o=>(e.openBlock(),e.createElementBlock("div",{key:o.id,class:e.normalizeClass(["stream-viewer__entry",`stream-viewer__entry--${o.type}`])},[r.showTimestamps?(e.openBlock(),e.createElementBlock("span",ge,e.toDisplayString(_(o.timestamp)),1)):e.createCommentVNode("",!0),e.createElementVNode("pre",we,e.toDisplayString(o.data),1)],2))),128)),u.value.length===0?(e.openBlock(),e.createElementBlock("div",be," Waiting for data... ")):e.createCommentVNode("",!0)],512)]))}}),Se=D(Ce,[["__scopeId","data-v-06dc8d20"]]),ke={class:"unified-player"},Ee=["autoplay","controls","muted"],Be={key:0,class:"unified-player__loading"},Re={key:1,class:"unified-player__error"},Ve=e.defineComponent({__name:"UnifiedPlayer",props:{type:{},config:{},autoOpen:{type:Boolean,default:!0},autoplay:{type:Boolean,default:!0},controls:{type:Boolean,default:!0},muted:{type:Boolean,default:!1},lowLatency:{type:Boolean,default:!1}},emits:["open","close","error","status"],setup(g,{expose:C,emit:S}){const t=g,n=S,u=e.ref(null),y=e.ref(!1),h=e.ref(null),a=e.ref("idle");let l=null,v=null,s=null,c=null;const m=e.computed(()=>({width:"100%",height:"100%",objectFit:"contain"}));async function _(d){if(!u.value)throw new Error("Video element not available");a.value="connecting",n("status","connecting");try{i(),l=new RTCPeerConnection({iceServers:[{urls:"stun:stun.l.google.com:19302"}]}),l.ontrack=R=>{u.value&&R.streams[0]&&(u.value.srcObject=R.streams[0],v=R.streams[0],a.value="connected",n("status","connected"),n("open"))},l.onconnectionstatechange=()=>{const R=l==null?void 0:l.connectionState;R==="failed"||R==="disconnected"?(a.value=R,n("status",R),setTimeout(()=>_(d),2e3)):R==="connected"&&(a.value="connected",n("status","connected"))};const p=await l.createOffer({offerToReceiveVideo:!0,offerToReceiveAudio:!0});await l.setLocalDescription(p),s=new AbortController;const b=await fetch(d,{method:"POST",headers:{"Content-Type":"application/sdp"},body:p.sdp,signal:s.signal});if(!b.ok)throw new Error(`WHEP request failed: ${b.status}`);const B=await b.text();await l.setRemoteDescription({type:"answer",sdp:B}),y.value=!1}catch(p){const b=p instanceof Error?p:new Error(String(p));h.value=b,a.value="error",n("error",b),n("status","error"),y.value=!1}}function i(){s&&(s.abort(),s=null),v&&(v.getTracks().forEach(d=>d.stop()),v=null),l&&(l.close(),l=null),u.value&&(u.value.srcObject=null)}async function r(d){if(!u.value)throw new Error("Video element not available");a.value="connecting",n("status","connecting");try{const p={url:d,autoPlay:t.autoplay,lowLatencyMode:t.lowLatency},b={onManifestLoaded:()=>{a.value="connected",n("status","connected"),n("open"),y.value=!1},onError:B=>{h.value=B,a.value="error",n("error",B),n("status","error"),y.value=!1}};c=P.useHLS(p,b),await c.attach(u.value)}catch(p){const b=p instanceof Error?p:new Error(String(p));h.value=b,a.value="error",n("error",b),n("status","error"),y.value=!1}}function f(){c&&(c.destroy(),c=null)}async function o(){var d;if(!((d=t.config)!=null&&d.url)){const p=new Error("Stream URL is required");h.value=p,n("error",p);return}y.value=!0,h.value=null,t.type==="webrtc"?await _(t.config.url):await r(t.config.url)}function w(){t.type==="webrtc"?i():f(),a.value="idle",n("status","idle"),n("close")}return e.watch(()=>{var d;return[t.type,(d=t.config)==null?void 0:d.url]},()=>{t.autoOpen&&(w(),o())}),e.onMounted(()=>{var d;t.autoOpen&&((d=t.config)!=null&&d.url)&&o()}),e.onUnmounted(()=>{w()}),C({open:o,close:w,status:a,error:h,videoRef:u}),(d,p)=>(e.openBlock(),e.createElementBlock("div",ke,[e.createElementVNode("video",{ref_key:"videoRef",ref:u,style:e.normalizeStyle(m.value),autoplay:d.autoplay,controls:d.controls,muted:d.muted,playsinline:""},null,12,Ee),y.value?(e.openBlock(),e.createElementBlock("div",Be,[...p[0]||(p[0]=[e.createElementVNode("div",{class:"unified-player__spinner"},null,-1)])])):e.createCommentVNode("",!0),h.value?(e.openBlock(),e.createElementBlock("div",Re,[e.createElementVNode("span",null,"⚠️ "+e.toDisplayString(h.value.message),1)])):e.createCommentVNode("",!0)]))}}),Ne=D(Ve,[["__scopeId","data-v-19bf6a4d"]]),Pe={class:"webrtc-viewer"},$e={key:0,class:"webrtc-viewer__header"},xe={class:"webrtc-viewer__status"},De={class:"webrtc-viewer__controls"},Le={class:"webrtc-viewer__content"},Ae={class:"webrtc-viewer__default"},Te={key:0,class:"webrtc-viewer__placeholder"},Fe={key:1,class:"webrtc-viewer__loading"},ze={key:2,class:"webrtc-viewer__error"},Me={key:3,class:"webrtc-viewer__info"},He={key:0},Oe={key:1},Ie={key:1,class:"webrtc-viewer__footer"},Ue={key:0},je={key:1},We=e.defineComponent({__name:"WebRTCViewer",props:{signalingUrl:{},iceServers:{default:()=>[{urls:"stun:stun.l.google.com:19302"}]},enablePointCloud:{type:Boolean,default:!0},enableDetections:{type:Boolean,default:!0},autoConnect:{type:Boolean,default:!0},autoReconnect:{type:Boolean,default:!0},maxReconnectAttempts:{default:5},showStatus:{type:Boolean,default:!0},showStats:{type:Boolean,default:!0}},emits:["connected","disconnected","error","pointcloud","detections","boundingboxes","status"],setup(g,{expose:C,emit:S}){const t=g,n=S,u=e.ref("Idle"),y={signalingUrl:t.signalingUrl,iceServers:t.iceServers,enablePointCloud:t.enablePointCloud,enableDetections:t.enableDetections,autoReconnect:t.autoReconnect,maxReconnectAttempts:t.maxReconnectAttempts},h={onStatus:d=>{u.value=d,n("status",d)},onConnectionState:d=>{d==="connected"?n("connected"):(d==="disconnected"||d==="closed"||d==="failed")&&n("disconnected")},onPointCloudFrame:d=>{n("pointcloud",d)},onDetectionFrame:d=>{n("detections",d)},onBoundingBoxData:d=>{n("boundingboxes",d)},onError:d=>{n("error",d)}},{isRunning:a,connectionState:l,dataChannels:v,lastPointCloudFrame:s,lastDetectionFrame:c,lastBoundingBoxes:m,error:_,start:i,stop:r,sendControl:f}=P.useWebRTC(y,h),o=e.computed(()=>{var d,p;return{channels:v.value.size,pointCount:((d=s.value)==null?void 0:d.points.length)??0,detectionCount:((p=c.value)==null?void 0:p.detections.length)??0,bboxCount:m.value.length}}),w=e.computed(()=>{switch(l.value){case"connected":return"#4caf50";case"connecting":return"#ff9800";case"reconnecting":return"#ff9800";case"error":return"#f44336";default:return"#9e9e9e"}});return e.onMounted(()=>{t.autoConnect&&i()}),e.watch(()=>t.signalingUrl,()=>{a.value&&(r(),y.signalingUrl=t.signalingUrl,i())}),C({isRunning:a,connectionState:l,start:i,stop:r,sendControl:f,lastPointCloudFrame:s,lastDetectionFrame:c,lastBoundingBoxes:m,stats:o}),(d,p)=>(e.openBlock(),e.createElementBlock("div",Pe,[d.showStatus?(e.openBlock(),e.createElementBlock("div",$e,[e.createElementVNode("div",xe,[e.createElementVNode("span",{class:"webrtc-viewer__indicator",style:e.normalizeStyle({backgroundColor:w.value})},null,4),e.createElementVNode("span",null,e.toDisplayString(e.unref(l)),1)]),e.createElementVNode("div",De,[e.unref(a)?(e.openBlock(),e.createElementBlock("button",{key:1,onClick:p[1]||(p[1]=(...b)=>e.unref(r)&&e.unref(r)(...b)),class:"webrtc-viewer__btn webrtc-viewer__btn--disconnect"}," ⏹ Disconnect ")):(e.openBlock(),e.createElementBlock("button",{key:0,onClick:p[0]||(p[0]=(...b)=>e.unref(i)&&e.unref(i)(...b)),class:"webrtc-viewer__btn webrtc-viewer__btn--connect"}," ▶ Connect "))])])):e.createCommentVNode("",!0),e.createElementVNode("div",Le,[e.renderSlot(d.$slots,"default",{isRunning:e.unref(a),connectionState:e.unref(l),pointCloudFrame:e.unref(s),detectionFrame:e.unref(c),boundingBoxes:e.unref(m),error:e.unref(_),start:e.unref(i),stop:e.unref(r),sendControl:e.unref(f)},()=>[e.createElementVNode("div",Ae,[e.unref(a)?e.unref(l)==="connecting"?(e.openBlock(),e.createElementBlock("div",Fe,[p[3]||(p[3]=e.createElementVNode("div",{class:"webrtc-viewer__spinner"},null,-1)),e.createElementVNode("span",null,e.toDisplayString(u.value),1)])):e.unref(_)?(e.openBlock(),e.createElementBlock("div",ze,[e.createElementVNode("span",null,"⚠️ "+e.toDisplayString(e.unref(_).message),1)])):(e.openBlock(),e.createElementBlock("div",Me,[p[4]||(p[4]=e.createElementVNode("p",null,"WebRTC Connected",-1)),o.value.pointCount>0?(e.openBlock(),e.createElementBlock("p",He," Points: "+e.toDisplayString(o.value.pointCount.toLocaleString()),1)):e.createCommentVNode("",!0),o.value.bboxCount>0?(e.openBlock(),e.createElementBlock("p",Oe," Bounding Boxes: "+e.toDisplayString(o.value.bboxCount),1)):e.createCommentVNode("",!0)])):(e.openBlock(),e.createElementBlock("div",Te,[...p[2]||(p[2]=[e.createElementVNode("span",null,"Click Connect to start WebRTC stream",-1)])]))])],!0)]),d.showStats&&e.unref(a)?(e.openBlock(),e.createElementBlock("div",Ie,[e.createElementVNode("span",null,"Channels: "+e.toDisplayString(o.value.channels),1),t.enablePointCloud?(e.openBlock(),e.createElementBlock("span",Ue," Points: "+e.toDisplayString(o.value.pointCount.toLocaleString()),1)):e.createCommentVNode("",!0),t.enableDetections?(e.openBlock(),e.createElementBlock("span",je," Detections: "+e.toDisplayString(o.value.detectionCount),1)):e.createCommentVNode("",!0)])):e.createCommentVNode("",!0)]))}}),qe=D(We,[["__scopeId","data-v-3f83a728"]]),Ge=e.defineComponent({__name:"DataStreamView",props:{config:{default:()=>({})},autoStart:{type:Boolean,default:!0}},emits:["data","batch","error"],setup(g,{expose:C,emit:S}){const t=g,n=S,{config:u}=e.toRefs(t),{data:y,buffer:h,bufferSize:a,isStreaming:l,itemsPerSecond:v,totalItems:s,error:c,start:m,stop:_,push:i,clear:r,getBuffer:f,subscribe:o}=P.useDataStream(t.config,{onData:w=>n("data",w),onBatch:w=>n("batch",w),onError:w=>n("error",w)});return e.onMounted(()=>{t.autoStart&&m()}),e.watch(u,()=>{_(),m()},{deep:!0}),C({data:y,buffer:h,bufferSize:a,isStreaming:l,itemsPerSecond:v,totalItems:s,error:c,start:m,stop:_,push:i,clear:r,getBuffer:f,subscribe:o}),(w,d)=>e.renderSlot(w.$slots,"default",{data:e.unref(y),buffer:e.unref(h),bufferSize:e.unref(a),isStreaming:e.unref(l),itemsPerSecond:e.unref(v),totalItems:e.unref(s),error:e.unref(c),start:e.unref(m),stop:e.unref(_),push:e.unref(i),clear:e.unref(r)})}}),Je=e.defineComponent({__name:"HTTPStream",props:{url:{},method:{default:"GET"},headers:{default:()=>({})},body:{default:void 0},credentials:{default:"same-origin"},autoConnect:{type:Boolean,default:!0},autoReconnect:{type:Boolean,default:!0},maxReconnectAttempts:{default:5},reconnectDelay:{default:1e3},ndjson:{type:Boolean,default:!0}},emits:["open","chunk","complete","error","progress","reconnecting","reconnected","reconnectFailed"],setup(g,{expose:C,emit:S}){const t=g,n=S,{url:u}=e.toRefs(t),{isConnected:y,isStreaming:h,connectionState:a,lastChunk:l,chunks:v,bytesReceived:s,error:c,reconnectAttempts:m,connect:_,disconnect:i,clearChunks:r}=P.useHTTPStream({url:t.url,method:t.method,headers:t.headers,body:t.body,credentials:t.credentials,autoConnect:t.autoConnect,autoReconnect:t.autoReconnect,maxReconnectAttempts:t.maxReconnectAttempts,reconnectDelay:t.reconnectDelay,ndjson:t.ndjson},{onOpen:()=>n("open"),onChunk:(f,o)=>n("chunk",f,o),onComplete:()=>n("complete"),onError:f=>n("error",f),onProgress:f=>n("progress",f),onReconnecting:(f,o)=>n("reconnecting",f,o),onReconnected:()=>n("reconnected"),onReconnectFailed:()=>n("reconnectFailed")});return e.watch(u,()=>{i(),_()}),C({isConnected:y,isStreaming:h,connectionState:a,lastChunk:l,chunks:v,bytesReceived:s,error:c,reconnectAttempts:m,connect:_,disconnect:i,clearChunks:r}),(f,o)=>e.renderSlot(f.$slots,"default",{isConnected:e.unref(y),isStreaming:e.unref(h),connectionState:e.unref(a),lastChunk:e.unref(l),chunks:e.unref(v),bytesReceived:e.unref(s),error:e.unref(c),reconnectAttempts:e.unref(m),connect:e.unref(_),disconnect:e.unref(i),clearChunks:e.unref(r)})}}),Qe=e.defineComponent({__name:"LaravelEchoStream",props:{config:{default:()=>({})},echo:{default:void 0},channel:{default:void 0},channelType:{default:"public"},events:{default:()=>[]},autoSubscribe:{type:Boolean,default:!0}},emits:["connected","event","error","subscribed","unsubscribed","here","joining","leaving"],setup(g,{expose:C,emit:S}){const t=g,n=S,{channel:u}=e.toRefs(t),{isConnected:y,connectionState:h,error:a,channels:l,channel:v,privateChannel:s,presenceChannel:c,leave:m,leaveAll:_,connect:i}=P.useLaravelEcho(t.config??{},{onConnected:o=>n("connected",o),onError:o=>n("error",o)},t.echo);let r=null;function f(){if(t.channel){if(t.channelType==="private")r=s(t.channel);else if(t.channelType==="presence"){const o=c(t.channel);r=o,o.here(w=>n("here",w)),o.joining(w=>n("joining",w)),o.leaving(w=>n("leaving",w))}else r=v(t.channel);t.events.forEach(o=>{r==null||r.listen(o,w=>{n("event",o,w)})}),n("subscribed",t.channel)}}return e.onMounted(async()=>{await i(),t.autoSubscribe&&t.channel&&y.value&&f()}),e.watch(u,(o,w)=>{w&&(m(w),n("unsubscribed",w)),o&&t.autoSubscribe&&f()}),C({isConnected:y,connectionState:h,error:a,channels:l,subscribePublic:v,privateChannel:s,presenceChannel:c,leave:m,leaveAll:_,connect:i}),(o,w)=>e.renderSlot(o.$slots,"default",{isConnected:e.unref(y),connectionState:e.unref(h),error:e.unref(a),channels:e.unref(l),activeChannels:e.unref(l).length,subscribePublic:e.unref(v),privateChannel:e.unref(s),presenceChannel:e.unref(c),leave:e.unref(m),leaveAll:e.unref(_)})}}),Ke=e.defineComponent({__name:"LongPollingStream",props:{url:{},method:{default:"GET"},headers:{default:()=>({})},body:{default:void 0},credentials:{default:"same-origin"},interval:{default:0},timeout:{default:3e4},autoStart:{type:Boolean,default:!0},autoRestart:{type:Boolean,default:!0},maxRestartAttempts:{default:5},restartDelay:{default:1e3},includeTimestamp:{type:Boolean,default:!1},timestampParam:{default:"since"}},emits:["start","data","error","stop","restarting","restarted","restartFailed"],setup(g,{expose:C,emit:S}){const t=g,n=S,{url:u}=e.toRefs(t),{isPolling:y,connectionState:h,lastData:a,dataHistory:l,requestCount:v,error:s,restartAttempts:c,start:m,stop:_,poll:i,clearHistory:r}=P.useLongPolling({url:t.url,method:t.method,headers:t.headers,body:t.body,credentials:t.credentials,interval:t.interval,timeout:t.timeout,autoStart:t.autoStart,autoRestart:t.autoRestart,maxRestartAttempts:t.maxRestartAttempts,restartDelay:t.restartDelay,includeTimestamp:t.includeTimestamp,timestampParam:t.timestampParam},{onStart:()=>n("start"),onData:f=>n("data",f),onError:f=>n("error",f),onStop:()=>n("stop"),onRestarting:(f,o)=>n("restarting",f,o),onRestarted:()=>n("restarted"),onRestartFailed:()=>n("restartFailed")});return e.watch(u,()=>{_(),m()}),C({isPolling:y,connectionState:h,lastData:a,dataHistory:l,requestCount:v,error:s,restartAttempts:c,start:m,stop:_,poll:i,clearHistory:r}),(f,o)=>e.renderSlot(f.$slots,"default",{isPolling:e.unref(y),connectionState:e.unref(h),lastData:e.unref(a),dataHistory:e.unref(l),requestCount:e.unref(v),error:e.unref(s),restartAttempts:e.unref(c),start:e.unref(m),stop:e.unref(_),poll:e.unref(i),clearHistory:e.unref(r)})}}),Xe=e.defineComponent({__name:"SocketIOStream",props:{config:{},autoConnect:{type:Boolean,default:!0},events:{default:()=>[]}},emits:["connect","disconnect","error","event","reconnecting","reconnected","reconnectFailed"],setup(g,{expose:C,emit:S}){const t=g,n=S,{config:u}=e.toRefs(t),{isConnected:y,connectionState:h,socketId:a,rooms:l,error:v,connect:s,disconnect:c,emit:m,on:_,off:i,join:r,leave:f}=P.useSocketIO(t.config,{onConnect:o=>n("connect",o),onDisconnect:o=>n("disconnect",o),onError:o=>n("error",o),onReconnecting:o=>n("reconnecting",o),onReconnectFailed:()=>n("reconnectFailed")});return e.onMounted(async()=>{t.autoConnect&&await s(),t.events.forEach(o=>{_(o,w=>{n("event",o,w)})})}),e.watch(()=>u.value.url,()=>{c(),s()}),C({isConnected:y,connectionState:h,socketId:a,rooms:l,error:v,connect:s,disconnect:c,emit:m,on:_,off:i,join:r,leave:f}),(o,w)=>e.renderSlot(o.$slots,"default",{isConnected:e.unref(y),connectionState:e.unref(h),socketId:e.unref(a),rooms:e.unref(l),error:e.unref(v),connect:e.unref(s),disconnect:e.unref(c),emit:e.unref(m),on:e.unref(_),off:e.unref(i),join:e.unref(r),leave:e.unref(f)})}}),Ye=e.defineComponent({__name:"SSEStream",props:{url:{},withCredentials:{type:Boolean,default:!1},autoConnect:{type:Boolean,default:!0},autoReconnect:{type:Boolean,default:!0},maxReconnectAttempts:{default:5},reconnectDelay:{default:1e3},eventTypes:{default:()=>["message"]}},emits:["open","error","message","event","reconnecting","reconnected","reconnectFailed"],setup(g,{expose:C,emit:S}){const t=g,n=S,{url:u}=e.toRefs(t),{isConnected:y,connectionState:h,lastMessage:a,lastEventType:l,lastEventId:v,error:s,reconnectAttempts:c,connect:m,disconnect:_,addEventListener:i,removeEventListener:r}=P.useSSE({url:t.url,withCredentials:t.withCredentials,autoConnect:t.autoConnect,autoReconnect:t.autoReconnect,maxReconnectAttempts:t.maxReconnectAttempts,reconnectDelay:t.reconnectDelay,eventTypes:t.eventTypes},{onOpen:()=>n("open"),onError:f=>n("error",f),onMessage:(f,o)=>n("message",f,o),onEvent:(f,o,w)=>n("event",f,o,w),onReconnecting:(f,o)=>n("reconnecting",f,o),onReconnected:()=>n("reconnected"),onReconnectFailed:()=>n("reconnectFailed")});return e.watch(u,()=>{_(),m()}),C({isConnected:y,connectionState:h,lastMessage:a,lastEventType:l,lastEventId:v,error:s,reconnectAttempts:c,connect:m,disconnect:_,addEventListener:i,removeEventListener:r}),(f,o)=>e.renderSlot(f.$slots,"default",{isConnected:e.unref(y),connectionState:e.unref(h),lastMessage:e.unref(a),lastEventType:e.unref(l),lastEventId:e.unref(v),error:e.unref(s),reconnectAttempts:e.unref(c),connect:e.unref(m),disconnect:e.unref(_),addEventListener:e.unref(i),removeEventListener:e.unref(r)})}}),Ze=e.defineComponent({__name:"WebSocketStream",props:{config:{},autoConnect:{type:Boolean,default:!0}},emits:["open","close","error","message","reconnecting","reconnected","reconnectFailed"],setup(g,{expose:C,emit:S}){const t=g,n=S,{config:u}=e.toRefs(t),{isConnected:y,connectionState:h,lastMessage:a,error:l,reconnectAttempts:v,connect:s,disconnect:c,send:m,sendJSON:_}=P.useWebSocket(t.config,{onOpen:()=>n("open"),onClose:(i,r)=>n("close",i,r),onError:i=>n("error",i),onMessage:(i,r)=>n("message",i,r),onReconnecting:(i,r)=>n("reconnecting",i,r),onReconnected:()=>n("reconnected"),onReconnectFailed:()=>n("reconnectFailed")});return e.watch(()=>u.value.url,()=>{c(),s()}),C({isConnected:y,connectionState:h,lastMessage:a,error:l,reconnectAttempts:v,connect:s,disconnect:c,send:m,sendJSON:_}),(i,r)=>e.renderSlot(i.$slots,"default",{isConnected:e.unref(y),connectionState:e.unref(h),lastMessage:e.unref(a),error:e.unref(l),reconnectAttempts:e.unref(v),connect:e.unref(s),disconnect:e.unref(c),send:e.unref(m),sendJson:e.unref(_)})}});exports.HLSPlayer=se;exports.PointCloudViewer=pe;exports.StreamViewer=Se;exports.UnifiedPlayer=Ne;exports.WebRTCViewer=qe;exports._sfc_main=Ge;exports._sfc_main$1=Je;exports._sfc_main$2=Qe;exports._sfc_main$3=Ke;exports._sfc_main$4=Ye;exports._sfc_main$5=Xe;exports._sfc_main$6=Ze;
|
|
2
|
+
//# sourceMappingURL=WebSocketStream.vue_vue_type_script_setup_true_lang-D5IiGqMS.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WebSocketStream.vue_vue_type_script_setup_true_lang-D5IiGqMS.cjs","sources":["../src/components/HLSPlayer.vue","../src/components/PointCloudViewer.vue","../src/components/StreamViewer.vue","../src/components/UnifiedPlayer.vue","../src/components/WebRTCViewer.vue","../src/components/DataStreamView.vue","../src/components/HTTPStream.vue","../src/components/LaravelEchoStream.vue","../src/components/LongPollingStream.vue","../src/components/SocketIOStream.vue","../src/components/SSEStream.vue","../src/components/WebSocketStream.vue"],"sourcesContent":["<script setup lang=\"ts\">\r\n/**\r\n * HLSPlayer - HLS video player component\r\n * Wrapper for useHLS composable with video controls\r\n */\r\nimport { computed, onMounted, ref, watch } from \"vue\";\r\nimport { useHLS, type HLSState } from \"../composables/useHLS\";\r\nimport type { HLSCallbacks, HLSConfig, HLSLevel } from \"../types\";\r\n\r\ninterface Props {\r\n /** HLS stream URL */\r\n src: string;\r\n /** Auto-play video */\r\n autoPlay?: boolean;\r\n /** Show native controls */\r\n controls?: boolean;\r\n /** Muted */\r\n muted?: boolean;\r\n /** Loop */\r\n loop?: boolean;\r\n /** Poster image */\r\n poster?: string;\r\n /** Low latency mode */\r\n lowLatency?: boolean;\r\n /** Start level (-1 for auto) */\r\n startLevel?: number;\r\n /** CSS class for video element */\r\n videoClass?: string;\r\n}\r\n\r\nconst props = withDefaults(defineProps<Props>(), {\r\n autoPlay: true,\r\n controls: true,\r\n muted: false,\r\n loop: false,\r\n lowLatency: false,\r\n startLevel: -1,\r\n});\r\n\r\nconst emit = defineEmits<{\r\n (e: \"ready\"): void;\r\n (e: \"play\"): void;\r\n (e: \"pause\"): void;\r\n (e: \"ended\"): void;\r\n (e: \"error\", error: Error): void;\r\n (e: \"levelChange\", level: number): void;\r\n (e: \"timeUpdate\", time: number): void;\r\n (e: \"stateChange\", state: HLSState): void;\r\n}>();\r\n\r\nconst videoRef = ref<HTMLVideoElement | null>(null);\r\n\r\nconst hlsConfig: HLSConfig = {\r\n url: props.src,\r\n autoPlay: props.autoPlay,\r\n lowLatencyMode: props.lowLatency,\r\n startLevel: props.startLevel,\r\n};\r\n\r\nconst hlsCallbacks: HLSCallbacks = {\r\n onManifestLoaded: (levels) => {\r\n emit(\"ready\");\r\n },\r\n onLevelSwitched: (level) => {\r\n emit(\"levelChange\", level);\r\n },\r\n onPlaybackStarted: () => {\r\n emit(\"play\");\r\n },\r\n onPlaybackEnded: () => {\r\n emit(\"ended\");\r\n },\r\n onError: (error) => {\r\n emit(\"error\", error);\r\n },\r\n};\r\n\r\nconst {\r\n state,\r\n isPlaying,\r\n isBuffering,\r\n levels,\r\n currentLevel,\r\n autoLevelEnabled,\r\n currentTime,\r\n duration,\r\n buffered,\r\n volume,\r\n muted: isMuted,\r\n stats,\r\n error,\r\n isSupported,\r\n attach,\r\n play,\r\n pause,\r\n stop,\r\n seek,\r\n setLevel,\r\n setVolume,\r\n toggleMute,\r\n destroy,\r\n} = useHLS(hlsConfig, hlsCallbacks);\r\n\r\n// Watch state changes\r\nwatch(state, (newState) => {\r\n emit(\"stateChange\", newState);\r\n});\r\n\r\nwatch(currentTime, (time) => {\r\n emit(\"timeUpdate\", time);\r\n});\r\n\r\n// Format time\r\nfunction formatTime(seconds: number): string {\r\n if (!isFinite(seconds)) return \"0:00\";\r\n const mins = Math.floor(seconds / 60);\r\n const secs = Math.floor(seconds % 60);\r\n return `${mins}:${secs.toString().padStart(2, \"0\")}`;\r\n}\r\n\r\n// Current level info\r\nconst currentLevelInfo = computed<HLSLevel | null>(() => {\r\n if (currentLevel.value < 0 || currentLevel.value >= levels.value.length) {\r\n return null;\r\n }\r\n return levels.value[currentLevel.value];\r\n});\r\n\r\n// Initialize on mount\r\nonMounted(async () => {\r\n if (videoRef.value) {\r\n try {\r\n await attach(videoRef.value);\r\n } catch (err) {\r\n console.error(\"[HLSPlayer] Failed to attach:\", err);\r\n }\r\n }\r\n});\r\n\r\n// Watch for src changes\r\nwatch(\r\n () => props.src,\r\n async (newSrc) => {\r\n if (videoRef.value && newSrc) {\r\n destroy();\r\n load(newSrc);\r\n await attach(videoRef.value);\r\n }\r\n },\r\n);\r\n\r\ndefineExpose({\r\n play,\r\n pause,\r\n stop,\r\n seek,\r\n setLevel,\r\n setVolume,\r\n toggleMute,\r\n state,\r\n levels,\r\n currentLevel,\r\n stats,\r\n});\r\n</script>\r\n\r\n<template>\r\n <div class=\"hls-player\">\r\n <div class=\"hls-player__video-container\">\r\n <video\r\n ref=\"videoRef\"\r\n :class=\"['hls-player__video', videoClass]\"\r\n :controls=\"controls\"\r\n :muted=\"muted\"\r\n :loop=\"loop\"\r\n :poster=\"poster\"\r\n playsinline\r\n />\r\n\r\n <!-- Loading overlay -->\r\n <div v-if=\"isBuffering\" class=\"hls-player__overlay\">\r\n <div class=\"hls-player__spinner\" />\r\n </div>\r\n\r\n <!-- Error overlay -->\r\n <div v-if=\"error\" class=\"hls-player__overlay hls-player__overlay--error\">\r\n <div class=\"hls-player__error\">\r\n <span>⚠️ {{ error.message }}</span>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Quality selector -->\r\n <div v-if=\"levels.length > 1\" class=\"hls-player__controls\">\r\n <div class=\"hls-player__quality\">\r\n <label>Quality:</label>\r\n <select\r\n :value=\"currentLevel\"\r\n @change=\"setLevel(Number(($event.target as HTMLSelectElement).value))\"\r\n >\r\n <option :value=\"-1\">Auto</option>\r\n <option\r\n v-for=\"level in levels\"\r\n :key=\"level.index\"\r\n :value=\"level.index\"\r\n >\r\n {{ level.height }}p ({{ Math.round(level.bitrate / 1000) }}kbps)\r\n </option>\r\n </select>\r\n </div>\r\n\r\n <div class=\"hls-player__stats\">\r\n <span v-if=\"currentLevelInfo\">\r\n {{ currentLevelInfo.width }}x{{ currentLevelInfo.height }}\r\n </span>\r\n <span\r\n >{{ Math.round((stats.bandwidth / 1000000) * 10) / 10 }} Mbps</span\r\n >\r\n <span>{{ formatTime(currentTime) }} / {{ formatTime(duration) }}</span>\r\n </div>\r\n </div>\r\n </div>\r\n</template>\r\n\r\n<style scoped>\r\n.hls-player {\r\n display: flex;\r\n flex-direction: column;\r\n background: #000;\r\n border-radius: 4px;\r\n overflow: hidden;\r\n}\r\n\r\n.hls-player__video-container {\r\n position: relative;\r\n width: 100%;\r\n aspect-ratio: 16 / 9;\r\n}\r\n\r\n.hls-player__video {\r\n width: 100%;\r\n height: 100%;\r\n object-fit: contain;\r\n}\r\n\r\n.hls-player__overlay {\r\n position: absolute;\r\n top: 0;\r\n left: 0;\r\n right: 0;\r\n bottom: 0;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n background: rgba(0, 0, 0, 0.5);\r\n}\r\n\r\n.hls-player__overlay--error {\r\n background: rgba(0, 0, 0, 0.8);\r\n}\r\n\r\n.hls-player__spinner {\r\n width: 48px;\r\n height: 48px;\r\n border: 3px solid rgba(255, 255, 255, 0.3);\r\n border-top-color: #fff;\r\n border-radius: 50%;\r\n animation: spin 1s linear infinite;\r\n}\r\n\r\n@keyframes spin {\r\n to {\r\n transform: rotate(360deg);\r\n }\r\n}\r\n\r\n.hls-player__error {\r\n color: #f48771;\r\n text-align: center;\r\n padding: 16px;\r\n}\r\n\r\n.hls-player__controls {\r\n display: flex;\r\n justify-content: space-between;\r\n align-items: center;\r\n padding: 8px 12px;\r\n background: #1e1e1e;\r\n color: #ccc;\r\n font-size: 12px;\r\n}\r\n\r\n.hls-player__quality {\r\n display: flex;\r\n align-items: center;\r\n gap: 8px;\r\n}\r\n\r\n.hls-player__quality select {\r\n padding: 4px 8px;\r\n background: #3c3c3c;\r\n border: none;\r\n border-radius: 3px;\r\n color: #ccc;\r\n cursor: pointer;\r\n}\r\n\r\n.hls-player__stats {\r\n display: flex;\r\n gap: 16px;\r\n color: #858585;\r\n}\r\n</style>\r\n","<script setup lang=\"ts\">\r\n/**\r\n * PointCloudViewer - 3D Point Cloud visualization component\r\n * Uses Three.js for rendering (requires three as peer dependency)\r\n */\r\nimport { computed, onMounted, onUnmounted, ref, watch } from \"vue\";\r\nimport type { DecodedPointCloud, Point3D } from \"../types\";\r\n\r\ninterface Props {\r\n /** Point cloud data */\r\n points: Point3D[];\r\n /** Point size */\r\n pointSize?: number;\r\n /** Default point color (hex) */\r\n pointColor?: number;\r\n /** Use point colors if available */\r\n usePointColors?: boolean;\r\n /** Camera position */\r\n cameraPosition?: { x: number; y: number; z: number };\r\n /** Auto-rotate */\r\n autoRotate?: boolean;\r\n /** Auto-rotate speed */\r\n autoRotateSpeed?: number;\r\n /** Background color */\r\n backgroundColor?: number;\r\n /** Show axes helper */\r\n showAxes?: boolean;\r\n /** Show grid */\r\n showGrid?: boolean;\r\n /** Bounds for camera auto-fit */\r\n bounds?: DecodedPointCloud[\"bounds\"];\r\n}\r\n\r\nconst props = withDefaults(defineProps<Props>(), {\r\n pointSize: 0.02,\r\n pointColor: 0x00ff00,\r\n usePointColors: true,\r\n cameraPosition: () => ({ x: 5, y: 5, z: 5 }),\r\n autoRotate: false,\r\n autoRotateSpeed: 1,\r\n backgroundColor: 0x1e1e1e,\r\n showAxes: false,\r\n showGrid: true,\r\n});\r\n\r\nconst emit = defineEmits<{\r\n (e: \"ready\"): void;\r\n (e: \"click\", point: Point3D | null, index: number): void;\r\n (e: \"error\", error: Error): void;\r\n}>();\r\n\r\nconst containerRef = ref<HTMLElement | null>(null);\r\nconst isLoading = ref(true);\r\nconst error = ref<Error | null>(null);\r\n\r\n// Three.js objects (loaded dynamically)\r\nlet THREE: typeof import(\"three\") | null = null;\r\nlet scene: InstanceType<typeof import(\"three\").Scene> | null = null;\r\nlet camera: InstanceType<typeof import(\"three\").PerspectiveCamera> | null =\r\n null;\r\nlet renderer: InstanceType<typeof import(\"three\").WebGLRenderer> | null = null;\r\nlet controls: {\r\n update: () => void;\r\n autoRotate: boolean;\r\n autoRotateSpeed: number;\r\n dispose: () => void;\r\n} | null = null;\r\nlet pointsObject: InstanceType<typeof import(\"three\").Points> | null = null;\r\nlet animationId: number | null = null;\r\nlet resizeObserverInstance: ResizeObserver | null = null;\r\n\r\n/**\r\n * Initialize Three.js scene\r\n */\r\nasync function initScene(): Promise<void> {\r\n if (!containerRef.value) return;\r\n\r\n try {\r\n // Dynamic import Three.js\r\n THREE = await import(\"three\");\r\n const { OrbitControls } =\r\n await import(\"three/examples/jsm/controls/OrbitControls.js\");\r\n\r\n const container = containerRef.value;\r\n const width = container.clientWidth;\r\n const height = container.clientHeight;\r\n\r\n // Scene\r\n scene = new THREE.Scene();\r\n scene.background = new THREE.Color(props.backgroundColor);\r\n\r\n // Camera\r\n camera = new THREE.PerspectiveCamera(75, width / height, 0.1, 1000);\r\n camera.position.set(\r\n props.cameraPosition.x,\r\n props.cameraPosition.y,\r\n props.cameraPosition.z,\r\n );\r\n\r\n // Renderer\r\n renderer = new THREE.WebGLRenderer({ antialias: true });\r\n renderer.setSize(width, height);\r\n renderer.setPixelRatio(window.devicePixelRatio);\r\n container.appendChild(renderer.domElement);\r\n\r\n // Controls\r\n controls = new OrbitControls(camera, renderer.domElement);\r\n controls.autoRotate = props.autoRotate;\r\n controls.autoRotateSpeed = props.autoRotateSpeed;\r\n\r\n // Grid\r\n if (props.showGrid) {\r\n const grid = new THREE.GridHelper(10, 10, 0x444444, 0x333333);\r\n scene.add(grid);\r\n }\r\n\r\n // Axes\r\n if (props.showAxes) {\r\n const axes = new THREE.AxesHelper(5);\r\n scene.add(axes);\r\n }\r\n\r\n // Handle resize\r\n resizeObserverInstance = new ResizeObserver(() => {\r\n if (!camera || !renderer || !containerRef.value) return;\r\n const w = containerRef.value.clientWidth;\r\n const h = containerRef.value.clientHeight;\r\n camera.aspect = w / h;\r\n camera.updateProjectionMatrix();\r\n renderer.setSize(w, h);\r\n });\r\n resizeObserverInstance.observe(container);\r\n\r\n // Start animation loop\r\n animate();\r\n\r\n isLoading.value = false;\r\n emit(\"ready\");\r\n } catch (err) {\r\n const e = err instanceof Error ? err : new Error(String(err));\r\n error.value = e;\r\n emit(\"error\", e);\r\n console.error(\"[PointCloudViewer] Failed to initialize:\", err);\r\n }\r\n}\r\n\r\n/**\r\n * Update point cloud geometry\r\n */\r\nfunction updatePointCloud(): void {\r\n if (!THREE || !scene) return;\r\n\r\n // Remove existing points\r\n if (pointsObject) {\r\n scene.remove(pointsObject);\r\n pointsObject.geometry.dispose();\r\n (\r\n pointsObject.material as InstanceType<typeof THREE.PointsMaterial>\r\n ).dispose();\r\n pointsObject = null;\r\n }\r\n\r\n if (props.points.length === 0) return;\r\n\r\n // Create geometry\r\n const geometry = new THREE.BufferGeometry();\r\n const positions = new Float32Array(props.points.length * 3);\r\n const colors = new Float32Array(props.points.length * 3);\r\n let hasColors = false;\r\n\r\n for (let i = 0; i < props.points.length; i++) {\r\n const point = props.points[i];\r\n positions[i * 3] = point.x;\r\n positions[i * 3 + 1] = point.y;\r\n positions[i * 3 + 2] = point.z;\r\n\r\n if (props.usePointColors && point.r !== undefined) {\r\n hasColors = true;\r\n colors[i * 3] = point.r;\r\n colors[i * 3 + 1] = point.g ?? 0;\r\n colors[i * 3 + 2] = point.b ?? 0;\r\n } else {\r\n const color = new THREE.Color(props.pointColor);\r\n colors[i * 3] = color.r;\r\n colors[i * 3 + 1] = color.g;\r\n colors[i * 3 + 2] = color.b;\r\n }\r\n }\r\n\r\n geometry.setAttribute(\"position\", new THREE.BufferAttribute(positions, 3));\r\n geometry.setAttribute(\"color\", new THREE.BufferAttribute(colors, 3));\r\n\r\n // Create material\r\n const material = new THREE.PointsMaterial({\r\n size: props.pointSize,\r\n vertexColors: true,\r\n sizeAttenuation: true,\r\n });\r\n\r\n // Create points\r\n pointsObject = new THREE.Points(geometry, material);\r\n scene.add(pointsObject);\r\n\r\n // Auto-fit camera if bounds provided\r\n if (props.bounds && camera) {\r\n const center = {\r\n x: (props.bounds.min.x + props.bounds.max.x) / 2,\r\n y: (props.bounds.min.y + props.bounds.max.y) / 2,\r\n z: (props.bounds.min.z + props.bounds.max.z) / 2,\r\n };\r\n\r\n const size = Math.max(\r\n props.bounds.max.x - props.bounds.min.x,\r\n props.bounds.max.y - props.bounds.min.y,\r\n props.bounds.max.z - props.bounds.min.z,\r\n );\r\n\r\n camera.position.set(\r\n center.x + size * 1.5,\r\n center.y + size * 1.5,\r\n center.z + size * 1.5,\r\n );\r\n camera.lookAt(center.x, center.y, center.z);\r\n }\r\n}\r\n\r\n/**\r\n * Animation loop\r\n */\r\nfunction animate(): void {\r\n animationId = requestAnimationFrame(animate);\r\n\r\n if (controls) {\r\n controls.update();\r\n }\r\n\r\n if (renderer && scene && camera) {\r\n renderer.render(scene, camera);\r\n }\r\n}\r\n\r\n/**\r\n * Cleanup\r\n */\r\nfunction cleanup(): void {\r\n if (animationId) {\r\n cancelAnimationFrame(animationId);\r\n animationId = null;\r\n }\r\n\r\n if (resizeObserverInstance) {\r\n resizeObserverInstance.disconnect();\r\n resizeObserverInstance = null;\r\n }\r\n\r\n if (pointsObject && scene) {\r\n scene.remove(pointsObject);\r\n pointsObject.geometry.dispose();\r\n (\r\n pointsObject.material as InstanceType<\r\n typeof import(\"three\").PointsMaterial\r\n >\r\n ).dispose();\r\n }\r\n\r\n if (controls) {\r\n controls.dispose();\r\n }\r\n\r\n if (renderer) {\r\n renderer.dispose();\r\n if (containerRef.value && renderer.domElement.parentNode) {\r\n containerRef.value.removeChild(renderer.domElement);\r\n }\r\n }\r\n\r\n scene = null;\r\n camera = null;\r\n renderer = null;\r\n controls = null;\r\n pointsObject = null;\r\n}\r\n\r\n// Watch for points changes\r\nwatch(() => props.points, updatePointCloud, { deep: true });\r\n\r\n// Watch for config changes\r\nwatch(\r\n [() => props.pointSize, () => props.pointColor, () => props.usePointColors],\r\n updatePointCloud,\r\n);\r\n\r\nwatch(\r\n () => props.autoRotate,\r\n (value) => {\r\n if (controls) {\r\n controls.autoRotate = value;\r\n }\r\n },\r\n);\r\n\r\nwatch(\r\n () => props.autoRotateSpeed,\r\n (value) => {\r\n if (controls) {\r\n controls.autoRotateSpeed = value;\r\n }\r\n },\r\n);\r\n\r\nonMounted(() => {\r\n initScene();\r\n});\r\n\r\nonUnmounted(() => {\r\n cleanup();\r\n});\r\n\r\n// Stats\r\nconst stats = computed(() => ({\r\n pointCount: props.points.length,\r\n hasColors: props.points.length > 0 && props.points[0].r !== undefined,\r\n}));\r\n\r\ndefineExpose({\r\n updatePointCloud,\r\n stats,\r\n});\r\n</script>\r\n\r\n<template>\r\n <div class=\"pointcloud-viewer\">\r\n <div ref=\"containerRef\" class=\"pointcloud-viewer__canvas\" />\r\n\r\n <!-- Loading -->\r\n <div v-if=\"isLoading\" class=\"pointcloud-viewer__overlay\">\r\n <div class=\"pointcloud-viewer__spinner\" />\r\n <span>Loading viewer...</span>\r\n </div>\r\n\r\n <!-- Error -->\r\n <div\r\n v-if=\"error\"\r\n class=\"pointcloud-viewer__overlay pointcloud-viewer__overlay--error\"\r\n >\r\n <span>⚠️ {{ error.message }}</span>\r\n <small>Make sure 'three' package is installed</small>\r\n </div>\r\n\r\n <!-- Stats -->\r\n <div class=\"pointcloud-viewer__stats\">\r\n <span>Points: {{ stats.pointCount.toLocaleString() }}</span>\r\n <span v-if=\"stats.hasColors\">🎨 Colored</span>\r\n </div>\r\n </div>\r\n</template>\r\n\r\n<style scoped>\r\n.pointcloud-viewer {\r\n position: relative;\r\n width: 100%;\r\n height: 100%;\r\n min-height: 300px;\r\n background: #1e1e1e;\r\n border-radius: 4px;\r\n overflow: hidden;\r\n}\r\n\r\n.pointcloud-viewer__canvas {\r\n width: 100%;\r\n height: 100%;\r\n}\r\n\r\n.pointcloud-viewer__overlay {\r\n position: absolute;\r\n top: 0;\r\n left: 0;\r\n right: 0;\r\n bottom: 0;\r\n display: flex;\r\n flex-direction: column;\r\n align-items: center;\r\n justify-content: center;\r\n gap: 12px;\r\n background: rgba(30, 30, 30, 0.9);\r\n color: #ccc;\r\n}\r\n\r\n.pointcloud-viewer__overlay--error {\r\n color: #f48771;\r\n}\r\n\r\n.pointcloud-viewer__overlay small {\r\n color: #858585;\r\n}\r\n\r\n.pointcloud-viewer__spinner {\r\n width: 32px;\r\n height: 32px;\r\n border: 3px solid rgba(255, 255, 255, 0.3);\r\n border-top-color: #fff;\r\n border-radius: 50%;\r\n animation: spin 1s linear infinite;\r\n}\r\n\r\n@keyframes spin {\r\n to {\r\n transform: rotate(360deg);\r\n }\r\n}\r\n\r\n.pointcloud-viewer__stats {\r\n position: absolute;\r\n bottom: 8px;\r\n left: 8px;\r\n display: flex;\r\n gap: 12px;\r\n padding: 4px 8px;\r\n background: rgba(0, 0, 0, 0.6);\r\n border-radius: 3px;\r\n color: #ccc;\r\n font-size: 11px;\r\n}\r\n</style>\r\n","<script setup lang=\"ts\">\r\n/**\r\n * StreamViewer - Generic stream viewer component\r\n * Displays real-time data from various streaming sources\r\n */\r\nimport { computed, ref, watch } from \"vue\";\r\n\r\ninterface Props {\r\n /** Stream data to display */\r\n data?: unknown;\r\n /** Stream type for formatting */\r\n type?: \"json\" | \"text\" | \"binary\" | \"auto\";\r\n /** Maximum lines to display */\r\n maxLines?: number;\r\n /** Auto-scroll to bottom */\r\n autoScroll?: boolean;\r\n /** Show timestamps */\r\n showTimestamps?: boolean;\r\n /** Paused state */\r\n paused?: boolean;\r\n /** Custom formatter function */\r\n formatter?: (data: unknown) => string;\r\n}\r\n\r\nconst props = withDefaults(defineProps<Props>(), {\r\n type: \"auto\",\r\n maxLines: 100,\r\n autoScroll: true,\r\n showTimestamps: true,\r\n paused: false,\r\n});\r\n\r\nconst emit = defineEmits<{\r\n (e: \"clear\"): void;\r\n (e: \"pause\", paused: boolean): void;\r\n}>();\r\n\r\ninterface LogEntry {\r\n id: number;\r\n timestamp: Date;\r\n data: string;\r\n type: \"data\" | \"error\" | \"info\";\r\n}\r\n\r\nconst logs = ref<LogEntry[]>([]);\r\nconst containerRef = ref<HTMLElement | null>(null);\r\nlet idCounter = 0;\r\n\r\n/**\r\n * Format data based on type\r\n */\r\nfunction formatData(data: unknown): string {\r\n if (props.formatter) {\r\n return props.formatter(data);\r\n }\r\n\r\n if (data === null || data === undefined) {\r\n return String(data);\r\n }\r\n\r\n const type = props.type === \"auto\" ? detectType(data) : props.type;\r\n\r\n switch (type) {\r\n case \"json\":\r\n try {\r\n return JSON.stringify(data, null, 2);\r\n } catch {\r\n return String(data);\r\n }\r\n case \"binary\":\r\n if (data instanceof ArrayBuffer) {\r\n const bytes = new Uint8Array(data);\r\n return `Binary: ${bytes.length} bytes`;\r\n }\r\n return String(data);\r\n default:\r\n return String(data);\r\n }\r\n}\r\n\r\n/**\r\n * Detect data type\r\n */\r\nfunction detectType(data: unknown): \"json\" | \"text\" | \"binary\" {\r\n if (data instanceof ArrayBuffer || data instanceof Uint8Array) {\r\n return \"binary\";\r\n }\r\n if (typeof data === \"object\") {\r\n return \"json\";\r\n }\r\n return \"text\";\r\n}\r\n\r\n/**\r\n * Add log entry\r\n */\r\nfunction addLog(data: unknown, type: LogEntry[\"type\"] = \"data\"): void {\r\n if (props.paused) return;\r\n\r\n const entry: LogEntry = {\r\n id: idCounter++,\r\n timestamp: new Date(),\r\n data: formatData(data),\r\n type,\r\n };\r\n\r\n logs.value = [...logs.value, entry].slice(-props.maxLines);\r\n\r\n if (props.autoScroll) {\r\n scrollToBottom();\r\n }\r\n}\r\n\r\n/**\r\n * Scroll to bottom\r\n */\r\nfunction scrollToBottom(): void {\r\n requestAnimationFrame(() => {\r\n if (containerRef.value) {\r\n containerRef.value.scrollTop = containerRef.value.scrollHeight;\r\n }\r\n });\r\n}\r\n\r\n/**\r\n * Clear logs\r\n */\r\nfunction clear(): void {\r\n logs.value = [];\r\n emit(\"clear\");\r\n}\r\n\r\n/**\r\n * Toggle pause\r\n */\r\nfunction togglePause(): void {\r\n emit(\"pause\", !props.paused);\r\n}\r\n\r\n/**\r\n * Format timestamp\r\n */\r\nfunction formatTimestamp(date: Date): string {\r\n return date.toLocaleTimeString(\"en-US\", {\r\n hour12: false,\r\n hour: \"2-digit\",\r\n minute: \"2-digit\",\r\n second: \"2-digit\",\r\n fractionalSecondDigits: 3,\r\n });\r\n}\r\n\r\n// Watch for new data\r\nwatch(\r\n () => props.data,\r\n (newData) => {\r\n if (newData !== undefined) {\r\n addLog(newData);\r\n }\r\n },\r\n);\r\n\r\n// Computed stats\r\nconst stats = computed(() => ({\r\n total: logs.value.length,\r\n errors: logs.value.filter((l) => l.type === \"error\").length,\r\n}));\r\n\r\ndefineExpose({\r\n addLog,\r\n clear,\r\n logs,\r\n stats,\r\n});\r\n</script>\r\n\r\n<template>\r\n <div class=\"stream-viewer\">\r\n <div class=\"stream-viewer__header\">\r\n <div class=\"stream-viewer__stats\">\r\n <span>Lines: {{ stats.total }}</span>\r\n <span v-if=\"stats.errors > 0\" class=\"stream-viewer__errors\">\r\n Errors: {{ stats.errors }}\r\n </span>\r\n </div>\r\n <div class=\"stream-viewer__actions\">\r\n <button\r\n @click=\"togglePause\"\r\n class=\"stream-viewer__btn\"\r\n :class=\"{ 'stream-viewer__btn--active': paused }\"\r\n >\r\n {{ paused ? \"▶ Resume\" : \"⏸ Pause\" }}\r\n </button>\r\n <button @click=\"clear\" class=\"stream-viewer__btn\">🗑 Clear</button>\r\n </div>\r\n </div>\r\n\r\n <div ref=\"containerRef\" class=\"stream-viewer__content\">\r\n <div\r\n v-for=\"log in logs\"\r\n :key=\"log.id\"\r\n class=\"stream-viewer__entry\"\r\n :class=\"`stream-viewer__entry--${log.type}`\"\r\n >\r\n <span v-if=\"showTimestamps\" class=\"stream-viewer__timestamp\">\r\n {{ formatTimestamp(log.timestamp) }}\r\n </span>\r\n <pre class=\"stream-viewer__data\">{{ log.data }}</pre>\r\n </div>\r\n\r\n <div v-if=\"logs.length === 0\" class=\"stream-viewer__empty\">\r\n Waiting for data...\r\n </div>\r\n </div>\r\n </div>\r\n</template>\r\n\r\n<style scoped>\r\n.stream-viewer {\r\n display: flex;\r\n flex-direction: column;\r\n height: 100%;\r\n min-height: 200px;\r\n background: #1e1e1e;\r\n border-radius: 4px;\r\n overflow: hidden;\r\n font-family: \"Consolas\", \"Monaco\", monospace;\r\n font-size: 12px;\r\n}\r\n\r\n.stream-viewer__header {\r\n display: flex;\r\n justify-content: space-between;\r\n align-items: center;\r\n padding: 8px 12px;\r\n background: #252526;\r\n border-bottom: 1px solid #3c3c3c;\r\n}\r\n\r\n.stream-viewer__stats {\r\n display: flex;\r\n gap: 16px;\r\n color: #858585;\r\n}\r\n\r\n.stream-viewer__errors {\r\n color: #f48771;\r\n}\r\n\r\n.stream-viewer__actions {\r\n display: flex;\r\n gap: 8px;\r\n}\r\n\r\n.stream-viewer__btn {\r\n padding: 4px 8px;\r\n background: #3c3c3c;\r\n border: none;\r\n border-radius: 3px;\r\n color: #cccccc;\r\n cursor: pointer;\r\n font-size: 11px;\r\n}\r\n\r\n.stream-viewer__btn:hover {\r\n background: #4c4c4c;\r\n}\r\n\r\n.stream-viewer__btn--active {\r\n background: #0e639c;\r\n}\r\n\r\n.stream-viewer__content {\r\n flex: 1;\r\n overflow-y: auto;\r\n padding: 8px;\r\n}\r\n\r\n.stream-viewer__entry {\r\n display: flex;\r\n gap: 8px;\r\n padding: 2px 0;\r\n border-bottom: 1px solid #2d2d2d;\r\n}\r\n\r\n.stream-viewer__entry--error {\r\n background: rgba(244, 135, 113, 0.1);\r\n}\r\n\r\n.stream-viewer__entry--info {\r\n color: #4ec9b0;\r\n}\r\n\r\n.stream-viewer__timestamp {\r\n color: #858585;\r\n white-space: nowrap;\r\n}\r\n\r\n.stream-viewer__data {\r\n margin: 0;\r\n white-space: pre-wrap;\r\n word-break: break-all;\r\n color: #d4d4d4;\r\n}\r\n\r\n.stream-viewer__empty {\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n height: 100%;\r\n color: #858585;\r\n}\r\n</style>\r\n","<script setup lang=\"ts\">\r\n/**\r\n * UnifiedPlayer - Unified video player for HLS and WebRTC/WHEP streams\r\n * Supports both HLS streaming and WebRTC WHEP protocol\r\n */\r\nimport { computed, onMounted, onUnmounted, ref, watch } from \"vue\";\r\nimport { useHLS } from \"../composables/useHLS\";\r\nimport type { HLSCallbacks, HLSConfig } from \"../types\";\r\n\r\ninterface Props {\r\n /** Stream type: 'hls' or 'webrtc' */\r\n type: \"hls\" | \"webrtc\";\r\n /** Stream configuration */\r\n config: {\r\n url: string;\r\n [key: string]: unknown;\r\n };\r\n /** Auto-open/connect on mount */\r\n autoOpen?: boolean;\r\n /** Auto-play video */\r\n autoplay?: boolean;\r\n /** Show native controls */\r\n controls?: boolean;\r\n /** Muted */\r\n muted?: boolean;\r\n /** Low latency mode (HLS only) */\r\n lowLatency?: boolean;\r\n}\r\n\r\nconst props = withDefaults(defineProps<Props>(), {\r\n autoOpen: true,\r\n autoplay: true,\r\n controls: true,\r\n muted: false,\r\n lowLatency: false,\r\n});\r\n\r\nconst emit = defineEmits<{\r\n (e: \"open\"): void;\r\n (e: \"close\"): void;\r\n (e: \"error\", error: Error): void;\r\n (e: \"status\", status: string): void;\r\n}>();\r\n\r\nconst videoRef = ref<HTMLVideoElement | null>(null);\r\nconst isLoading = ref(false);\r\nconst error = ref<Error | null>(null);\r\nconst status = ref(\"idle\");\r\n\r\n// WebRTC state\r\nlet peerConnection: RTCPeerConnection | null = null;\r\nlet mediaStream: MediaStream | null = null;\r\nlet abortController: AbortController | null = null;\r\n\r\n// HLS state\r\nlet hlsInstance: ReturnType<typeof useHLS> | null = null;\r\n\r\n// Computed style for video\r\nconst videoStyle = computed(() => ({\r\n width: \"100%\",\r\n height: \"100%\",\r\n objectFit: \"contain\" as const,\r\n}));\r\n\r\n/**\r\n * Initialize WebRTC/WHEP connection\r\n */\r\nasync function initWebRTC(url: string): Promise<void> {\r\n if (!videoRef.value) {\r\n throw new Error(\"Video element not available\");\r\n }\r\n\r\n status.value = \"connecting\";\r\n emit(\"status\", \"connecting\");\r\n\r\n try {\r\n // Cleanup previous connection\r\n cleanupWebRTC();\r\n\r\n // Create peer connection\r\n peerConnection = new RTCPeerConnection({\r\n iceServers: [{ urls: \"stun:stun.l.google.com:19302\" }],\r\n });\r\n\r\n // Handle incoming tracks\r\n peerConnection.ontrack = (event) => {\r\n if (videoRef.value && event.streams[0]) {\r\n videoRef.value.srcObject = event.streams[0];\r\n mediaStream = event.streams[0];\r\n status.value = \"connected\";\r\n emit(\"status\", \"connected\");\r\n emit(\"open\");\r\n }\r\n };\r\n\r\n // Handle connection state changes\r\n peerConnection.onconnectionstatechange = () => {\r\n const state = peerConnection?.connectionState;\r\n if (state === \"failed\" || state === \"disconnected\") {\r\n status.value = state;\r\n emit(\"status\", state);\r\n // Auto-reconnect after delay\r\n setTimeout(() => initWebRTC(url), 2000);\r\n } else if (state === \"connected\") {\r\n status.value = \"connected\";\r\n emit(\"status\", \"connected\");\r\n }\r\n };\r\n\r\n // Create offer\r\n const offer = await peerConnection.createOffer({\r\n offerToReceiveVideo: true,\r\n offerToReceiveAudio: true,\r\n });\r\n await peerConnection.setLocalDescription(offer);\r\n\r\n // Send offer to WHEP endpoint\r\n abortController = new AbortController();\r\n const response = await fetch(url, {\r\n method: \"POST\",\r\n headers: {\r\n \"Content-Type\": \"application/sdp\",\r\n },\r\n body: offer.sdp,\r\n signal: abortController.signal,\r\n });\r\n\r\n if (!response.ok) {\r\n throw new Error(`WHEP request failed: ${response.status}`);\r\n }\r\n\r\n // Set remote description\r\n const answerSdp = await response.text();\r\n await peerConnection.setRemoteDescription({\r\n type: \"answer\",\r\n sdp: answerSdp,\r\n });\r\n\r\n isLoading.value = false;\r\n } catch (err) {\r\n const e = err instanceof Error ? err : new Error(String(err));\r\n error.value = e;\r\n status.value = \"error\";\r\n emit(\"error\", e);\r\n emit(\"status\", \"error\");\r\n isLoading.value = false;\r\n }\r\n}\r\n\r\n/**\r\n * Cleanup WebRTC connection\r\n */\r\nfunction cleanupWebRTC(): void {\r\n if (abortController) {\r\n abortController.abort();\r\n abortController = null;\r\n }\r\n\r\n if (mediaStream) {\r\n mediaStream.getTracks().forEach((track) => track.stop());\r\n mediaStream = null;\r\n }\r\n\r\n if (peerConnection) {\r\n peerConnection.close();\r\n peerConnection = null;\r\n }\r\n\r\n if (videoRef.value) {\r\n videoRef.value.srcObject = null;\r\n }\r\n}\r\n\r\n/**\r\n * Initialize HLS stream\r\n */\r\nasync function initHLS(url: string): Promise<void> {\r\n if (!videoRef.value) {\r\n throw new Error(\"Video element not available\");\r\n }\r\n\r\n status.value = \"connecting\";\r\n emit(\"status\", \"connecting\");\r\n\r\n try {\r\n const hlsConfig: HLSConfig = {\r\n url,\r\n autoPlay: props.autoplay,\r\n lowLatencyMode: props.lowLatency,\r\n };\r\n\r\n const hlsCallbacks: HLSCallbacks = {\r\n onManifestLoaded: () => {\r\n status.value = \"connected\";\r\n emit(\"status\", \"connected\");\r\n emit(\"open\");\r\n isLoading.value = false;\r\n },\r\n onError: (err) => {\r\n error.value = err;\r\n status.value = \"error\";\r\n emit(\"error\", err);\r\n emit(\"status\", \"error\");\r\n isLoading.value = false;\r\n },\r\n };\r\n\r\n hlsInstance = useHLS(hlsConfig, hlsCallbacks);\r\n await hlsInstance.attach(videoRef.value);\r\n } catch (err) {\r\n const e = err instanceof Error ? err : new Error(String(err));\r\n error.value = e;\r\n status.value = \"error\";\r\n emit(\"error\", e);\r\n emit(\"status\", \"error\");\r\n isLoading.value = false;\r\n }\r\n}\r\n\r\n/**\r\n * Cleanup HLS stream\r\n */\r\nfunction cleanupHLS(): void {\r\n if (hlsInstance) {\r\n hlsInstance.destroy();\r\n hlsInstance = null;\r\n }\r\n}\r\n\r\n/**\r\n * Open/connect stream\r\n */\r\nasync function open(): Promise<void> {\r\n if (!props.config?.url) {\r\n const err = new Error(\"Stream URL is required\");\r\n error.value = err;\r\n emit(\"error\", err);\r\n return;\r\n }\r\n\r\n isLoading.value = true;\r\n error.value = null;\r\n\r\n if (props.type === \"webrtc\") {\r\n await initWebRTC(props.config.url);\r\n } else {\r\n await initHLS(props.config.url);\r\n }\r\n}\r\n\r\n/**\r\n * Close/disconnect stream\r\n */\r\nfunction close(): void {\r\n if (props.type === \"webrtc\") {\r\n cleanupWebRTC();\r\n } else {\r\n cleanupHLS();\r\n }\r\n\r\n status.value = \"idle\";\r\n emit(\"status\", \"idle\");\r\n emit(\"close\");\r\n}\r\n\r\n// Watch for config/type changes\r\nwatch(\r\n () => [props.type, props.config?.url],\r\n () => {\r\n if (props.autoOpen) {\r\n close();\r\n open();\r\n }\r\n },\r\n);\r\n\r\n// Auto-open on mount\r\nonMounted(() => {\r\n if (props.autoOpen && props.config?.url) {\r\n open();\r\n }\r\n});\r\n\r\n// Cleanup on unmount\r\nonUnmounted(() => {\r\n close();\r\n});\r\n\r\n// Expose methods\r\ndefineExpose({\r\n open,\r\n close,\r\n status,\r\n error,\r\n videoRef,\r\n});\r\n</script>\r\n\r\n<template>\r\n <div class=\"unified-player\">\r\n <video\r\n ref=\"videoRef\"\r\n :style=\"videoStyle\"\r\n :autoplay=\"autoplay\"\r\n :controls=\"controls\"\r\n :muted=\"muted\"\r\n playsinline\r\n />\r\n <div v-if=\"isLoading\" class=\"unified-player__loading\">\r\n <div class=\"unified-player__spinner\" />\r\n </div>\r\n <div v-if=\"error\" class=\"unified-player__error\">\r\n <span>⚠️ {{ error.message }}</span>\r\n </div>\r\n </div>\r\n</template>\r\n\r\n<style scoped>\r\n.unified-player {\r\n position: relative;\r\n width: 100%;\r\n height: 100%;\r\n background: #000;\r\n}\r\n\r\n.unified-player video {\r\n display: block;\r\n}\r\n\r\n.unified-player__loading {\r\n position: absolute;\r\n top: 50%;\r\n left: 50%;\r\n transform: translate(-50%, -50%);\r\n}\r\n\r\n.unified-player__spinner {\r\n width: 48px;\r\n height: 48px;\r\n border: 3px solid rgba(255, 255, 255, 0.3);\r\n border-top-color: #fff;\r\n border-radius: 50%;\r\n animation: spin 1s linear infinite;\r\n}\r\n\r\n@keyframes spin {\r\n to {\r\n transform: rotate(360deg);\r\n }\r\n}\r\n\r\n.unified-player__error {\r\n position: absolute;\r\n bottom: 10px;\r\n left: 10px;\r\n right: 10px;\r\n padding: 10px;\r\n background: rgba(244, 67, 54, 0.9);\r\n color: white;\r\n border-radius: 4px;\r\n text-align: center;\r\n}\r\n</style>\r\n","<script setup lang=\"ts\">\r\n/**\r\n * WebRTCViewer - WebRTC stream viewer with point cloud and detection support\r\n * Combines video, point cloud, and bounding box visualization\r\n */\r\nimport { computed, onMounted, ref, watch } from \"vue\";\r\nimport { useWebRTC } from \"../composables/useWebRTC\";\r\nimport type {\r\n BoundingBox3D,\r\n DetectionFrame,\r\n PointCloudFrame,\r\n WebRTCCallbacks,\r\n WebRTCConfig,\r\n} from \"../types\";\r\n\r\ninterface Props {\r\n /** Signaling server URL */\r\n signalingUrl: string;\r\n /** ICE servers */\r\n iceServers?: RTCIceServer[];\r\n /** Enable point cloud */\r\n enablePointCloud?: boolean;\r\n /** Enable detections */\r\n enableDetections?: boolean;\r\n /** Auto-connect on mount */\r\n autoConnect?: boolean;\r\n /** Auto-reconnect */\r\n autoReconnect?: boolean;\r\n /** Max reconnect attempts */\r\n maxReconnectAttempts?: number;\r\n /** Show connection status */\r\n showStatus?: boolean;\r\n /** Show stats */\r\n showStats?: boolean;\r\n}\r\n\r\nconst props = withDefaults(defineProps<Props>(), {\r\n iceServers: () => [{ urls: \"stun:stun.l.google.com:19302\" }],\r\n enablePointCloud: true,\r\n enableDetections: true,\r\n autoConnect: true,\r\n autoReconnect: true,\r\n maxReconnectAttempts: 5,\r\n showStatus: true,\r\n showStats: true,\r\n});\r\n\r\nconst emit = defineEmits<{\r\n (e: \"connected\"): void;\r\n (e: \"disconnected\"): void;\r\n (e: \"error\", error: Error): void;\r\n (e: \"pointcloud\", frame: PointCloudFrame): void;\r\n (e: \"detections\", frame: DetectionFrame): void;\r\n (e: \"boundingboxes\", boxes: BoundingBox3D[]): void;\r\n (e: \"status\", status: string): void;\r\n}>();\r\n\r\nconst statusMessage = ref(\"Idle\");\r\n\r\nconst config: WebRTCConfig = {\r\n signalingUrl: props.signalingUrl,\r\n iceServers: props.iceServers,\r\n enablePointCloud: props.enablePointCloud,\r\n enableDetections: props.enableDetections,\r\n autoReconnect: props.autoReconnect,\r\n maxReconnectAttempts: props.maxReconnectAttempts,\r\n};\r\n\r\nconst callbacks: WebRTCCallbacks = {\r\n onStatus: (status) => {\r\n statusMessage.value = status;\r\n emit(\"status\", status);\r\n },\r\n onConnectionState: (state) => {\r\n if (state === \"connected\") {\r\n emit(\"connected\");\r\n } else if (\r\n state === \"disconnected\" ||\r\n state === \"closed\" ||\r\n state === \"failed\"\r\n ) {\r\n emit(\"disconnected\");\r\n }\r\n },\r\n onPointCloudFrame: (frame) => {\r\n emit(\"pointcloud\", frame);\r\n },\r\n onDetectionFrame: (frame) => {\r\n emit(\"detections\", frame);\r\n },\r\n onBoundingBoxData: (boxes) => {\r\n emit(\"boundingboxes\", boxes);\r\n },\r\n onError: (error) => {\r\n emit(\"error\", error);\r\n },\r\n};\r\n\r\nconst {\r\n isRunning,\r\n connectionState,\r\n dataChannels,\r\n lastPointCloudFrame,\r\n lastDetectionFrame,\r\n lastBoundingBoxes,\r\n error,\r\n start,\r\n stop,\r\n sendControl,\r\n} = useWebRTC(config, callbacks);\r\n\r\n// Stats\r\nconst stats = computed(() => ({\r\n channels: dataChannels.value.size,\r\n pointCount: lastPointCloudFrame.value?.points.length ?? 0,\r\n detectionCount: lastDetectionFrame.value?.detections.length ?? 0,\r\n bboxCount: lastBoundingBoxes.value.length,\r\n}));\r\n\r\n// Connection state color\r\nconst stateColor = computed(() => {\r\n switch (connectionState.value) {\r\n case \"connected\":\r\n return \"#4caf50\";\r\n case \"connecting\":\r\n return \"#ff9800\";\r\n case \"reconnecting\":\r\n return \"#ff9800\";\r\n case \"error\":\r\n return \"#f44336\";\r\n default:\r\n return \"#9e9e9e\";\r\n }\r\n});\r\n\r\n// Auto-connect on mount\r\nonMounted(() => {\r\n if (props.autoConnect) {\r\n start();\r\n }\r\n});\r\n\r\n// Watch for signalingUrl changes\r\nwatch(\r\n () => props.signalingUrl,\r\n () => {\r\n if (isRunning.value) {\r\n stop();\r\n config.signalingUrl = props.signalingUrl;\r\n start();\r\n }\r\n },\r\n);\r\n\r\ndefineExpose({\r\n isRunning,\r\n connectionState,\r\n start,\r\n stop,\r\n sendControl,\r\n lastPointCloudFrame,\r\n lastDetectionFrame,\r\n lastBoundingBoxes,\r\n stats,\r\n});\r\n</script>\r\n\r\n<template>\r\n <div class=\"webrtc-viewer\">\r\n <!-- Header -->\r\n <div v-if=\"showStatus\" class=\"webrtc-viewer__header\">\r\n <div class=\"webrtc-viewer__status\">\r\n <span\r\n class=\"webrtc-viewer__indicator\"\r\n :style=\"{ backgroundColor: stateColor }\"\r\n />\r\n <span>{{ connectionState }}</span>\r\n </div>\r\n\r\n <div class=\"webrtc-viewer__controls\">\r\n <button\r\n v-if=\"!isRunning\"\r\n @click=\"start\"\r\n class=\"webrtc-viewer__btn webrtc-viewer__btn--connect\"\r\n >\r\n ▶ Connect\r\n </button>\r\n <button\r\n v-else\r\n @click=\"stop\"\r\n class=\"webrtc-viewer__btn webrtc-viewer__btn--disconnect\"\r\n >\r\n ⏹ Disconnect\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <!-- Main content -->\r\n <div class=\"webrtc-viewer__content\">\r\n <slot\r\n :is-running=\"isRunning\"\r\n :connection-state=\"connectionState\"\r\n :point-cloud-frame=\"lastPointCloudFrame\"\r\n :detection-frame=\"lastDetectionFrame\"\r\n :bounding-boxes=\"lastBoundingBoxes\"\r\n :error=\"error\"\r\n :start=\"start\"\r\n :stop=\"stop\"\r\n :send-control=\"sendControl\"\r\n >\r\n <!-- Default content when no slot provided -->\r\n <div class=\"webrtc-viewer__default\">\r\n <div v-if=\"!isRunning\" class=\"webrtc-viewer__placeholder\">\r\n <span>Click Connect to start WebRTC stream</span>\r\n </div>\r\n\r\n <div\r\n v-else-if=\"connectionState === 'connecting'\"\r\n class=\"webrtc-viewer__loading\"\r\n >\r\n <div class=\"webrtc-viewer__spinner\" />\r\n <span>{{ statusMessage }}</span>\r\n </div>\r\n\r\n <div v-else-if=\"error\" class=\"webrtc-viewer__error\">\r\n <span>⚠️ {{ error.message }}</span>\r\n </div>\r\n\r\n <div v-else class=\"webrtc-viewer__info\">\r\n <p>WebRTC Connected</p>\r\n <p v-if=\"stats.pointCount > 0\">\r\n Points: {{ stats.pointCount.toLocaleString() }}\r\n </p>\r\n <p v-if=\"stats.bboxCount > 0\">\r\n Bounding Boxes: {{ stats.bboxCount }}\r\n </p>\r\n </div>\r\n </div>\r\n </slot>\r\n </div>\r\n\r\n <!-- Stats footer -->\r\n <div v-if=\"showStats && isRunning\" class=\"webrtc-viewer__footer\">\r\n <span>Channels: {{ stats.channels }}</span>\r\n <span v-if=\"props.enablePointCloud\">\r\n Points: {{ stats.pointCount.toLocaleString() }}\r\n </span>\r\n <span v-if=\"props.enableDetections\">\r\n Detections: {{ stats.detectionCount }}\r\n </span>\r\n </div>\r\n </div>\r\n</template>\r\n\r\n<style scoped>\r\n.webrtc-viewer {\r\n display: flex;\r\n flex-direction: column;\r\n height: 100%;\r\n min-height: 200px;\r\n background: #1e1e1e;\r\n border-radius: 4px;\r\n overflow: hidden;\r\n}\r\n\r\n.webrtc-viewer__header {\r\n display: flex;\r\n justify-content: space-between;\r\n align-items: center;\r\n padding: 8px 12px;\r\n background: #252526;\r\n border-bottom: 1px solid #3c3c3c;\r\n}\r\n\r\n.webrtc-viewer__status {\r\n display: flex;\r\n align-items: center;\r\n gap: 8px;\r\n color: #ccc;\r\n font-size: 12px;\r\n}\r\n\r\n.webrtc-viewer__indicator {\r\n width: 8px;\r\n height: 8px;\r\n border-radius: 50%;\r\n}\r\n\r\n.webrtc-viewer__controls {\r\n display: flex;\r\n gap: 8px;\r\n}\r\n\r\n.webrtc-viewer__btn {\r\n padding: 4px 12px;\r\n border: none;\r\n border-radius: 3px;\r\n font-size: 12px;\r\n cursor: pointer;\r\n}\r\n\r\n.webrtc-viewer__btn--connect {\r\n background: #0e639c;\r\n color: white;\r\n}\r\n\r\n.webrtc-viewer__btn--connect:hover {\r\n background: #1177bb;\r\n}\r\n\r\n.webrtc-viewer__btn--disconnect {\r\n background: #5a5a5a;\r\n color: white;\r\n}\r\n\r\n.webrtc-viewer__btn--disconnect:hover {\r\n background: #6a6a6a;\r\n}\r\n\r\n.webrtc-viewer__content {\r\n flex: 1;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n min-height: 100px;\r\n}\r\n\r\n.webrtc-viewer__default {\r\n display: flex;\r\n flex-direction: column;\r\n align-items: center;\r\n justify-content: center;\r\n gap: 12px;\r\n color: #858585;\r\n text-align: center;\r\n padding: 24px;\r\n}\r\n\r\n.webrtc-viewer__placeholder,\r\n.webrtc-viewer__loading,\r\n.webrtc-viewer__info {\r\n display: flex;\r\n flex-direction: column;\r\n align-items: center;\r\n gap: 8px;\r\n}\r\n\r\n.webrtc-viewer__error {\r\n color: #f48771;\r\n}\r\n\r\n.webrtc-viewer__spinner {\r\n width: 32px;\r\n height: 32px;\r\n border: 3px solid rgba(255, 255, 255, 0.3);\r\n border-top-color: #fff;\r\n border-radius: 50%;\r\n animation: spin 1s linear infinite;\r\n}\r\n\r\n@keyframes spin {\r\n to {\r\n transform: rotate(360deg);\r\n }\r\n}\r\n\r\n.webrtc-viewer__info p {\r\n margin: 4px 0;\r\n color: #ccc;\r\n}\r\n\r\n.webrtc-viewer__footer {\r\n display: flex;\r\n gap: 16px;\r\n padding: 6px 12px;\r\n background: #252526;\r\n border-top: 1px solid #3c3c3c;\r\n color: #858585;\r\n font-size: 11px;\r\n}\r\n</style>\r\n","<script setup lang=\"ts\">\r\n/**\r\n * DataStreamView - Vue component for generic data streaming\r\n * @component\r\n */\r\nimport { onMounted, toRefs, watch } from \"vue\";\r\nimport { useDataStream } from \"../composables/useDataStream\";\r\nimport type { DataStreamConfig } from \"../types\";\r\n\r\nexport interface DataStreamViewProps<T = unknown> {\r\n /** Data stream configuration */\r\n config?: DataStreamConfig<T>;\r\n /** Auto-start on mount */\r\n autoStart?: boolean;\r\n}\r\n\r\nconst props = withDefaults(defineProps<DataStreamViewProps>(), {\r\n config: () => ({}),\r\n autoStart: true,\r\n});\r\n\r\nconst emit = defineEmits<{\r\n data: [data: unknown];\r\n batch: [data: unknown[]];\r\n error: [error: Error];\r\n}>();\r\n\r\nconst { config } = toRefs(props);\r\n\r\nconst {\r\n data,\r\n buffer,\r\n bufferSize,\r\n isStreaming,\r\n itemsPerSecond,\r\n totalItems,\r\n error,\r\n start,\r\n stop,\r\n push,\r\n clear,\r\n getBuffer,\r\n subscribe,\r\n} = useDataStream(props.config, {\r\n onData: (data) => emit(\"data\", data),\r\n onBatch: (batch) => emit(\"batch\", batch),\r\n onError: (err) => emit(\"error\", err),\r\n});\r\n\r\n// Auto-start on mount if enabled\r\nonMounted(() => {\r\n if (props.autoStart) {\r\n start();\r\n }\r\n});\r\n\r\n// Watch for config changes\r\nwatch(\r\n config,\r\n () => {\r\n stop();\r\n start();\r\n },\r\n { deep: true },\r\n);\r\n\r\ndefineExpose({\r\n data,\r\n buffer,\r\n bufferSize,\r\n isStreaming,\r\n itemsPerSecond,\r\n totalItems,\r\n error,\r\n start,\r\n stop,\r\n push,\r\n clear,\r\n getBuffer,\r\n subscribe,\r\n});\r\n</script>\r\n\r\n<template>\r\n <slot\r\n :data=\"data\"\r\n :buffer=\"buffer\"\r\n :buffer-size=\"bufferSize\"\r\n :is-streaming=\"isStreaming\"\r\n :items-per-second=\"itemsPerSecond\"\r\n :total-items=\"totalItems\"\r\n :error=\"error\"\r\n :start=\"start\"\r\n :stop=\"stop\"\r\n :push=\"push\"\r\n :clear=\"clear\"\r\n />\r\n</template>\r\n","<script setup lang=\"ts\">\r\n/**\r\n * HTTPStream - Vue component for HTTP streaming with Fetch API\r\n * @component\r\n */\r\nimport { toRefs, watch } from \"vue\";\r\nimport { useHTTPStream } from \"../composables/useHTTP\";\r\n\r\nexport interface HTTPStreamProps {\r\n /** HTTP endpoint URL */\r\n url: string;\r\n /** HTTP method */\r\n method?: \"GET\" | \"POST\" | \"PUT\" | \"PATCH\";\r\n /** Request headers */\r\n headers?: Record<string, string>;\r\n /** Request body (for POST/PUT/PATCH) */\r\n body?: unknown;\r\n /** Credentials mode */\r\n credentials?: RequestCredentials;\r\n /** Auto-connect on mount */\r\n autoConnect?: boolean;\r\n /** Auto-reconnect on error */\r\n autoReconnect?: boolean;\r\n /** Max reconnection attempts */\r\n maxReconnectAttempts?: number;\r\n /** Reconnection delay in ms */\r\n reconnectDelay?: number;\r\n /** Parse as line-delimited JSON */\r\n ndjson?: boolean;\r\n}\r\n\r\nconst props = withDefaults(defineProps<HTTPStreamProps>(), {\r\n method: \"GET\",\r\n headers: () => ({}),\r\n body: undefined,\r\n credentials: \"same-origin\",\r\n autoConnect: true,\r\n autoReconnect: true,\r\n maxReconnectAttempts: 5,\r\n reconnectDelay: 1000,\r\n ndjson: true,\r\n});\r\n\r\nconst emit = defineEmits<{\r\n open: [];\r\n chunk: [data: unknown, rawChunk: string];\r\n complete: [];\r\n error: [error: Error];\r\n progress: [bytesReceived: number];\r\n reconnecting: [attempt: number, maxAttempts: number];\r\n reconnected: [];\r\n reconnectFailed: [];\r\n}>();\r\n\r\nconst { url } = toRefs(props);\r\n\r\nconst {\r\n isConnected,\r\n isStreaming,\r\n connectionState,\r\n lastChunk,\r\n chunks,\r\n bytesReceived,\r\n error,\r\n reconnectAttempts,\r\n connect,\r\n disconnect,\r\n clearChunks,\r\n} = useHTTPStream(\r\n {\r\n url: props.url,\r\n method: props.method,\r\n headers: props.headers,\r\n body: props.body,\r\n credentials: props.credentials,\r\n autoConnect: props.autoConnect,\r\n autoReconnect: props.autoReconnect,\r\n maxReconnectAttempts: props.maxReconnectAttempts,\r\n reconnectDelay: props.reconnectDelay,\r\n ndjson: props.ndjson,\r\n },\r\n {\r\n onOpen: () => emit(\"open\"),\r\n onChunk: (data, raw) => emit(\"chunk\", data, raw),\r\n onComplete: () => emit(\"complete\"),\r\n onError: (err) => emit(\"error\", err),\r\n onProgress: (bytes) => emit(\"progress\", bytes),\r\n onReconnecting: (attempt, max) => emit(\"reconnecting\", attempt, max),\r\n onReconnected: () => emit(\"reconnected\"),\r\n onReconnectFailed: () => emit(\"reconnectFailed\"),\r\n },\r\n);\r\n\r\n// Watch for URL changes\r\nwatch(url, () => {\r\n disconnect();\r\n connect();\r\n});\r\n\r\ndefineExpose({\r\n isConnected,\r\n isStreaming,\r\n connectionState,\r\n lastChunk,\r\n chunks,\r\n bytesReceived,\r\n error,\r\n reconnectAttempts,\r\n connect,\r\n disconnect,\r\n clearChunks,\r\n});\r\n</script>\r\n\r\n<template>\r\n <slot\r\n :is-connected=\"isConnected\"\r\n :is-streaming=\"isStreaming\"\r\n :connection-state=\"connectionState\"\r\n :last-chunk=\"lastChunk\"\r\n :chunks=\"chunks\"\r\n :bytes-received=\"bytesReceived\"\r\n :error=\"error\"\r\n :reconnect-attempts=\"reconnectAttempts\"\r\n :connect=\"connect\"\r\n :disconnect=\"disconnect\"\r\n :clear-chunks=\"clearChunks\"\r\n />\r\n</template>\r\n","<script setup lang=\"ts\">\r\n/**\r\n * LaravelEchoStream - Vue component for Laravel Echo streaming\r\n * @component\r\n */\r\nimport { onMounted, toRefs, watch } from \"vue\";\r\nimport {\r\n useLaravelEcho,\r\n type ChannelWrapper,\r\n type PresenceChannelWrapper,\r\n} from \"../composables/useLaravelEcho\";\r\nimport type { LaravelEchoConfig } from \"../types\";\r\n\r\nexport interface LaravelEchoStreamProps {\r\n /** Laravel Echo configuration (used when creating a new Echo instance) */\r\n config?: LaravelEchoConfig;\r\n /** Pre-configured Echo instance (e.g. from plugins/echo.js) */\r\n echo?: unknown;\r\n /** Channel name to subscribe */\r\n channel?: string;\r\n /** Channel type */\r\n channelType?: \"public\" | \"private\" | \"presence\";\r\n /** Events to listen for on the channel */\r\n events?: string[];\r\n /** Auto-subscribe on mount */\r\n autoSubscribe?: boolean;\r\n}\r\n\r\nconst props = withDefaults(defineProps<LaravelEchoStreamProps>(), {\r\n config: () => ({}),\r\n echo: undefined,\r\n channel: undefined,\r\n channelType: \"public\",\r\n events: () => [],\r\n autoSubscribe: true,\r\n});\r\n\r\nconst emit = defineEmits<{\r\n connected: [socketId: string];\r\n event: [eventName: string, data: unknown];\r\n error: [error: Error];\r\n subscribed: [channelName: string];\r\n unsubscribed: [channelName: string];\r\n // Presence channel events\r\n here: [members: unknown[]];\r\n joining: [member: unknown];\r\n leaving: [member: unknown];\r\n}>();\r\n\r\nconst { channel: channelRef } = toRefs(props);\r\n\r\nconst {\r\n isConnected,\r\n connectionState,\r\n error,\r\n channels,\r\n channel: subscribePublic,\r\n privateChannel,\r\n presenceChannel,\r\n leave,\r\n leaveAll,\r\n connect,\r\n} = useLaravelEcho(\r\n props.config ?? {},\r\n {\r\n onConnected: (socketId) => emit(\"connected\", socketId),\r\n onError: (err) => emit(\"error\", err),\r\n },\r\n props.echo,\r\n);\r\n\r\nlet currentChannelWrapper: ChannelWrapper | PresenceChannelWrapper | null =\r\n null;\r\n\r\n// Subscribe to channel and setup event listeners\r\nfunction setupChannel() {\r\n if (!props.channel) return;\r\n\r\n if (props.channelType === \"private\") {\r\n currentChannelWrapper = privateChannel(props.channel);\r\n } else if (props.channelType === \"presence\") {\r\n const presenceWrapper = presenceChannel(props.channel);\r\n currentChannelWrapper = presenceWrapper;\r\n\r\n // Setup presence events\r\n presenceWrapper.here((members) => emit(\"here\", members as unknown[]));\r\n presenceWrapper.joining((member) => emit(\"joining\", member));\r\n presenceWrapper.leaving((member) => emit(\"leaving\", member));\r\n } else {\r\n currentChannelWrapper = subscribePublic(props.channel);\r\n }\r\n\r\n // Setup event listeners\r\n props.events.forEach((eventName) => {\r\n currentChannelWrapper?.listen(eventName, (data: unknown) => {\r\n emit(\"event\", eventName, data);\r\n });\r\n });\r\n\r\n emit(\"subscribed\", props.channel);\r\n}\r\n\r\nonMounted(async () => {\r\n await connect();\r\n if (props.autoSubscribe && props.channel && isConnected.value) {\r\n setupChannel();\r\n }\r\n});\r\n\r\n// Watch for channel changes\r\nwatch(channelRef, (newChannel, oldChannel) => {\r\n if (oldChannel) {\r\n leave(oldChannel);\r\n emit(\"unsubscribed\", oldChannel);\r\n }\r\n if (newChannel && props.autoSubscribe) {\r\n setupChannel();\r\n }\r\n});\r\n\r\ndefineExpose({\r\n isConnected,\r\n connectionState,\r\n error,\r\n channels,\r\n subscribePublic,\r\n privateChannel,\r\n presenceChannel,\r\n leave,\r\n leaveAll,\r\n connect,\r\n});\r\n</script>\r\n\r\n<template>\r\n <slot\r\n :is-connected=\"isConnected\"\r\n :connection-state=\"connectionState\"\r\n :error=\"error\"\r\n :channels=\"channels\"\r\n :active-channels=\"channels.length\"\r\n :subscribe-public=\"subscribePublic\"\r\n :private-channel=\"privateChannel\"\r\n :presence-channel=\"presenceChannel\"\r\n :leave=\"leave\"\r\n :leave-all=\"leaveAll\"\r\n />\r\n</template>\r\n","<script setup lang=\"ts\">\r\n/**\r\n * LongPollingStream - Vue component for HTTP Long Polling\r\n * @component\r\n */\r\nimport { toRefs, watch } from \"vue\";\r\nimport { useLongPolling } from \"../composables/useLongPolling\";\r\n\r\nexport interface LongPollingStreamProps {\r\n /** Polling endpoint URL */\r\n url: string;\r\n /** HTTP method */\r\n method?: \"GET\" | \"POST\";\r\n /** Request headers */\r\n headers?: Record<string, string>;\r\n /** Request body (for POST) */\r\n body?: unknown;\r\n /** Credentials mode */\r\n credentials?: RequestCredentials;\r\n /** Polling interval in ms (0 = immediate) */\r\n interval?: number;\r\n /** Request timeout in ms */\r\n timeout?: number;\r\n /** Auto-start on mount */\r\n autoStart?: boolean;\r\n /** Auto-restart on error */\r\n autoRestart?: boolean;\r\n /** Max restart attempts */\r\n maxRestartAttempts?: number;\r\n /** Restart delay in ms */\r\n restartDelay?: number;\r\n /** Include timestamp in requests */\r\n includeTimestamp?: boolean;\r\n /** Timestamp parameter name */\r\n timestampParam?: string;\r\n}\r\n\r\nconst props = withDefaults(defineProps<LongPollingStreamProps>(), {\r\n method: \"GET\",\r\n headers: () => ({}),\r\n body: undefined,\r\n credentials: \"same-origin\",\r\n interval: 0,\r\n timeout: 30000,\r\n autoStart: true,\r\n autoRestart: true,\r\n maxRestartAttempts: 5,\r\n restartDelay: 1000,\r\n includeTimestamp: false,\r\n timestampParam: \"since\",\r\n});\r\n\r\nconst emit = defineEmits<{\r\n start: [];\r\n data: [data: unknown];\r\n error: [error: Error];\r\n stop: [];\r\n restarting: [attempt: number, maxAttempts: number];\r\n restarted: [];\r\n restartFailed: [];\r\n}>();\r\n\r\nconst { url } = toRefs(props);\r\n\r\nconst {\r\n isPolling,\r\n connectionState,\r\n lastData,\r\n dataHistory,\r\n requestCount,\r\n error,\r\n restartAttempts,\r\n start,\r\n stop,\r\n poll,\r\n clearHistory,\r\n} = useLongPolling(\r\n {\r\n url: props.url,\r\n method: props.method,\r\n headers: props.headers,\r\n body: props.body,\r\n credentials: props.credentials,\r\n interval: props.interval,\r\n timeout: props.timeout,\r\n autoStart: props.autoStart,\r\n autoRestart: props.autoRestart,\r\n maxRestartAttempts: props.maxRestartAttempts,\r\n restartDelay: props.restartDelay,\r\n includeTimestamp: props.includeTimestamp,\r\n timestampParam: props.timestampParam,\r\n },\r\n {\r\n onStart: () => emit(\"start\"),\r\n onData: (data) => emit(\"data\", data),\r\n onError: (err) => emit(\"error\", err),\r\n onStop: () => emit(\"stop\"),\r\n onRestarting: (attempt, max) => emit(\"restarting\", attempt, max),\r\n onRestarted: () => emit(\"restarted\"),\r\n onRestartFailed: () => emit(\"restartFailed\"),\r\n },\r\n);\r\n\r\n// Watch for URL changes\r\nwatch(url, () => {\r\n stop();\r\n start();\r\n});\r\n\r\ndefineExpose({\r\n isPolling,\r\n connectionState,\r\n lastData,\r\n dataHistory,\r\n requestCount,\r\n error,\r\n restartAttempts,\r\n start,\r\n stop,\r\n poll,\r\n clearHistory,\r\n});\r\n</script>\r\n\r\n<template>\r\n <slot\r\n :is-polling=\"isPolling\"\r\n :connection-state=\"connectionState\"\r\n :last-data=\"lastData\"\r\n :data-history=\"dataHistory\"\r\n :request-count=\"requestCount\"\r\n :error=\"error\"\r\n :restart-attempts=\"restartAttempts\"\r\n :start=\"start\"\r\n :stop=\"stop\"\r\n :poll=\"poll\"\r\n :clear-history=\"clearHistory\"\r\n />\r\n</template>\r\n","<script setup lang=\"ts\">\r\n/**\r\n * SocketIOStream - Vue component for Socket.IO streaming\r\n * @component\r\n */\r\nimport { onMounted, toRefs, watch } from \"vue\";\r\nimport { useSocketIO } from \"../composables/useSocketIO\";\r\nimport type { SocketIOConfig } from \"../types\";\r\n\r\nexport interface SocketIOStreamProps {\r\n /** Socket.IO configuration */\r\n config: SocketIOConfig;\r\n /** Auto-connect on mount */\r\n autoConnect?: boolean;\r\n /** Events to listen for */\r\n events?: string[];\r\n}\r\n\r\nconst props = withDefaults(defineProps<SocketIOStreamProps>(), {\r\n autoConnect: true,\r\n events: () => [],\r\n});\r\n\r\nconst emit = defineEmits<{\r\n connect: [socketId: string];\r\n disconnect: [reason: string];\r\n error: [error: Error];\r\n event: [eventName: string, data: unknown];\r\n reconnecting: [attempt: number];\r\n reconnected: [];\r\n reconnectFailed: [];\r\n}>();\r\n\r\nconst { config } = toRefs(props);\r\n\r\nconst {\r\n isConnected,\r\n connectionState,\r\n socketId,\r\n rooms,\r\n error,\r\n connect,\r\n disconnect,\r\n emit: socketEmit,\r\n on,\r\n off,\r\n join,\r\n leave,\r\n} = useSocketIO(props.config, {\r\n onConnect: (id) => emit(\"connect\", id),\r\n onDisconnect: (reason) => emit(\"disconnect\", reason),\r\n onError: (err) => emit(\"error\", err),\r\n onReconnecting: (attempt) => emit(\"reconnecting\", attempt),\r\n onReconnectFailed: () => emit(\"reconnectFailed\"),\r\n});\r\n\r\n// Setup event listeners after socket is connected\r\nonMounted(async () => {\r\n if (props.autoConnect) {\r\n await connect();\r\n }\r\n // Register event listeners after connection\r\n props.events.forEach((eventName) => {\r\n on(eventName, (data: unknown) => {\r\n emit(\"event\", eventName, data);\r\n });\r\n });\r\n});\r\n\r\n// Watch for config URL changes\r\nwatch(\r\n () => config.value.url,\r\n () => {\r\n disconnect();\r\n connect();\r\n },\r\n);\r\n\r\ndefineExpose({\r\n isConnected,\r\n connectionState,\r\n socketId,\r\n rooms,\r\n error,\r\n connect,\r\n disconnect,\r\n emit: socketEmit,\r\n on,\r\n off,\r\n join,\r\n leave,\r\n});\r\n</script>\r\n\r\n<template>\r\n <slot\r\n :is-connected=\"isConnected\"\r\n :connection-state=\"connectionState\"\r\n :socket-id=\"socketId\"\r\n :rooms=\"rooms\"\r\n :error=\"error\"\r\n :connect=\"connect\"\r\n :disconnect=\"disconnect\"\r\n :emit=\"socketEmit\"\r\n :on=\"on\"\r\n :off=\"off\"\r\n :join=\"join\"\r\n :leave=\"leave\"\r\n />\r\n</template>\r\n","<script setup lang=\"ts\">\r\n/**\r\n * SSEStream - Vue component for Server-Sent Events streaming\r\n * @component\r\n */\r\nimport { toRefs, watch } from \"vue\";\r\nimport { useSSE } from \"../composables/useSSE\";\r\n\r\nexport interface SSEStreamProps {\r\n /** SSE endpoint URL */\r\n url: string;\r\n /** Enable credentials (cookies) */\r\n withCredentials?: boolean;\r\n /** Auto-connect on mount */\r\n autoConnect?: boolean;\r\n /** Auto-reconnect on error */\r\n autoReconnect?: boolean;\r\n /** Max reconnection attempts */\r\n maxReconnectAttempts?: number;\r\n /** Reconnection delay in ms */\r\n reconnectDelay?: number;\r\n /** Event types to listen for */\r\n eventTypes?: string[];\r\n}\r\n\r\nconst props = withDefaults(defineProps<SSEStreamProps>(), {\r\n withCredentials: false,\r\n autoConnect: true,\r\n autoReconnect: true,\r\n maxReconnectAttempts: 5,\r\n reconnectDelay: 1000,\r\n eventTypes: () => [\"message\"],\r\n});\r\n\r\nconst emit = defineEmits<{\r\n open: [];\r\n error: [error: Event];\r\n message: [data: unknown, event: MessageEvent];\r\n event: [eventType: string, data: unknown, event: MessageEvent];\r\n reconnecting: [attempt: number, maxAttempts: number];\r\n reconnected: [];\r\n reconnectFailed: [];\r\n}>();\r\n\r\nconst { url } = toRefs(props);\r\n\r\nconst {\r\n isConnected,\r\n connectionState,\r\n lastMessage,\r\n lastEventType,\r\n lastEventId,\r\n error,\r\n reconnectAttempts,\r\n connect,\r\n disconnect,\r\n addEventListener,\r\n removeEventListener,\r\n} = useSSE(\r\n {\r\n url: props.url,\r\n withCredentials: props.withCredentials,\r\n autoConnect: props.autoConnect,\r\n autoReconnect: props.autoReconnect,\r\n maxReconnectAttempts: props.maxReconnectAttempts,\r\n reconnectDelay: props.reconnectDelay,\r\n eventTypes: props.eventTypes,\r\n },\r\n {\r\n onOpen: () => emit(\"open\"),\r\n onError: (err) => emit(\"error\", err),\r\n onMessage: (data, event) => emit(\"message\", data, event),\r\n onEvent: (type, data, event) => emit(\"event\", type, data, event),\r\n onReconnecting: (attempt, max) => emit(\"reconnecting\", attempt, max),\r\n onReconnected: () => emit(\"reconnected\"),\r\n onReconnectFailed: () => emit(\"reconnectFailed\"),\r\n },\r\n);\r\n\r\n// Watch for URL changes\r\nwatch(url, () => {\r\n disconnect();\r\n connect();\r\n});\r\n\r\ndefineExpose({\r\n isConnected,\r\n connectionState,\r\n lastMessage,\r\n lastEventType,\r\n lastEventId,\r\n error,\r\n reconnectAttempts,\r\n connect,\r\n disconnect,\r\n addEventListener,\r\n removeEventListener,\r\n});\r\n</script>\r\n\r\n<template>\r\n <slot\r\n :is-connected=\"isConnected\"\r\n :connection-state=\"connectionState\"\r\n :last-message=\"lastMessage\"\r\n :last-event-type=\"lastEventType\"\r\n :last-event-id=\"lastEventId\"\r\n :error=\"error\"\r\n :reconnect-attempts=\"reconnectAttempts\"\r\n :connect=\"connect\"\r\n :disconnect=\"disconnect\"\r\n :add-event-listener=\"addEventListener\"\r\n :remove-event-listener=\"removeEventListener\"\r\n />\r\n</template>\r\n","<script setup lang=\"ts\">\r\n/**\r\n * WebSocketStream - Vue component for WebSocket streaming\r\n * @component\r\n */\r\nimport { toRefs, watch } from \"vue\";\r\nimport { useWebSocket } from \"../composables/useWebSocket\";\r\nimport type { WebSocketConfig } from \"../types\";\r\n\r\nexport interface WebSocketStreamProps {\r\n /** WebSocket configuration */\r\n config: WebSocketConfig;\r\n /** Auto-connect on mount */\r\n autoConnect?: boolean;\r\n}\r\n\r\nconst props = withDefaults(defineProps<WebSocketStreamProps>(), {\r\n autoConnect: true,\r\n});\r\n\r\nconst emit = defineEmits<{\r\n open: [];\r\n close: [code: number, reason: string];\r\n error: [error: Event];\r\n message: [data: unknown, event: MessageEvent];\r\n reconnecting: [attempt: number, maxAttempts: number];\r\n reconnected: [];\r\n reconnectFailed: [];\r\n}>();\r\n\r\nconst { config } = toRefs(props);\r\n\r\nconst {\r\n isConnected,\r\n connectionState,\r\n lastMessage,\r\n error,\r\n reconnectAttempts,\r\n connect,\r\n disconnect,\r\n send,\r\n sendJSON,\r\n} = useWebSocket(props.config, {\r\n onOpen: () => emit(\"open\"),\r\n onClose: (code, reason) => emit(\"close\", code, reason),\r\n onError: (err) => emit(\"error\", err),\r\n onMessage: (data, event) => emit(\"message\", data, event),\r\n onReconnecting: (attempt, max) => emit(\"reconnecting\", attempt, max),\r\n onReconnected: () => emit(\"reconnected\"),\r\n onReconnectFailed: () => emit(\"reconnectFailed\"),\r\n});\r\n\r\n// Watch for URL changes\r\nwatch(\r\n () => config.value.url,\r\n () => {\r\n disconnect();\r\n connect();\r\n },\r\n);\r\n\r\ndefineExpose({\r\n isConnected,\r\n connectionState,\r\n lastMessage,\r\n error,\r\n reconnectAttempts,\r\n connect,\r\n disconnect,\r\n send,\r\n sendJSON,\r\n});\r\n</script>\r\n\r\n<template>\r\n <slot\r\n :is-connected=\"isConnected\"\r\n :connection-state=\"connectionState\"\r\n :last-message=\"lastMessage\"\r\n :error=\"error\"\r\n :reconnect-attempts=\"reconnectAttempts\"\r\n :connect=\"connect\"\r\n :disconnect=\"disconnect\"\r\n :send=\"send\"\r\n :send-json=\"sendJSON\"\r\n />\r\n</template>\r\n"],"names":["props","__props","emit","__emit","videoRef","ref","hlsConfig","hlsCallbacks","levels","level","error","state","isPlaying","isBuffering","currentLevel","autoLevelEnabled","currentTime","duration","buffered","volume","isMuted","stats","isSupported","attach","play","pause","stop","seek","setLevel","setVolume","toggleMute","destroy","useHLS","watch","newState","time","formatTime","seconds","mins","secs","currentLevelInfo","computed","onMounted","err","newSrc","__expose","_openBlock","_createElementBlock","_hoisted_1","_createElementVNode","_hoisted_2","videoClass","controls","muted","loop","poster","_unref","_hoisted_4","_cache","_hoisted_5","_hoisted_6","_toDisplayString","_hoisted_7","_hoisted_8","$event","_Fragment","_renderList","_hoisted_10","_hoisted_11","_hoisted_12","containerRef","isLoading","THREE","scene","camera","renderer","pointsObject","animationId","resizeObserverInstance","initScene","OrbitControls","container","width","height","grid","axes","w","h","animate","e","updatePointCloud","geometry","positions","colors","i","point","color","material","center","size","cleanup","value","onUnmounted","_hoisted_3","logs","idCounter","formatData","data","detectType","addLog","type","entry","scrollToBottom","clear","togglePause","formatTimestamp","date","newData","l","_normalizeClass","paused","log","showTimestamps","status","peerConnection","mediaStream","abortController","hlsInstance","videoStyle","initWebRTC","url","cleanupWebRTC","event","offer","response","answerSdp","track","initHLS","cleanupHLS","open","_a","close","autoplay","statusMessage","config","callbacks","frame","boxes","isRunning","connectionState","dataChannels","lastPointCloudFrame","lastDetectionFrame","lastBoundingBoxes","start","sendControl","useWebRTC","_b","stateColor","showStatus","args","_renderSlot","_ctx","_hoisted_9","showStats","_hoisted_13","_hoisted_15","toRefs","buffer","bufferSize","isStreaming","itemsPerSecond","totalItems","push","getBuffer","subscribe","useDataStream","batch","isConnected","lastChunk","chunks","bytesReceived","reconnectAttempts","connect","disconnect","clearChunks","useHTTPStream","raw","bytes","attempt","max","channelRef","channels","subscribePublic","privateChannel","presenceChannel","leave","leaveAll","useLaravelEcho","socketId","currentChannelWrapper","setupChannel","presenceWrapper","members","member","eventName","newChannel","oldChannel","isPolling","lastData","dataHistory","requestCount","restartAttempts","poll","clearHistory","useLongPolling","rooms","socketEmit","on","off","join","useSocketIO","id","reason","lastMessage","lastEventType","lastEventId","addEventListener","removeEventListener","useSSE","send","sendJSON","useWebSocket","code"],"mappings":"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"}
|