@gjsify/webrtc 0.4.24 → 0.4.25

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.
@@ -0,0 +1 @@
1
+ import"../_virtual/_rolldown/runtime.js";import{Gst as e}from"../gst-init.js";import{RTCDataChannel as t}from"../rtc-data-channel.js";import{DOMException as n}from"@gjsify/dom-exception";function coerceUnsignedShort(e,t){let n=Number(t);if(!Number.isFinite(n))throw TypeError(`createDataChannel: ${e} must be a finite number, got ${String(t)}`);let r=Math.trunc(n);if(r<0||r>65535)throw TypeError(`createDataChannel: ${e}=${r} is outside the [0, 65535] range`);return r}const r={createDataChannel(r,i={}){if(this._closed)throw new n(`Cannot create a data channel on a closed RTCPeerConnection`,`InvalidStateError`);if(typeof r!=`string`)throw TypeError(`createDataChannel: label must be a string`);if(new TextEncoder().encode(r).byteLength>65535)throw TypeError(`createDataChannel: label too long (> 65535 bytes)`);let a=i.maxPacketLifeTime==null?void 0:coerceUnsignedShort(`maxPacketLifeTime`,i.maxPacketLifeTime),o=i.maxRetransmits==null?void 0:coerceUnsignedShort(`maxRetransmits`,i.maxRetransmits),s=i.id==null?void 0:coerceUnsignedShort(`id`,i.id);if(a!==void 0&&o!==void 0)throw TypeError(`createDataChannel: maxPacketLifeTime and maxRetransmits are mutually exclusive`);if(i.negotiated===!0&&s===void 0)throw TypeError(`createDataChannel: negotiated=true requires an id`);if(s===65535)throw TypeError(`createDataChannel: id 65535 is reserved`);let c=e.Structure.new_empty(`data-channel-opts`);this._setStructureField(c,`ordered`,`boolean`,i.ordered),this._setStructureField(c,`max-packet-lifetime`,`int`,a),this._setStructureField(c,`max-retransmits`,`int`,o),this._setStructureField(c,`protocol`,`string`,i.protocol),this._setStructureField(c,`negotiated`,`boolean`,i.negotiated),this._setStructureField(c,`id`,`int`,s);let l=null;try{l=this._webrtcbin.emit(`create-data-channel`,r,c)}catch(e){throw Error(`create-data-channel failed: ${e?.message??e}`)}if(!l)throw Error(`webrtcbin returned null data channel (check id/label/options)`);this._ensureSctpTransport();let u=new t(l);return this._dataChannels.set(l,u),u.addEventListener(`close`,()=>{this._dataChannels.delete(l)}),u}};function installDataChannelMethods(e){Object.assign(e,r)}export{installDataChannelMethods};
@@ -0,0 +1 @@
1
+ import"../_virtual/_rolldown/runtime.js";import{MediaStreamTrack as e}from"../media-stream-track.js";import{filterStatsByTrackId as t,parseGstStats as n}from"../gst-stats-parser.js";import{withGstPromise as r}from"../gst-utils.js";import{DOMException as i}from"@gjsify/dom-exception";const a={async getStats(a){if(this._rejectIfClosed(`getStats`),a!=null&&a instanceof e){let e=this._senders.some(e=>e.track===a),t=this._receivers.some(e=>e.track===a);if(!e&&!t)throw new i(`The selector track is not associated with a sender or receiver of this connection`,`InvalidAccessError`)}let o=n(await r(e=>{this._webrtcbin.emit(`get-stats`,null,e)}));return a!=null&&a instanceof e?t(o,a.id):o},restartIce(){this._closed||(this._iceRestartNeeded=!0,this._hasNegotiated&&Promise.resolve().then(()=>{this._closed||this._handleNegotiationNeeded()}))},setConfiguration(e){if(this._rejectIfClosed(`setConfiguration`),e.bundlePolicy&&e.bundlePolicy!==(this._conf.bundlePolicy??`balanced`))throw new i(`setConfiguration: bundlePolicy cannot be changed`,`InvalidModificationError`);if(e.rtcpMuxPolicy&&e.rtcpMuxPolicy!==(this._conf.rtcpMuxPolicy??`require`))throw new i(`setConfiguration: rtcpMuxPolicy cannot be changed`,`InvalidModificationError`);e.iceServers&&this._applyIceServers(e.iceServers),e.iceTransportPolicy&&this._applyIceTransportPolicy(e.iceTransportPolicy),this._conf={...this._conf,...e}},getConfiguration(){return{...this._conf}}};function installStatsAndConfigMethods(e){Object.assign(e,a)}export{installStatsAndConfigMethods};
@@ -0,0 +1 @@
1
+ import"../_virtual/_rolldown/runtime.js";import{MediaStreamTrack as e}from"../media-stream-track.js";import{DOMException as t}from"@gjsify/dom-exception";const n={addTrack(n,...r){if(this._rejectIfClosed(`addTrack`),!(n instanceof e))throw TypeError(`Failed to execute 'addTrack' on 'RTCPeerConnection': parameter 1 is not a MediaStreamTrack`);if(this._senders.find(e=>e.track===n))throw new t(`Track already exists in a sender of this connection`,`InvalidAccessError`);let i;for(let e of this._transceivers.values())if(e.sender.track===null&&!e.stopped&&e.direction!==`stopped`&&e.receiver.track.kind===n.kind){let t=e.direction;if(t===`recvonly`||t===`inactive`){i=e;break}}if(i){let e=i.direction;return i.direction=e===`recvonly`?`sendrecv`:`sendonly`,i.sender._setTrack(n),i.sender}return this.addTransceiver(n,{direction:`sendrecv`}).sender},removeTrack(e){if(this._rejectIfClosed(`removeTrack`),!this._senders.includes(e))throw new t(`sender was not created by this connection`,`InvalidAccessError`);e._setTrack(null)},getSenders(){return[...this._senders]},getReceivers(){return[...this._receivers]},getTransceivers(){return[...this._transceivers.values()]}};function installTrackMethods(e){Object.assign(e,n)}export{installTrackMethods};
@@ -0,0 +1 @@
1
+ import"../_virtual/_rolldown/runtime.js";import{Gst as e}from"../gst-init.js";import{MediaStreamTrack as t}from"../media-stream-track.js";import{w3cDirectionToGst as n}from"../gst-enum-maps.js";import{RTCRtpSender as r}from"../rtc-rtp-sender.js";import{RTCRtpReceiver as i}from"../rtc-rtp-receiver.js";import{RTCRtpTransceiver as a}from"../rtc-rtp-transceiver.js";const o={addTransceiver(o,s){this._rejectIfClosed(`addTransceiver`);let c;if(typeof o==`string`){if(o!==`audio`&&o!==`video`)throw TypeError(`Failed to execute 'addTransceiver' on 'RTCPeerConnection': The provided value '${o}' is not a valid enum value of type MediaStreamTrackKind.`);c=o}else if(o instanceof t)c=o.kind;else throw TypeError(`Failed to execute 'addTransceiver' on 'RTCPeerConnection': parameter 1 is not of type 'MediaStreamTrack' or a valid MediaStreamTrackKind.`);if(s?.sendEncodings){let e=new Set;for(let t of s.sendEncodings){if(t.rid!==void 0){if(typeof t.rid!=`string`||t.rid.length===0||t.rid.length>16||!/^[a-zA-Z0-9]+$/.test(t.rid))throw TypeError(`Invalid RID value: ${t.rid}`);if(e.has(t.rid))throw TypeError(`Duplicate RID: ${t.rid}`);e.add(t.rid)}if(t.scaleResolutionDownBy!==void 0&&t.scaleResolutionDownBy<1)throw RangeError(`scaleResolutionDownBy must be >= 1.0`)}}let l=s?.direction??`sendrecv`;if(![`sendrecv`,`sendonly`,`recvonly`,`inactive`].includes(l))throw TypeError(`Failed to execute 'addTransceiver' on 'RTCPeerConnection': The provided value '${l}' is not a valid enum value of type RTCRtpTransceiverDirection.`);let u=o instanceof t&&o._gstSource,d=l===`sendrecv`||l===`sendonly`,f,p;if(u&&d){let e=o,t=new r(null,this._pipeline,this._webrtcbin);t._kind=c,t._onPipelineChanged=e=>{this._pipeline=e},t._setTrack(e),t._wirePipeline(e);let s=this._findNewGstTransceiver();if(!s)throw Error(`webrtcbin did not create a transceiver for the send pad`);f=s;let u=f.receiver??null,d=new i(c,u,this._pipeline),statsDelegate=e=>this.getStats(e);t._getStatsForTrack=statsDelegate,d._getStatsForTrack=statsDelegate;let m=this._ensureTransports();t._transport=m,d._transport=m,p=new a(f,t,d),t._transceiver=p,this._transceivers.set(f,p),this._senders.push(t),this._receivers.push(d),f.direction=n(l)}else{let r=e.Caps.from_string(`application/x-rtp,media=${c}`),i=n(l===`inactive`?`sendrecv`:l),a=this._webrtcbin.emit(`add-transceiver`,i,r);if(!a)throw Error(`webrtcbin did not create a transceiver`);f=a,p=this._transceivers.get(f),p||=this._createTransceiverWrapper(f),f.direction=n(l),o instanceof t&&p.sender._setTrack(o)}return p}};function installTransceiverMethods(e){Object.assign(e,o)}export{installTransceiverMethods};
@@ -1 +1 @@
1
- import"./_virtual/_rolldown/runtime.js";import{Gst as e,ensureWebrtcbinAvailable as t}from"./gst-init.js";import{MediaStreamTrack as n}from"./media-stream-track.js";import{MediaStream as r}from"./media-stream.js";import{gstToConnectionState as i,gstToIceConnectionState as a,gstToIceGatheringState as o,gstToSignalingState as s,w3cDirectionToGst as c}from"./gst-enum-maps.js";import{filterStatsByTrackId as l,parseGstStats as u}from"./gst-stats-parser.js";import{withGstPromise as d}from"./gst-utils.js";import{asWebRtcBin as f,asWebRtcSrcPad as p}from"./internal/gst-types.js";import{RTCSessionDescription as m}from"./rtc-session-description.js";import{RTCIceCandidate as h}from"./rtc-ice-candidate.js";import{RTCDataChannelEvent as g,RTCPeerConnectionIceEvent as _}from"./rtc-events.js";import{RTCDataChannel as v}from"./rtc-data-channel.js";import{RTCRtpSender as y}from"./rtc-rtp-sender.js";import{RTCRtpReceiver as b}from"./rtc-rtp-receiver.js";import{RTCRtpTransceiver as x}from"./rtc-rtp-transceiver.js";import{RTCTrackEvent as S}from"./rtc-track-event.js";import{RTCIceTransport as C}from"./rtc-ice-transport.js";import{RTCDtlsTransport as w}from"./rtc-dtls-transport.js";import{RTCSctpTransport as T}from"./rtc-sctp-transport.js";import{RTCCertificate as E,generateCertificate as D}from"./rtc-certificate.js";import{installSdpNegotiationMethods as O}from"./rtc-peer-connection/sdp-negotiation.js";import{DOMException as k}from"@gjsify/dom-exception";import A from"gi://GLib?version=2.0";import j from"gi://GstWebRTC?version=1.0";import{WebrtcbinBridge as M}from"@gjsify/webrtc-native";import N from"gi://GObject?version=2.0";function coerceUnsignedShort(e,t){let n=Number(t);if(!Number.isFinite(n))throw TypeError(`createDataChannel: ${e} must be a finite number, got ${String(t)}`);let r=Math.trunc(n);if(r<0||r>65535)throw TypeError(`createDataChannel: ${e}=${r} is outside the [0, 65535] range`);return r}let P=0;var RTCPeerConnection=class extends EventTarget{_pipeline;_webrtcbin;_bridge;_conf;_closed=!1;_iceRestartNeeded=!1;_hasNegotiated=!1;_dataChannels=new Map;_transceivers=new Map;_senders=[];_receivers=[];_iceTransport=null;_dtlsTransport=null;_sctpTransport=null;canTrickleIceCandidates=!0;constructor(n){super(),t();let[r,i]=e.version();if(r<1||r===1&&i<20)throw new k(`@gjsify/webrtc requires GStreamer >= 1.20 (you have ${r}.${i}). webrtcbin is only stable from 1.20 onward.`,`NotSupportedError`);let a=++P;this._pipeline=new e.Pipeline({name:`gjsify-webrtc-pipeline-${a}`});let o=e.ElementFactory.make(`webrtcbin`,`gjsify-webrtcbin-${a}`);if(!o)throw Error(`Failed to create webrtcbin element`);if(this._webrtcbin=o,this._conf={...n},n?.certificates){for(let e of n.certificates)if(e instanceof E&&e.expires<=Date.now())throw new k(`RTCPeerConnection: one of the provided certificates has expired`,`InvalidAccessError`)}this._applyIceServers(n?.iceServers??[]),this._applyIceTransportPolicy(n?.iceTransportPolicy),this._applyBundlePolicy(n?.bundlePolicy),this._pipeline.add(this._webrtcbin),this._bridge=new M({bin:this._webrtcbin}),this._bridge.connect(`negotiation-needed`,()=>this._handleNegotiationNeeded()),this._bridge.connect(`icecandidate`,(e,t,n)=>this._handleIceCandidate(t,n)),this._bridge.connect(`datachannel`,(e,t)=>this._handleDataChannel(t)),this._bridge.connect(`new-transceiver`,(e,t)=>this._handleNewTransceiver(t)),this._bridge.connect(`pad-added`,(e,t)=>this._handlePadAdded(t)),this._bridge.connect(`connection-state-changed`,()=>this._dispatchStateChange(`connectionstatechange`)),this._bridge.connect(`ice-connection-state-changed`,()=>this._dispatchStateChange(`iceconnectionstatechange`)),this._bridge.connect(`ice-gathering-state-changed`,()=>this._dispatchStateChange(`icegatheringstatechange`)),this._bridge.connect(`signaling-state-changed`,()=>this._dispatchStateChange(`signalingstatechange`)),this._pipeline.set_state(e.State.PLAYING)}_applyIceServers(e){let t=!1;for(let n of e){let e=Array.isArray(n.urls)?n.urls:[n.urls];if(e.length===0)throw SyntaxError(`RTCIceServer.urls must not be empty`);for(let r of e){if(typeof r!=`string`||r.length===0)throw TypeError(`RTCIceServer.urls entries must be non-empty strings`);let e=r.indexOf(`:`);if(e<0)throw TypeError(`Invalid ICE server URL "${r}"`);let i=r.slice(0,e+1),a=r.slice(e+1);if(i===`stun:`||i===`stuns:`){if(t)continue;f(this._webrtcbin).stun_server=`${i}//${a}`,t=!0}else if(i===`turn:`||i===`turns:`){if(typeof n.username!=`string`||typeof n.credential!=`string`)throw TypeError(`TURN server credential for ${r} missing`);let e=`${i}//${encodeURIComponent(n.username)}:${encodeURIComponent(n.credential)}@${a}`;try{this._webrtcbin.emit(`add-turn-server`,e)}catch{f(this._webrtcbin).turn_server=e}}else throw TypeError(`Unsupported ICE server protocol "${i}"`)}}}_applyIceTransportPolicy(e){if(!e)return;let t=e===`relay`?j.WebRTCICETransportPolicy.RELAY:j.WebRTCICETransportPolicy.ALL;try{f(this._webrtcbin).ice_transport_policy=t}catch{}}_applyBundlePolicy(e){if(!e)return;let t;switch(e){case`balanced`:t=j.WebRTCBundlePolicy.BALANCED;break;case`max-compat`:t=j.WebRTCBundlePolicy.MAX_COMPAT;break;case`max-bundle`:t=j.WebRTCBundlePolicy.MAX_BUNDLE;break;default:return}try{f(this._webrtcbin).bundle_policy=t}catch{}}get signalingState(){if(this._closed)return`closed`;try{return s(f(this._webrtcbin).signaling_state)}catch{return`stable`}}get connectionState(){if(this._closed)return`closed`;try{return i(f(this._webrtcbin).connection_state)}catch{return`new`}}get iceConnectionState(){if(this._closed)return`closed`;try{return a(f(this._webrtcbin).ice_connection_state)}catch{return`new`}}get iceGatheringState(){try{return o(f(this._webrtcbin).ice_gathering_state)}catch{return`new`}}_descProp(e){try{let t=f(this._webrtcbin)[e];return t?m.fromGstDesc(t):null}catch{return null}}get localDescription(){return this._descProp(`local_description`)}get remoteDescription(){return this._descProp(`remote_description`)}get currentLocalDescription(){return this._descProp(`current_local_description`)}get currentRemoteDescription(){return this._descProp(`current_remote_description`)}get pendingLocalDescription(){return this._descProp(`pending_local_description`)}get pendingRemoteDescription(){return this._descProp(`pending_remote_description`)}get sctp(){return this._sctpTransport}get peerIdentity(){return Promise.reject(TypeError(`peerIdentity assertions are not implemented`))}get idpErrorInfo(){return null}get idpLoginUrl(){return null}_rejectIfClosed(e){if(this._closed)throw new k(`RTCPeerConnection.${e}: connection is closed`,`InvalidStateError`)}createDataChannel(t,n={}){if(this._closed)throw new k(`Cannot create a data channel on a closed RTCPeerConnection`,`InvalidStateError`);if(typeof t!=`string`)throw TypeError(`createDataChannel: label must be a string`);if(new TextEncoder().encode(t).byteLength>65535)throw TypeError(`createDataChannel: label too long (> 65535 bytes)`);let r=n.maxPacketLifeTime==null?void 0:coerceUnsignedShort(`maxPacketLifeTime`,n.maxPacketLifeTime),i=n.maxRetransmits==null?void 0:coerceUnsignedShort(`maxRetransmits`,n.maxRetransmits),a=n.id==null?void 0:coerceUnsignedShort(`id`,n.id);if(r!==void 0&&i!==void 0)throw TypeError(`createDataChannel: maxPacketLifeTime and maxRetransmits are mutually exclusive`);if(n.negotiated===!0&&a===void 0)throw TypeError(`createDataChannel: negotiated=true requires an id`);if(a===65535)throw TypeError(`createDataChannel: id 65535 is reserved`);let o=e.Structure.new_empty(`data-channel-opts`);this._setStructureField(o,`ordered`,`boolean`,n.ordered),this._setStructureField(o,`max-packet-lifetime`,`int`,r),this._setStructureField(o,`max-retransmits`,`int`,i),this._setStructureField(o,`protocol`,`string`,n.protocol),this._setStructureField(o,`negotiated`,`boolean`,n.negotiated),this._setStructureField(o,`id`,`int`,a);let s=null;try{s=this._webrtcbin.emit(`create-data-channel`,t,o)}catch(e){throw Error(`create-data-channel failed: ${e?.message??e}`)}if(!s)throw Error(`webrtcbin returned null data channel (check id/label/options)`);this._ensureSctpTransport();let c=new v(s);return this._dataChannels.set(s,c),c.addEventListener(`close`,()=>{this._dataChannels.delete(s)}),c}_setStructureField(e,t,n,r){if(r==null)return;let i=new N.Value;n===`boolean`?(i.init(N.TYPE_BOOLEAN),i.set_boolean(!!r)):n===`int`?(i.init(N.TYPE_INT),i.set_int(Number(r))):n===`string`&&(i.init(N.TYPE_STRING),i.set_string(String(r))),e.set_value(t,i),i.unset()}getConfiguration(){return{...this._conf}}close(){this._closed||(this._closed=!0,A.idle_add(A.PRIORITY_DEFAULT,()=>{try{this._pipeline.set_state(e.State.NULL)}catch{}for(let e of this._dataChannels.values())try{e._disconnectSignals()}catch{}this._dataChannels.clear();for(let e of this._senders)try{e._teardownPipeline()}catch{}for(let e of this._receivers)try{e._dispose()}catch{}this._transceivers.clear(),this._senders.length=0,this._receivers.length=0,this._dtlsTransport&&this._dtlsTransport._setState(`closed`),this._iceTransport&&this._iceTransport._setState(`closed`),this._sctpTransport&&this._sctpTransport._setState(`closed`);try{this._bridge.dispose_bridge()}catch{}return A.SOURCE_REMOVE}))}addTransceiver(t,r){this._rejectIfClosed(`addTransceiver`);let i;if(typeof t==`string`){if(t!==`audio`&&t!==`video`)throw TypeError(`Failed to execute 'addTransceiver' on 'RTCPeerConnection': The provided value '${t}' is not a valid enum value of type MediaStreamTrackKind.`);i=t}else if(t instanceof n)i=t.kind;else throw TypeError(`Failed to execute 'addTransceiver' on 'RTCPeerConnection': parameter 1 is not of type 'MediaStreamTrack' or a valid MediaStreamTrackKind.`);if(r?.sendEncodings){let e=new Set;for(let t of r.sendEncodings){if(t.rid!==void 0){if(typeof t.rid!=`string`||t.rid.length===0||t.rid.length>16||!/^[a-zA-Z0-9]+$/.test(t.rid))throw TypeError(`Invalid RID value: ${t.rid}`);if(e.has(t.rid))throw TypeError(`Duplicate RID: ${t.rid}`);e.add(t.rid)}if(t.scaleResolutionDownBy!==void 0&&t.scaleResolutionDownBy<1)throw RangeError(`scaleResolutionDownBy must be >= 1.0`)}}let a=r?.direction??`sendrecv`;if(![`sendrecv`,`sendonly`,`recvonly`,`inactive`].includes(a))throw TypeError(`Failed to execute 'addTransceiver' on 'RTCPeerConnection': The provided value '${a}' is not a valid enum value of type RTCRtpTransceiverDirection.`);let o=t instanceof n&&t._gstSource,s=a===`sendrecv`||a===`sendonly`,l,u;if(o&&s){let e=t,n=new y(null,this._pipeline,this._webrtcbin);n._kind=i,n._onPipelineChanged=e=>{this._pipeline=e},n._setTrack(e),n._wirePipeline(e);let r=this._findNewGstTransceiver();if(!r)throw Error(`webrtcbin did not create a transceiver for the send pad`);l=r;let o=l.receiver??null,s=new b(i,o,this._pipeline),statsDelegate=e=>this.getStats(e);n._getStatsForTrack=statsDelegate,s._getStatsForTrack=statsDelegate;let d=this._ensureTransports();n._transport=d,s._transport=d,u=new x(l,n,s),n._transceiver=u,this._transceivers.set(l,u),this._senders.push(n),this._receivers.push(s),l.direction=c(a)}else{let r=e.Caps.from_string(`application/x-rtp,media=${i}`),o=c(a===`inactive`?`sendrecv`:a),s=this._webrtcbin.emit(`add-transceiver`,o,r);if(!s)throw Error(`webrtcbin did not create a transceiver`);l=s,u=this._transceivers.get(l),u||=this._createTransceiverWrapper(l),l.direction=c(a),t instanceof n&&u.sender._setTrack(t)}return u}addTrack(e,...t){if(this._rejectIfClosed(`addTrack`),!(e instanceof n))throw TypeError(`Failed to execute 'addTrack' on 'RTCPeerConnection': parameter 1 is not a MediaStreamTrack`);if(this._senders.find(t=>t.track===e))throw new k(`Track already exists in a sender of this connection`,`InvalidAccessError`);let r;for(let t of this._transceivers.values())if(t.sender.track===null&&!t.stopped&&t.direction!==`stopped`&&t.receiver.track.kind===e.kind){let e=t.direction;if(e===`recvonly`||e===`inactive`){r=t;break}}if(r){let t=r.direction;return r.direction=t===`recvonly`?`sendrecv`:`sendonly`,r.sender._setTrack(e),r.sender}return this.addTransceiver(e,{direction:`sendrecv`}).sender}removeTrack(e){if(this._rejectIfClosed(`removeTrack`),!this._senders.includes(e))throw new k(`sender was not created by this connection`,`InvalidAccessError`);e._setTrack(null)}getSenders(){return[...this._senders]}getReceivers(){return[...this._receivers]}getTransceivers(){return[...this._transceivers.values()]}async getStats(e){if(this._rejectIfClosed(`getStats`),e!=null&&e instanceof n){let t=this._senders.some(t=>t.track===e),n=this._receivers.some(t=>t.track===e);if(!t&&!n)throw new k(`The selector track is not associated with a sender or receiver of this connection`,`InvalidAccessError`)}let t=u(await d(e=>{this._webrtcbin.emit(`get-stats`,null,e)}));return e!=null&&e instanceof n?l(t,e.id):t}restartIce(){this._closed||(this._iceRestartNeeded=!0,this._hasNegotiated&&Promise.resolve().then(()=>{this._closed||this._handleNegotiationNeeded()}))}setConfiguration(e){if(this._rejectIfClosed(`setConfiguration`),e.bundlePolicy&&e.bundlePolicy!==(this._conf.bundlePolicy??`balanced`))throw new k(`setConfiguration: bundlePolicy cannot be changed`,`InvalidModificationError`);if(e.rtcpMuxPolicy&&e.rtcpMuxPolicy!==(this._conf.rtcpMuxPolicy??`require`))throw new k(`setConfiguration: rtcpMuxPolicy cannot be changed`,`InvalidModificationError`);e.iceServers&&this._applyIceServers(e.iceServers),e.iceTransportPolicy&&this._applyIceTransportPolicy(e.iceTransportPolicy),this._conf={...this._conf,...e}}getIdentityAssertion(){return Promise.reject(Error(`getIdentityAssertion is not implemented`))}_findNewGstTransceiver(){for(let e=0;;e++){let t=this._webrtcbin.emit(`get-transceiver`,e);if(!t)return null;if(!this._transceivers.has(t))return t}}_ensureTransports(){return this._dtlsTransport||=(this._iceTransport=new C,new w(this._iceTransport)),this._dtlsTransport}_ensureSctpTransport(){if(this._sctpTransport)return;let e=this._ensureTransports();this._sctpTransport=new T(e)}_createTransceiverWrapper(e){let t=`audio`;try{e.kind===j.WebRTCKind.VIDEO&&(t=`video`)}catch{}let n=e.receiver??null,r=e.sender??null,i=new b(t,n,this._pipeline),a=new y(r,this._pipeline,this._webrtcbin);a._kind=t,a._onPipelineChanged=e=>{this._pipeline=e};let statsDelegate=e=>this.getStats(e);a._getStatsForTrack=statsDelegate,i._getStatsForTrack=statsDelegate;let o=this._ensureTransports();a._transport=o,i._transport=o;try{let t=e.mlineindex;typeof t==`number`&&t>=0&&a._setMlineIndex(t)}catch{}let s=new x(e,a,i);return a._transceiver=s,this._transceivers.set(e,s),this._senders.push(a),this._receivers.push(i),s}_handleNegotiationNeeded(){let e=new Event(`negotiationneeded`);this._onnegotiationneeded?.call(this,e),this.dispatchEvent(e)}_handleIceCandidate(e,t){let n=new _(`icecandidate`,{candidate:new h({candidate:t,sdpMLineIndex:e})});this._onicecandidate?.call(this,n),this.dispatchEvent(n)}_handleNewTransceiver(e){this._closed||this._transceivers.has(e)||this._createTransceiverWrapper(e)}_handlePadAdded(t){if(this._closed||t.direction!==e.PadDirection.SRC)return;let n=p(t).transceiver;if(!n)return;let i=this._transceivers.get(n);i||=this._createTransceiverWrapper(n),i.receiver._connectToPad(t);let a=new r([i.receiver.track]),o=new S(`track`,{receiver:i.receiver,track:i.receiver.track,streams:[a],transceiver:i});this._ontrack?.call(this,o),this.dispatchEvent(o)}_handleDataChannel(e){this._ensureSctpTransport();let t=e.channel,n=this._dataChannels.get(t);n||(n=new v(e),this._dataChannels.set(t,n),n.addEventListener(`close`,()=>{this._dataChannels.delete(t)}));let r=new g(`datachannel`,{channel:n});this._ondatachannel?.call(this,r),this.dispatchEvent(r)}_dispatchStateChange(e){e===`connectionstatechange`?this._syncDtlsState():e===`iceconnectionstatechange`?this._syncIceState():e===`icegatheringstatechange`&&this._syncIceGatheringState();let t=new Event(e);switch(e){case`connectionstatechange`:this._onconnectionstatechange?.call(this,t);break;case`iceconnectionstatechange`:this._oniceconnectionstatechange?.call(this,t);break;case`icegatheringstatechange`:this._onicegatheringstatechange?.call(this,t);break;case`signalingstatechange`:this._onsignalingstatechange?.call(this,t);break}this.dispatchEvent(t)}_syncDtlsState(){if(!this._dtlsTransport)return;let e=this.connectionState;this._dtlsTransport._setState({new:`new`,connecting:`connecting`,connected:`connected`,disconnected:`connected`,failed:`failed`,closed:`closed`}[e]??`new`),e===`connected`&&this._sctpTransport&&this._sctpTransport._setState(`connected`)}_syncIceState(){if(!this._iceTransport)return;let e=this.iceConnectionState;this._iceTransport._setState(e)}_syncIceGatheringState(){if(!this._iceTransport)return;let e=this.iceGatheringState;this._iceTransport._setGatheringState(e)}_onconnectionstatechange=null;_ondatachannel=null;_onicecandidate=null;_oniceconnectionstatechange=null;_onicegatheringstatechange=null;_onnegotiationneeded=null;_onsignalingstatechange=null;get onconnectionstatechange(){return this._onconnectionstatechange}set onconnectionstatechange(e){this._onconnectionstatechange=e}get ondatachannel(){return this._ondatachannel}set ondatachannel(e){this._ondatachannel=e}get onicecandidate(){return this._onicecandidate}set onicecandidate(e){this._onicecandidate=e}get oniceconnectionstatechange(){return this._oniceconnectionstatechange}set oniceconnectionstatechange(e){this._oniceconnectionstatechange=e}get onicegatheringstatechange(){return this._onicegatheringstatechange}set onicegatheringstatechange(e){this._onicegatheringstatechange=e}get onnegotiationneeded(){return this._onnegotiationneeded}set onnegotiationneeded(e){this._onnegotiationneeded=e}get onsignalingstatechange(){return this._onsignalingstatechange}set onsignalingstatechange(e){this._onsignalingstatechange=e}_ontrack=null;get ontrack(){return this._ontrack}set ontrack(e){this._ontrack=e}get onicecandidateerror(){return null}set onicecandidateerror(e){}static generateCertificate(e){return D(e)}};O(RTCPeerConnection.prototype);export{RTCPeerConnection};
1
+ import"./_virtual/_rolldown/runtime.js";import{Gst as e,ensureWebrtcbinAvailable as t}from"./gst-init.js";import{MediaStream as n}from"./media-stream.js";import{gstToConnectionState as r,gstToIceConnectionState as i,gstToIceGatheringState as a,gstToSignalingState as o}from"./gst-enum-maps.js";import{asWebRtcBin as s,asWebRtcSrcPad as c}from"./internal/gst-types.js";import{RTCSessionDescription as l}from"./rtc-session-description.js";import{RTCIceCandidate as u}from"./rtc-ice-candidate.js";import{RTCDataChannelEvent as d,RTCPeerConnectionIceEvent as f}from"./rtc-events.js";import{RTCDataChannel as p}from"./rtc-data-channel.js";import{RTCRtpSender as m}from"./rtc-rtp-sender.js";import{RTCRtpReceiver as h}from"./rtc-rtp-receiver.js";import{RTCRtpTransceiver as g}from"./rtc-rtp-transceiver.js";import{RTCTrackEvent as _}from"./rtc-track-event.js";import{RTCIceTransport as v}from"./rtc-ice-transport.js";import{RTCDtlsTransport as y}from"./rtc-dtls-transport.js";import{RTCSctpTransport as b}from"./rtc-sctp-transport.js";import{RTCCertificate as x,generateCertificate as S}from"./rtc-certificate.js";import{installSdpNegotiationMethods as C}from"./rtc-peer-connection/sdp-negotiation.js";import{installDataChannelMethods as w}from"./rtc-peer-connection/data-channel.js";import{installTransceiverMethods as T}from"./rtc-peer-connection/transceivers.js";import{installTrackMethods as E}from"./rtc-peer-connection/tracks.js";import{installStatsAndConfigMethods as D}from"./rtc-peer-connection/stats-and-config.js";import{DOMException as O}from"@gjsify/dom-exception";import k from"gi://GLib?version=2.0";import A from"gi://GstWebRTC?version=1.0";import{WebrtcbinBridge as j}from"@gjsify/webrtc-native";import M from"gi://GObject?version=2.0";let N=0;var RTCPeerConnection=class extends EventTarget{_pipeline;_webrtcbin;_bridge;_conf;_closed=!1;_iceRestartNeeded=!1;_hasNegotiated=!1;_dataChannels=new Map;_transceivers=new Map;_senders=[];_receivers=[];_iceTransport=null;_dtlsTransport=null;_sctpTransport=null;canTrickleIceCandidates=!0;constructor(n){super(),t();let[r,i]=e.version();if(r<1||r===1&&i<20)throw new O(`@gjsify/webrtc requires GStreamer >= 1.20 (you have ${r}.${i}). webrtcbin is only stable from 1.20 onward.`,`NotSupportedError`);let a=++N;this._pipeline=new e.Pipeline({name:`gjsify-webrtc-pipeline-${a}`});let o=e.ElementFactory.make(`webrtcbin`,`gjsify-webrtcbin-${a}`);if(!o)throw Error(`Failed to create webrtcbin element`);if(this._webrtcbin=o,this._conf={...n},n?.certificates){for(let e of n.certificates)if(e instanceof x&&e.expires<=Date.now())throw new O(`RTCPeerConnection: one of the provided certificates has expired`,`InvalidAccessError`)}this._applyIceServers(n?.iceServers??[]),this._applyIceTransportPolicy(n?.iceTransportPolicy),this._applyBundlePolicy(n?.bundlePolicy),this._pipeline.add(this._webrtcbin),this._bridge=new j({bin:this._webrtcbin}),this._bridge.connect(`negotiation-needed`,()=>this._handleNegotiationNeeded()),this._bridge.connect(`icecandidate`,(e,t,n)=>this._handleIceCandidate(t,n)),this._bridge.connect(`datachannel`,(e,t)=>this._handleDataChannel(t)),this._bridge.connect(`new-transceiver`,(e,t)=>this._handleNewTransceiver(t)),this._bridge.connect(`pad-added`,(e,t)=>this._handlePadAdded(t)),this._bridge.connect(`connection-state-changed`,()=>this._dispatchStateChange(`connectionstatechange`)),this._bridge.connect(`ice-connection-state-changed`,()=>this._dispatchStateChange(`iceconnectionstatechange`)),this._bridge.connect(`ice-gathering-state-changed`,()=>this._dispatchStateChange(`icegatheringstatechange`)),this._bridge.connect(`signaling-state-changed`,()=>this._dispatchStateChange(`signalingstatechange`)),this._pipeline.set_state(e.State.PLAYING)}_applyIceServers(e){let t=!1;for(let n of e){let e=Array.isArray(n.urls)?n.urls:[n.urls];if(e.length===0)throw SyntaxError(`RTCIceServer.urls must not be empty`);for(let r of e){if(typeof r!=`string`||r.length===0)throw TypeError(`RTCIceServer.urls entries must be non-empty strings`);let e=r.indexOf(`:`);if(e<0)throw TypeError(`Invalid ICE server URL "${r}"`);let i=r.slice(0,e+1),a=r.slice(e+1);if(i===`stun:`||i===`stuns:`){if(t)continue;s(this._webrtcbin).stun_server=`${i}//${a}`,t=!0}else if(i===`turn:`||i===`turns:`){if(typeof n.username!=`string`||typeof n.credential!=`string`)throw TypeError(`TURN server credential for ${r} missing`);let e=`${i}//${encodeURIComponent(n.username)}:${encodeURIComponent(n.credential)}@${a}`;try{this._webrtcbin.emit(`add-turn-server`,e)}catch{s(this._webrtcbin).turn_server=e}}else throw TypeError(`Unsupported ICE server protocol "${i}"`)}}}_applyIceTransportPolicy(e){if(!e)return;let t=e===`relay`?A.WebRTCICETransportPolicy.RELAY:A.WebRTCICETransportPolicy.ALL;try{s(this._webrtcbin).ice_transport_policy=t}catch{}}_applyBundlePolicy(e){if(!e)return;let t;switch(e){case`balanced`:t=A.WebRTCBundlePolicy.BALANCED;break;case`max-compat`:t=A.WebRTCBundlePolicy.MAX_COMPAT;break;case`max-bundle`:t=A.WebRTCBundlePolicy.MAX_BUNDLE;break;default:return}try{s(this._webrtcbin).bundle_policy=t}catch{}}get signalingState(){if(this._closed)return`closed`;try{return o(s(this._webrtcbin).signaling_state)}catch{return`stable`}}get connectionState(){if(this._closed)return`closed`;try{return r(s(this._webrtcbin).connection_state)}catch{return`new`}}get iceConnectionState(){if(this._closed)return`closed`;try{return i(s(this._webrtcbin).ice_connection_state)}catch{return`new`}}get iceGatheringState(){try{return a(s(this._webrtcbin).ice_gathering_state)}catch{return`new`}}_descProp(e){try{let t=s(this._webrtcbin)[e];return t?l.fromGstDesc(t):null}catch{return null}}get localDescription(){return this._descProp(`local_description`)}get remoteDescription(){return this._descProp(`remote_description`)}get currentLocalDescription(){return this._descProp(`current_local_description`)}get currentRemoteDescription(){return this._descProp(`current_remote_description`)}get pendingLocalDescription(){return this._descProp(`pending_local_description`)}get pendingRemoteDescription(){return this._descProp(`pending_remote_description`)}get sctp(){return this._sctpTransport}get peerIdentity(){return Promise.reject(TypeError(`peerIdentity assertions are not implemented`))}get idpErrorInfo(){return null}get idpLoginUrl(){return null}_rejectIfClosed(e){if(this._closed)throw new O(`RTCPeerConnection.${e}: connection is closed`,`InvalidStateError`)}_setStructureField(e,t,n,r){if(r==null)return;let i=new M.Value;n===`boolean`?(i.init(M.TYPE_BOOLEAN),i.set_boolean(!!r)):n===`int`?(i.init(M.TYPE_INT),i.set_int(Number(r))):n===`string`&&(i.init(M.TYPE_STRING),i.set_string(String(r))),e.set_value(t,i),i.unset()}close(){this._closed||(this._closed=!0,k.idle_add(k.PRIORITY_DEFAULT,()=>{try{this._pipeline.set_state(e.State.NULL)}catch{}for(let e of this._dataChannels.values())try{e._disconnectSignals()}catch{}this._dataChannels.clear();for(let e of this._senders)try{e._teardownPipeline()}catch{}for(let e of this._receivers)try{e._dispose()}catch{}this._transceivers.clear(),this._senders.length=0,this._receivers.length=0,this._dtlsTransport&&this._dtlsTransport._setState(`closed`),this._iceTransport&&this._iceTransport._setState(`closed`),this._sctpTransport&&this._sctpTransport._setState(`closed`);try{this._bridge.dispose_bridge()}catch{}return k.SOURCE_REMOVE}))}getIdentityAssertion(){return Promise.reject(Error(`getIdentityAssertion is not implemented`))}_findNewGstTransceiver(){for(let e=0;;e++){let t=this._webrtcbin.emit(`get-transceiver`,e);if(!t)return null;if(!this._transceivers.has(t))return t}}_ensureTransports(){return this._dtlsTransport||=(this._iceTransport=new v,new y(this._iceTransport)),this._dtlsTransport}_ensureSctpTransport(){if(this._sctpTransport)return;let e=this._ensureTransports();this._sctpTransport=new b(e)}_createTransceiverWrapper(e){let t=`audio`;try{e.kind===A.WebRTCKind.VIDEO&&(t=`video`)}catch{}let n=e.receiver??null,r=e.sender??null,i=new h(t,n,this._pipeline),a=new m(r,this._pipeline,this._webrtcbin);a._kind=t,a._onPipelineChanged=e=>{this._pipeline=e};let statsDelegate=e=>this.getStats(e);a._getStatsForTrack=statsDelegate,i._getStatsForTrack=statsDelegate;let o=this._ensureTransports();a._transport=o,i._transport=o;try{let t=e.mlineindex;typeof t==`number`&&t>=0&&a._setMlineIndex(t)}catch{}let s=new g(e,a,i);return a._transceiver=s,this._transceivers.set(e,s),this._senders.push(a),this._receivers.push(i),s}_handleNegotiationNeeded(){let e=new Event(`negotiationneeded`);this._onnegotiationneeded?.call(this,e),this.dispatchEvent(e)}_handleIceCandidate(e,t){let n=new f(`icecandidate`,{candidate:new u({candidate:t,sdpMLineIndex:e})});this._onicecandidate?.call(this,n),this.dispatchEvent(n)}_handleNewTransceiver(e){this._closed||this._transceivers.has(e)||this._createTransceiverWrapper(e)}_handlePadAdded(t){if(this._closed||t.direction!==e.PadDirection.SRC)return;let r=c(t).transceiver;if(!r)return;let i=this._transceivers.get(r);i||=this._createTransceiverWrapper(r),i.receiver._connectToPad(t);let a=new n([i.receiver.track]),o=new _(`track`,{receiver:i.receiver,track:i.receiver.track,streams:[a],transceiver:i});this._ontrack?.call(this,o),this.dispatchEvent(o)}_handleDataChannel(e){this._ensureSctpTransport();let t=e.channel,n=this._dataChannels.get(t);n||(n=new p(e),this._dataChannels.set(t,n),n.addEventListener(`close`,()=>{this._dataChannels.delete(t)}));let r=new d(`datachannel`,{channel:n});this._ondatachannel?.call(this,r),this.dispatchEvent(r)}_dispatchStateChange(e){e===`connectionstatechange`?this._syncDtlsState():e===`iceconnectionstatechange`?this._syncIceState():e===`icegatheringstatechange`&&this._syncIceGatheringState();let t=new Event(e);switch(e){case`connectionstatechange`:this._onconnectionstatechange?.call(this,t);break;case`iceconnectionstatechange`:this._oniceconnectionstatechange?.call(this,t);break;case`icegatheringstatechange`:this._onicegatheringstatechange?.call(this,t);break;case`signalingstatechange`:this._onsignalingstatechange?.call(this,t);break}this.dispatchEvent(t)}_syncDtlsState(){if(!this._dtlsTransport)return;let e=this.connectionState;this._dtlsTransport._setState({new:`new`,connecting:`connecting`,connected:`connected`,disconnected:`connected`,failed:`failed`,closed:`closed`}[e]??`new`),e===`connected`&&this._sctpTransport&&this._sctpTransport._setState(`connected`)}_syncIceState(){if(!this._iceTransport)return;let e=this.iceConnectionState;this._iceTransport._setState(e)}_syncIceGatheringState(){if(!this._iceTransport)return;let e=this.iceGatheringState;this._iceTransport._setGatheringState(e)}_onconnectionstatechange=null;_ondatachannel=null;_onicecandidate=null;_oniceconnectionstatechange=null;_onicegatheringstatechange=null;_onnegotiationneeded=null;_onsignalingstatechange=null;get onconnectionstatechange(){return this._onconnectionstatechange}set onconnectionstatechange(e){this._onconnectionstatechange=e}get ondatachannel(){return this._ondatachannel}set ondatachannel(e){this._ondatachannel=e}get onicecandidate(){return this._onicecandidate}set onicecandidate(e){this._onicecandidate=e}get oniceconnectionstatechange(){return this._oniceconnectionstatechange}set oniceconnectionstatechange(e){this._oniceconnectionstatechange=e}get onicegatheringstatechange(){return this._onicegatheringstatechange}set onicegatheringstatechange(e){this._onicegatheringstatechange=e}get onnegotiationneeded(){return this._onnegotiationneeded}set onnegotiationneeded(e){this._onnegotiationneeded=e}get onsignalingstatechange(){return this._onsignalingstatechange}set onsignalingstatechange(e){this._onsignalingstatechange=e}_ontrack=null;get ontrack(){return this._ontrack}set ontrack(e){this._ontrack=e}get onicecandidateerror(){return null}set onicecandidateerror(e){}static generateCertificate(e){return S(e)}};C(RTCPeerConnection.prototype),w(RTCPeerConnection.prototype),T(RTCPeerConnection.prototype),E(RTCPeerConnection.prototype),D(RTCPeerConnection.prototype);export{RTCPeerConnection};
@@ -0,0 +1,11 @@
1
+ import { RTCDataChannel } from '../rtc-data-channel.js';
2
+ import type { RTCDataChannelInit } from '../rtc-peer-connection.js';
3
+ export interface DataChannelMethods {
4
+ createDataChannel(label: string, options?: RTCDataChannelInit): RTCDataChannel;
5
+ }
6
+ declare module '../rtc-peer-connection.js' {
7
+ interface RTCPeerConnection extends DataChannelMethods {
8
+ }
9
+ }
10
+ /** Install data-channel-creation methods on RTCPeerConnection.prototype. */
11
+ export declare function installDataChannelMethods(proto: object): void;
@@ -0,0 +1,15 @@
1
+ import { MediaStreamTrack } from '../media-stream-track.js';
2
+ import type { RTCStatsReport } from '../rtc-stats-report.js';
3
+ import type { RTCConfiguration } from '../rtc-peer-connection.js';
4
+ export interface StatsAndConfigMethods {
5
+ getStats(selector?: MediaStreamTrack | null): Promise<RTCStatsReport>;
6
+ restartIce(): void;
7
+ setConfiguration(configuration: RTCConfiguration): void;
8
+ getConfiguration(): RTCConfiguration;
9
+ }
10
+ declare module '../rtc-peer-connection.js' {
11
+ interface RTCPeerConnection extends StatsAndConfigMethods {
12
+ }
13
+ }
14
+ /** Install stats + restartIce + setConfiguration / getConfiguration on RTCPeerConnection.prototype. */
15
+ export declare function installStatsAndConfigMethods(proto: object): void;
@@ -0,0 +1,18 @@
1
+ import { MediaStreamTrack } from '../media-stream-track.js';
2
+ import type { MediaStream } from '../media-stream.js';
3
+ import type { RTCRtpSender } from '../rtc-rtp-sender.js';
4
+ import type { RTCRtpReceiver } from '../rtc-rtp-receiver.js';
5
+ import type { RTCRtpTransceiver } from '../rtc-rtp-transceiver.js';
6
+ export interface TrackMethods {
7
+ addTrack(track: MediaStreamTrack, ...streams: MediaStream[]): RTCRtpSender;
8
+ removeTrack(sender: RTCRtpSender): void;
9
+ getSenders(): RTCRtpSender[];
10
+ getReceivers(): RTCRtpReceiver[];
11
+ getTransceivers(): RTCRtpTransceiver[];
12
+ }
13
+ declare module '../rtc-peer-connection.js' {
14
+ interface RTCPeerConnection extends TrackMethods {
15
+ }
16
+ }
17
+ /** Install track-management methods on RTCPeerConnection.prototype. */
18
+ export declare function installTrackMethods(proto: object): void;
@@ -0,0 +1,12 @@
1
+ import { MediaStreamTrack } from '../media-stream-track.js';
2
+ import { RTCRtpTransceiver } from '../rtc-rtp-transceiver.js';
3
+ import type { RTCRtpTransceiverInit } from '../rtc-peer-connection.js';
4
+ export interface TransceiverMethods {
5
+ addTransceiver(trackOrKind: MediaStreamTrack | string, init?: RTCRtpTransceiverInit): RTCRtpTransceiver;
6
+ }
7
+ declare module '../rtc-peer-connection.js' {
8
+ interface RTCPeerConnection extends TransceiverMethods {
9
+ }
10
+ }
11
+ /** Install transceiver-factory methods on RTCPeerConnection.prototype. */
12
+ export declare function installTransceiverMethods(proto: object): void;
@@ -1,3 +1,4 @@
1
+ import GstWebRTC from 'gi://GstWebRTC?version=1.0';
1
2
  import { Gst } from './gst-init.js';
2
3
  import { RTCSessionDescription } from './rtc-session-description.js';
3
4
  import { RTCDataChannel } from './rtc-data-channel.js';
@@ -6,9 +7,8 @@ import { RTCRtpSender, type RTCRtpTransceiverDirection } from './rtc-rtp-sender.
6
7
  import { RTCRtpReceiver } from './rtc-rtp-receiver.js';
7
8
  import { RTCRtpTransceiver } from './rtc-rtp-transceiver.js';
8
9
  import { MediaStream } from './media-stream.js';
9
- import { MediaStreamTrack } from './media-stream-track.js';
10
10
  import { RTCTrackEvent } from './rtc-track-event.js';
11
- import type { RTCStatsReport } from './rtc-stats-report.js';
11
+ import { RTCDtlsTransport } from './rtc-dtls-transport.js';
12
12
  import { RTCSctpTransport } from './rtc-sctp-transport.js';
13
13
  import { RTCCertificate, type AlgorithmIdentifier } from './rtc-certificate.js';
14
14
  export type RTCSignalingState = 'stable' | 'closed' | 'have-local-offer' | 'have-remote-offer' | 'have-local-pranswer' | 'have-remote-pranswer';
@@ -64,21 +64,21 @@ export declare class RTCPeerConnection extends EventTarget {
64
64
  _pipeline: Gst.Pipeline;
65
65
  _webrtcbin: Gst.Element;
66
66
  private _bridge;
67
- private _conf;
68
- private _closed;
67
+ _conf: RTCConfiguration;
68
+ _closed: boolean;
69
69
  _iceRestartNeeded: boolean;
70
70
  _hasNegotiated: boolean;
71
- private _dataChannels;
72
- private _transceivers;
73
- private _senders;
74
- private _receivers;
71
+ _dataChannels: Map<unknown, RTCDataChannel>;
72
+ _transceivers: Map<unknown, RTCRtpTransceiver>;
73
+ _senders: RTCRtpSender[];
74
+ _receivers: RTCRtpReceiver[];
75
75
  private _iceTransport;
76
76
  private _dtlsTransport;
77
77
  private _sctpTransport;
78
78
  readonly canTrickleIceCandidates: boolean;
79
79
  constructor(configuration?: RTCConfiguration);
80
- private _applyIceServers;
81
- private _applyIceTransportPolicy;
80
+ _applyIceServers(iceServers: RTCIceServer[]): void;
81
+ _applyIceTransportPolicy(policy?: RTCIceTransportPolicy): void;
82
82
  private _applyBundlePolicy;
83
83
  get signalingState(): RTCSignalingState;
84
84
  get connectionState(): RTCPeerConnectionState;
@@ -96,28 +96,17 @@ export declare class RTCPeerConnection extends EventTarget {
96
96
  get idpErrorInfo(): null;
97
97
  get idpLoginUrl(): null;
98
98
  _rejectIfClosed(method: string): void;
99
- createDataChannel(label: string, options?: RTCDataChannelInit): RTCDataChannel;
100
99
  _setStructureField(structure: Gst.Structure, name: string, type: 'boolean' | 'int' | 'string', value: unknown): void;
101
- getConfiguration(): RTCConfiguration;
102
100
  close(): void;
103
- addTransceiver(trackOrKind: MediaStreamTrack | string, init?: RTCRtpTransceiverInit): RTCRtpTransceiver;
104
- addTrack(track: MediaStreamTrack, ..._streams: MediaStream[]): RTCRtpSender;
105
- removeTrack(sender: RTCRtpSender): void;
106
- getSenders(): RTCRtpSender[];
107
- getReceivers(): RTCRtpReceiver[];
108
- getTransceivers(): RTCRtpTransceiver[];
109
- getStats(selector?: MediaStreamTrack | null): Promise<RTCStatsReport>;
110
- restartIce(): void;
111
- setConfiguration(configuration: RTCConfiguration): void;
112
101
  getIdentityAssertion(): Promise<never>;
113
102
  /** Find a GstWebRTCRTPTransceiver not yet in our map (created by request_pad_simple). */
114
- private _findNewGstTransceiver;
103
+ _findNewGstTransceiver(): GstWebRTC.WebRTCRTPTransceiver | null;
115
104
  /** Lazily create the shared DTLS and ICE transport instances (max-bundle → one pair). */
116
- private _ensureTransports;
105
+ _ensureTransports(): RTCDtlsTransport;
117
106
  /** Create the SCTP transport when a data channel is first negotiated. */
118
- private _ensureSctpTransport;
119
- private _createTransceiverWrapper;
120
- private _handleNegotiationNeeded;
107
+ _ensureSctpTransport(): void;
108
+ _createTransceiverWrapper(gstTrans: GstWebRTC.WebRTCRTPTransceiver): RTCRtpTransceiver;
109
+ _handleNegotiationNeeded(): void;
121
110
  private _handleIceCandidate;
122
111
  private _handleNewTransceiver;
123
112
  private _handlePadAdded;
@@ -158,5 +147,13 @@ export declare class RTCPeerConnection extends EventTarget {
158
147
  static generateCertificate(keygenAlgorithm: AlgorithmIdentifier): Promise<RTCCertificate>;
159
148
  }
160
149
  import './rtc-peer-connection/sdp-negotiation.js';
150
+ import './rtc-peer-connection/data-channel.js';
151
+ import './rtc-peer-connection/transceivers.js';
152
+ import './rtc-peer-connection/tracks.js';
153
+ import './rtc-peer-connection/stats-and-config.js';
161
154
  import './rtc-peer-connection/sdp-negotiation.js';
155
+ import './rtc-peer-connection/data-channel.js';
156
+ import './rtc-peer-connection/transceivers.js';
157
+ import './rtc-peer-connection/tracks.js';
158
+ import './rtc-peer-connection/stats-and-config.js';
162
159
  export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gjsify/webrtc",
3
- "version": "0.4.24",
3
+ "version": "0.4.25",
4
4
  "description": "W3C WebRTC API for GJS using GStreamer webrtcbin as the peer-connection backend",
5
5
  "type": "module",
6
6
  "module": "lib/esm/index.js",
@@ -58,10 +58,10 @@
58
58
  "peer-connection"
59
59
  ],
60
60
  "dependencies": {
61
- "@gjsify/buffer": "^0.4.24",
62
- "@gjsify/dom-events": "^0.4.24",
63
- "@gjsify/dom-exception": "^0.4.24",
64
- "@gjsify/webrtc-native": "^0.4.24"
61
+ "@gjsify/buffer": "^0.4.25",
62
+ "@gjsify/dom-events": "^0.4.25",
63
+ "@gjsify/dom-exception": "^0.4.25",
64
+ "@gjsify/webrtc-native": "^0.4.25"
65
65
  },
66
66
  "devDependencies": {
67
67
  "@girs/gjs": "4.0.1",
@@ -70,8 +70,8 @@
70
70
  "@girs/gst-1.0": "1.28.1-4.0.1",
71
71
  "@girs/gstsdp-1.0": "1.0.0-4.0.1",
72
72
  "@girs/gstwebrtc-1.0": "1.0.0-4.0.1",
73
- "@gjsify/cli": "^0.4.24",
74
- "@gjsify/unit": "^0.4.24",
73
+ "@gjsify/cli": "^0.4.25",
74
+ "@gjsify/unit": "^0.4.25",
75
75
  "@types/node": "^25.9.1",
76
76
  "typescript": "^6.0.3"
77
77
  }