stinky-moq-js 0.1.8 → 0.1.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +14 -14
- package/dist/index.mjs.map +1 -1
- package/dist/session.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const p=require("@kixelated/moq");class m{constructor(){this.listeners=new Map}on(t,s){this.listeners.has(t)||this.listeners.set(t,new Set),this.listeners.get(t).add(s)}off(t,s){const e=this.listeners.get(t);e&&e.delete(s)}emit(t,...s){const e=this.listeners.get(t);e&&e.forEach(o=>{try{o(...s)}catch(n){console.error("Error in event listener:",n)}})}removeAllListeners(t){t?this.listeners.delete(t):this.listeners.clear()}}var c=(r=>(r.DISCONNECTED="disconnected",r.CONNECTING="connecting",r.CONNECTED="connected",r.RECONNECTING="reconnecting",r.FAILED="failed",r))(c||{}),d=(r=>(r.IDLE="idle",r.BROADCASTING="broadcasting",r.ERROR="error",r))(d||{}),u=(r=>(r.PENDING="pending",r.SUBSCRIBED="subscribed",r.RETRYING="retrying",r.FAILED="failed",r))(u||{});class b extends m{constructor(t){super(),this.state=d.IDLE,this.bytesSent=0,this._config=t}get status(){return{state:this.state,trackName:this._config.trackName,bytesSent:this.bytesSent,lastError:this.lastError}}get config(){return{...this._config}}updateTrack(t){this.track=t,t&&this.setState(d.BROADCASTING)}async send(t,s){if(this.state!==d.BROADCASTING||!this.track)throw new Error("Broadcast is not active");try{(s||!this.group)&&(this.group&&this.group.close(),this.group=this.track.appendGroup()),await this.group.writeFrame(t),this.bytesSent+=t.length}catch(e){throw this.handleError(e),e}}async stop(){if(this.track){try{this.track.close()}catch(t){console.warn("Error closing track:",t)}this.track=void 0}this.setState(d.IDLE)}setState(t){this.state!==t&&(this.state=t,this.emit("stateChange",this.status))}handleError(t){this.lastError=t,this.setState(d.ERROR),this.emit("error",t)}dispose(){this.stop().catch(console.error),this.removeAllListeners()}}class f extends m{constructor(t){super(),this.state=u.PENDING,this.bytesReceived=0,this.retryAttempts=0,this._config=t}get status(){return{state:this.state,trackName:this._config.trackName,bytesReceived:this.bytesReceived,retryAttempts:this.retryAttempts,lastError:this.lastError}}get config(){return{...this._config}}async start(t,s){this.connection=t,this.namespace=s;try{await this.subscribe(t,s)}catch(e){this.handleError(e),this.scheduleRetry(t,s)}}async subscribe(t,s){this.setState(u.PENDING);const e=p.Path.from(s);this.broadcast=t.consume(e),this.subscription=this.broadcast.subscribe(this._config.trackName,this._config.priority||0),this.setState(u.SUBSCRIBED),this.retryAttempts=0,this.readFrames()}async readFrames(){if(this.subscription)try{for(;;){let t=0;const s=await this.subscription.nextGroup();if(!s)break;for(;;){const e=await s.readFrame();if(!e)break;t++,this.bytesReceived+=e.length;const o={trackName:this._config.trackName,data:e,timestamp:Date.now(),frameIndex:t};this.emit("data",o)}}}catch(t){this.handleError(t),this.connection&&this.namespace&&this.scheduleRetry(this.connection,this.namespace)}}scheduleRetry(t,s){var o;const e=((o=this._config.retry)==null?void 0:o.delay)||2e3;this.setState(u.RETRYING),this.retryAttempts++,this.retryTimer=setTimeout(async()=>{try{await this.subscribe(t,s)}catch(n){this.handleError(n),this.scheduleRetry(t,s)}},e)}async stop(){if(this.connection=void 0,this.namespace=void 0,this.retryTimer&&(clearTimeout(this.retryTimer),this.retryTimer=void 0),this.subscription){try{this.subscription.close()}catch(t){console.warn("Error closing subscription:",t)}this.subscription=void 0}if(this.broadcast){try{this.broadcast.close()}catch(t){console.warn("Error closing broadcast:",t)}this.broadcast=void 0}this.setState(u.PENDING)}setState(t){this.state!==t&&(this.state=t,this.emit("stateChange",this.status))}handleError(t){this.lastError=t,this.emit("error",t)}dispose(){this.stop().catch(t=>{console.warn("Error during dispose:",t)}),this.removeAllListeners()}}class y extends m{constructor(t){var s;super(),this.state=c.DISCONNECTED,this.reconnectAttempts=0,this.broadcasts=new Map,this.subscriptions=new Map,this.announcedBroadcasts=new Set,this.doReconnect=!0,this.config={...t,reconnection:{delay:Math.max(((s=t.reconnection)==null?void 0:s.delay)||1e3,1e3)},connectionTimeout:t.connectionTimeout||1e4},this.url=new URL(this.config.relayUrl)}get status(){return{state:this.state,reconnectAttempts:this.reconnectAttempts,lastError:this.lastError,connectedAt:this.connectedAt}}async connect(){if(!(this.state===c.CONNECTING||this.state===c.CONNECTED)){this.setState(c.CONNECTING);try{this.doReconnect=!0,this.connection=await p.Connection.connect(this.url,{websocket:{enabled:!1}}),this.setState(c.CONNECTED),this.connectedAt=new Date,this.reconnectAttempts=0,this.connection.closed.then(()=>{this.state===c.CONNECTED&&this.handleDisconnection()}),this.startAnnouncementDiscovery(),await this.restartBroadcasts(),await this.restartSubscriptions()}catch(t){throw this.handleError(t),this.scheduleReconnect(),t}}}async disconnect(){if(this.doReconnect=!1,this.reconnectTimer&&(clearTimeout(this.reconnectTimer),this.reconnectTimer=void 0),await this.stopAllBroadcasts(),await this.stopAllSubscriptions(),this.connection){try{this.connection.close()}catch(t){console.warn("Error closing connection:",t)}this.connection=void 0}this.setState(c.DISCONNECTED),this.connectedAt=void 0}getAllBroadcastTrackNames(){return Array.from(this.broadcasts.keys())}getAllSubscriptionTrackNames(){return Array.from(this.subscriptions.keys())}updateBroadcasts(t){const s=t.map(i=>i.trackName),e=new Set(s);if(s.length!==e.size){const i=s.filter((h,a)=>s.indexOf(h)!==a);throw new Error(`Duplicate broadcast track name: ${i[0]}`)}const o=new Set(t.map(i=>i.trackName)),n=new Set(this.broadcasts.keys());for(const i of n)o.has(i)||this._removeBroadcast(i);for(const i of t){const h=this.broadcasts.get(i.trackName);h?h.config.priority!==i.priority&&(this._removeBroadcast(i.trackName),this._createBroadcast(i)):this._createBroadcast(i)}}updateSubscriptions(t){var i,h;const s=t.map(a=>a.trackName),e=new Set(s);if(s.length!==e.size){const a=s.filter((l,E)=>s.indexOf(l)!==E);throw new Error(`Duplicate subscription track name: ${a[0]}`)}const o=new Set(t.map(a=>a.trackName)),n=new Set(this.subscriptions.keys());for(const a of n)o.has(a)||this._removeSubscription(a);for(const a of t){const l=this.subscriptions.get(a.trackName);l?(l.config.priority!==a.priority||((i=l.config.retry)==null?void 0:i.delay)!==((h=a.retry)==null?void 0:h.delay))&&(this._removeSubscription(a.trackName),this._createSubscription(a)):this._createSubscription(a)}}getAnnouncedBroadcasts(){return Array.from(this.announcedBroadcasts)}async send(t,s,e){const o=this.broadcasts.get(t);if(!o)throw new Error(`No broadcast found for track: ${t}`);await o.send(s,e)}getBroadcastStatus(t){const s=this.broadcasts.get(t);return s==null?void 0:s.status}getSubscriptionStatus(t){const s=this.subscriptions.get(t);return s==null?void 0:s.status}_createBroadcast(t){const s=new b(t);return this.broadcasts.set(t.trackName,s),s.on("stateChange",e=>{this.emit("broadcastStateChange",t.trackName,e)}),s.on("error",e=>{this.emit("broadcastError",t.trackName,e)}),this.initBroadcasting(),s}_createSubscription(t){const s=new f(t);return this.subscriptions.set(t.trackName,s),s.on("data",e=>{this.emit("data",e.trackName,e.data,e.frameIndex)}),s.on("stateChange",e=>{this.emit("subscriptionStateChange",t.trackName,e)}),s.on("error",e=>{this.emit("subscriptionError",t.trackName,e)}),this.state===c.CONNECTED&&this.connection&&s.start(this.connection,this.config.namespace).catch(e=>{console.error("Failed to start subscription:",e)}),s}_removeBroadcast(t){const s=this.broadcasts.get(t);s&&(s.stop().catch(e=>{console.warn("Error stopping broadcast:",e)}),this.broadcasts.delete(t))}_removeSubscription(t){const s=this.subscriptions.get(t);s&&(s.stop().catch(e=>{console.warn("Error stopping subscription:",e)}),this.subscriptions.delete(t))}async startAnnouncementDiscovery(){if(this.connection)try{const t=p.Path.from(this.config.namespace),s=this.connection.announced(t);this.processAnnouncements(s)}catch(t){console.error("Failed to start announcement discovery:",t)}}async processAnnouncements(t){try{for(;;){const s=await t.next();if(!s)break;s.active?(this.announcedBroadcasts.add(s.path),this.emit("broadcastAnnounced",{path:s.path,active:!0})):(this.announcedBroadcasts.delete(s.path),this.emit("broadcastAnnounced",{path:s.path,active:!1}))}}catch(s){console.error("Error processing announcements:",s)}}async restartBroadcasts(){await this.stopAllBroadcasts(),this.initBroadcasting()}initBroadcasting(){this.broadcast||this.broadcasts.size!==0&&(this.broadcast=new p.Broadcast,this.connection&&(this.connection.publish(p.Path.from(this.config.namespace),this.broadcast),this.handleTrackRequests().catch(t=>{console.error("Error handling track requests:",t)})))}async handleTrackRequests(){if(this.broadcast)try{for(;;){const t=await this.broadcast.requested();if(!t)return;const s=this.broadcasts.get(t.track.name);s&&(s.updateTrack(t.track),this.emit("trackRequested",t.track.name))}}catch(t){console.warn("Error handling track requests:",t),this.handleError(t)}}async restartSubscriptions(){if(!this.connection)return;const t=Array.from(this.subscriptions.values()).map(s=>s.start(this.connection,this.config.namespace).catch(e=>{console.error("Failed to restart subscription:",e)}));await Promise.allSettled(t)}async stopAllBroadcasts(){var s;(s=this.broadcast)==null||s.close(),this.broadcast=void 0;const t=Array.from(this.broadcasts.values()).map(e=>e.stop().catch(o=>{console.warn("Error stopping broadcast:",o)}));await Promise.allSettled(t)}async stopAllSubscriptions(){const t=Array.from(this.subscriptions.values()).map(s=>s.stop().catch(e=>{console.warn("Error stopping subscription:",e)}));await Promise.allSettled(t)}handleDisconnection(){this.setState(c.DISCONNECTED),this.scheduleReconnect()}scheduleReconnect(){var s;const t=((s=this.config.reconnection)==null?void 0:s.delay)||1e3;this.setState(c.RECONNECTING),this.reconnectAttempts++,this.reconnectTimer=setTimeout(()=>{this.doReconnect&&this.connect().catch(e=>{console.error("Reconnection failed:",e)})},t)}setState(t){this.state!==t&&(this.state=t,this.emit("stateChange",this.status))}handleError(t){this.lastError=t,this.emit("error",t)}dispose(){this.disconnect().catch(t=>{console.warn("Error during dispose:",t)}),this.removeAllListeners(),this.subscriptions.forEach(t=>t.dispose()),this.broadcasts.forEach(t=>t.dispose()),this.subscriptions.clear(),this.broadcasts.clear()}}exports.BroadcastState=d;exports.MoQBroadcast=b;exports.MoQSession=y;exports.MoQSubscription=f;exports.SessionState=c;exports.SubscriptionState=u;exports.default=y;
|
|
1
|
+
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const p=require("@kixelated/moq");class m{constructor(){this.listeners=new Map}on(t,s){this.listeners.has(t)||this.listeners.set(t,new Set),this.listeners.get(t).add(s)}off(t,s){const e=this.listeners.get(t);e&&e.delete(s)}emit(t,...s){const e=this.listeners.get(t);e&&e.forEach(o=>{try{o(...s)}catch(n){console.error("Error in event listener:",n)}})}removeAllListeners(t){t?this.listeners.delete(t):this.listeners.clear()}}var c=(r=>(r.DISCONNECTED="disconnected",r.CONNECTING="connecting",r.CONNECTED="connected",r.RECONNECTING="reconnecting",r.FAILED="failed",r))(c||{}),d=(r=>(r.IDLE="idle",r.BROADCASTING="broadcasting",r.ERROR="error",r))(d||{}),u=(r=>(r.PENDING="pending",r.SUBSCRIBED="subscribed",r.RETRYING="retrying",r.FAILED="failed",r))(u||{});class b extends m{constructor(t){super(),this.state=d.IDLE,this.bytesSent=0,this._config=t}get status(){return{state:this.state,trackName:this._config.trackName,bytesSent:this.bytesSent,lastError:this.lastError}}get config(){return{...this._config}}updateTrack(t){this.track=t,t&&this.setState(d.BROADCASTING)}async send(t,s){if(this.state!==d.BROADCASTING||!this.track)throw new Error("Broadcast is not active");try{(s||!this.group)&&(this.group&&this.group.close(),this.group=this.track.appendGroup()),await this.group.writeFrame(t),this.bytesSent+=t.length}catch(e){throw this.handleError(e),e}}async stop(){if(this.track){try{this.track.close()}catch(t){console.warn("Error closing track:",t)}this.track=void 0}this.setState(d.IDLE)}setState(t){this.state!==t&&(this.state=t,this.emit("stateChange",this.status))}handleError(t){this.lastError=t,this.setState(d.ERROR),this.emit("error",t)}dispose(){this.stop().catch(console.error),this.removeAllListeners()}}class f extends m{constructor(t){super(),this.state=u.PENDING,this.bytesReceived=0,this.retryAttempts=0,this._config=t}get status(){return{state:this.state,trackName:this._config.trackName,bytesReceived:this.bytesReceived,retryAttempts:this.retryAttempts,lastError:this.lastError}}get config(){return{...this._config}}async start(t,s){this.connection=t,this.namespace=s;try{await this.subscribe(t,s)}catch(e){this.handleError(e),this.scheduleRetry(t,s)}}async subscribe(t,s){this.setState(u.PENDING);const e=p.Path.from(s);this.broadcast=t.consume(e),this.subscription=this.broadcast.subscribe(this._config.trackName,this._config.priority||0),this.setState(u.SUBSCRIBED),this.retryAttempts=0,this.readFrames()}async readFrames(){if(this.subscription)try{for(;;){let t=0;const s=await this.subscription.nextGroup();if(!s)break;for(;;){const e=await s.readFrame();if(!e)break;t++,this.bytesReceived+=e.length;const o={trackName:this._config.trackName,data:e,timestamp:Date.now(),frameIndex:t};this.emit("data",o)}}}catch(t){this.handleError(t),this.connection&&this.namespace&&this.scheduleRetry(this.connection,this.namespace)}}scheduleRetry(t,s){var o;const e=((o=this._config.retry)==null?void 0:o.delay)||2e3;this.setState(u.RETRYING),this.retryAttempts++,this.retryTimer=setTimeout(async()=>{try{await this.subscribe(t,s)}catch(n){this.handleError(n),this.scheduleRetry(t,s)}},e)}async stop(){if(this.connection=void 0,this.namespace=void 0,this.retryTimer&&(clearTimeout(this.retryTimer),this.retryTimer=void 0),this.subscription){try{this.subscription.close()}catch(t){console.warn("Error closing subscription:",t)}this.subscription=void 0}if(this.broadcast){try{this.broadcast.close()}catch(t){console.warn("Error closing broadcast:",t)}this.broadcast=void 0}this.setState(u.PENDING)}setState(t){this.state!==t&&(this.state=t,this.emit("stateChange",this.status))}handleError(t){this.lastError=t,this.emit("error",t)}dispose(){this.stop().catch(t=>{console.warn("Error during dispose:",t)}),this.removeAllListeners()}}class E extends m{constructor(t){var s;super(),this.state=c.DISCONNECTED,this.reconnectAttempts=0,this.broadcasts=new Map,this.subscriptions=new Map,this.announcedBroadcasts=new Set,this.doReconnect=!0,this.config={...t,reconnection:{delay:Math.max(((s=t.reconnection)==null?void 0:s.delay)||1e3,1e3)},connectionTimeout:t.connectionTimeout||1e4},this.url=new URL(this.config.relayUrl)}get status(){return{state:this.state,reconnectAttempts:this.reconnectAttempts,lastError:this.lastError,connectedAt:this.connectedAt}}async connect(){if(!(this.state===c.CONNECTING||this.state===c.CONNECTED)){this.setState(c.CONNECTING);try{this.doReconnect=!0,this.connection=await p.Connection.connect(this.url,{websocket:{enabled:!1}}),this.setState(c.CONNECTED),this.connectedAt=new Date,this.reconnectAttempts=0,this.connection.closed.then(()=>{this.state===c.CONNECTED&&this.handleDisconnection()}),this.startAnnouncementDiscovery(),await this.restartBroadcasts(),await this.restartSubscriptions()}catch(t){throw this.handleError(t),this.scheduleReconnect(),t}}}async disconnect(){if(this.doReconnect=!1,this.reconnectTimer&&(clearTimeout(this.reconnectTimer),this.reconnectTimer=void 0),await this.stopAllBroadcasts(),await this.stopAllSubscriptions(),this.connection){try{this.connection.close()}catch(t){console.warn("Error closing connection:",t)}this.connection=void 0}this.setState(c.DISCONNECTED),this.connectedAt=void 0}getAllBroadcastTrackNames(){return Array.from(this.broadcasts.keys())}getAllSubscriptionTrackNames(){return Array.from(this.subscriptions.keys())}updateBroadcasts(t){const s=t.map(i=>i.trackName),e=new Set(s);if(s.length!==e.size){const i=s.filter((h,a)=>s.indexOf(h)!==a);throw new Error(`Duplicate broadcast track name: ${i[0]}`)}const o=new Set(t.map(i=>i.trackName)),n=new Set(this.broadcasts.keys());for(const i of n)o.has(i)||this._removeBroadcast(i);for(const i of t){const h=this.broadcasts.get(i.trackName);h?h.config.priority!==i.priority&&(this._removeBroadcast(i.trackName),this._createBroadcast(i)):this._createBroadcast(i)}}updateSubscriptions(t){var i,h;const s=t.map(a=>a.trackName),e=new Set(s);if(s.length!==e.size){const a=s.filter((l,y)=>s.indexOf(l)!==y);throw new Error(`Duplicate subscription track name: ${a[0]}`)}const o=new Set(t.map(a=>a.trackName)),n=new Set(this.subscriptions.keys());for(const a of n)o.has(a)||this._removeSubscription(a);for(const a of t){const l=this.subscriptions.get(a.trackName);l?(l.config.priority!==a.priority||((i=l.config.retry)==null?void 0:i.delay)!==((h=a.retry)==null?void 0:h.delay))&&(this._removeSubscription(a.trackName),this._createSubscription(a)):this._createSubscription(a)}}getAnnouncedBroadcasts(){return Array.from(this.announcedBroadcasts)}async send(t,s,e){const o=this.broadcasts.get(t);if(!o)throw new Error(`No broadcast found for track: ${t}`);await o.send(s,e)}getBroadcastStatus(t){const s=this.broadcasts.get(t);return s==null?void 0:s.status}getSubscriptionStatus(t){const s=this.subscriptions.get(t);return s==null?void 0:s.status}_createBroadcast(t){const s=new b(t);return this.broadcasts.set(t.trackName,s),s.on("stateChange",e=>{this.emit("broadcastStateChange",t.trackName,e)}),s.on("error",e=>{this.emit("broadcastError",t.trackName,e)}),this.initBroadcasting(),s}_createSubscription(t){const s=new f(t);return this.subscriptions.set(t.trackName,s),s.on("data",e=>{this.emit("data",e.trackName,e.data,e.frameIndex)}),s.on("stateChange",e=>{this.emit("subscriptionStateChange",t.trackName,e)}),s.on("error",e=>{this.emit("subscriptionError",t.trackName,e)}),this.state===c.CONNECTED&&this.connection&&s.start(this.connection,this.config.namespace).catch(e=>{console.error("Failed to start subscription:",e)}),s}_removeBroadcast(t){const s=this.broadcasts.get(t);s&&(s.stop().catch(e=>{console.warn("Error stopping broadcast:",e)}),this.broadcasts.delete(t))}_removeSubscription(t){const s=this.subscriptions.get(t);s&&(s.stop().catch(e=>{console.warn("Error stopping subscription:",e)}),this.subscriptions.delete(t))}async startAnnouncementDiscovery(){if(this.connection)try{const t=p.Path.from(this.config.namespace),s=this.connection.announced(t);this.processAnnouncements(s)}catch(t){console.error("Failed to start announcement discovery:",t)}}async processAnnouncements(t){try{for(;;){const s=await t.next();if(!s)break;s.active?(this.announcedBroadcasts.add(s.path),this.emit("broadcastAnnounced",{path:s.path,active:!0})):(this.announcedBroadcasts.delete(s.path),this.emit("broadcastAnnounced",{path:s.path,active:!1}))}}catch(s){console.error("Error processing announcements:",s)}}async restartBroadcasts(){await this.stopAllBroadcasts(),this.initBroadcasting()}initBroadcasting(){this.broadcast||this.broadcasts.size!==0&&(this.broadcast=new p.Broadcast,this.connection&&(this.connection.publish(p.Path.from(this.config.namespace),this.broadcast),this.handleTrackRequests().catch(t=>{console.error("Error handling track requests:",t)})))}async handleTrackRequests(){if(this.broadcast)try{for(;;){const t=await this.broadcast.requested();if(!t)return;const s=this.broadcasts.get(t.track.name);s&&(s.updateTrack(t.track),this.emit("trackRequested",t.track.name))}}catch(t){console.warn("Error handling track requests:",t),this.handleError(t)}}async restartSubscriptions(){if(!this.connection)return;const t=Array.from(this.subscriptions.values()).map(s=>s.start(this.connection,this.config.namespace).catch(e=>{console.error("Failed to restart subscription:",e)}));await Promise.allSettled(t)}async stopAllBroadcasts(){var s;(s=this.broadcast)==null||s.close(),this.broadcast=void 0;const t=Array.from(this.broadcasts.values()).map(e=>e.stop().catch(o=>{console.warn("Error stopping broadcast:",o)}));await Promise.allSettled(t)}async stopAllSubscriptions(){const t=Array.from(this.subscriptions.values()).map(s=>s.stop().catch(e=>{console.warn("Error stopping subscription:",e)}));await Promise.allSettled(t)}handleDisconnection(){this.setState(c.DISCONNECTED),this.scheduleReconnect()}scheduleReconnect(){var s;if(!this.config.reconnection||!this.doReconnect)return;const t=((s=this.config.reconnection)==null?void 0:s.delay)||1e3;this.setState(c.RECONNECTING),this.reconnectAttempts++,this.reconnectTimer=setTimeout(()=>{this.doReconnect&&this.state===c.RECONNECTING&&this.connect().catch(e=>{console.error("Reconnection failed:",e)})},t)}setState(t){this.state!==t&&(this.state=t,this.emit("stateChange",this.status))}handleError(t){this.lastError=t,this.emit("error",t)}dispose(){this.doReconnect=!1,this.reconnectTimer&&(clearTimeout(this.reconnectTimer),this.reconnectTimer=void 0),this.disconnect().catch(t=>{console.warn("Error during session disconnect:",t)}),this.removeAllListeners(),this.subscriptions.forEach(t=>t.dispose()),this.broadcasts.forEach(t=>t.dispose()),this.subscriptions.clear(),this.broadcasts.clear()}}exports.BroadcastState=d;exports.MoQBroadcast=b;exports.MoQSession=E;exports.MoQSubscription=f;exports.SessionState=c;exports.SubscriptionState=u;exports.default=E;
|
|
2
2
|
//# sourceMappingURL=index.cjs.map
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","sources":["../src/event-emitter.ts","../src/types.ts","../src/broadcast.ts","../src/subscription.ts","../src/session.ts"],"sourcesContent":["// Simple event emitter for type-safe events\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport class EventEmitter<T extends Record<string, (...args: any[]) => void>> {\n private listeners = new Map<keyof T, Set<T[keyof T]>>();\n\n on<K extends keyof T>(event: K, listener: T[K]): void {\n if (!this.listeners.has(event)) {\n this.listeners.set(event, new Set());\n }\n this.listeners.get(event)!.add(listener);\n }\n\n off<K extends keyof T>(event: K, listener: T[K]): void {\n const eventListeners = this.listeners.get(event);\n if (eventListeners) {\n eventListeners.delete(listener);\n }\n }\n\n emit<K extends keyof T>(event: K, ...args: Parameters<T[K]>): void {\n const eventListeners = this.listeners.get(event);\n if (eventListeners) {\n eventListeners.forEach(listener => {\n try {\n listener(...args);\n } catch (error) {\n console.error('Error in event listener:', error);\n }\n });\n }\n }\n\n removeAllListeners<K extends keyof T>(event?: K): void {\n if (event) {\n this.listeners.delete(event);\n } else {\n this.listeners.clear();\n }\n }\n}","// Types for the library\nexport interface MoQSessionConfig {\n /** URL of the MoQ relay server */\n relayUrl: string;\n /** MoQ namespace (broadcast name) */\n namespace: string;\n /** Reconnection configuration */\n reconnection?: {\n /** Delay between reconnection attempts in ms (minimum: 1000) */\n delay?: number;\n };\n /** Connection timeout in ms (default: 10000) */\n connectionTimeout?: number;\n}\n\nexport interface BroadcastConfig {\n /** Track name for the broadcast */\n trackName: string;\n /** Priority for the track (default: 0) */\n priority?: number;\n}\n\nexport interface SubscriptionConfig {\n /** Track name to subscribe to */\n trackName: string;\n /** Priority for the subscription (default: 0) */\n priority?: number;\n /** Retry configuration for failed subscriptions */\n retry?: {\n /** Delay between retry attempts in ms (default: 2000) */\n delay?: number;\n };\n}\n\nexport enum SessionState {\n DISCONNECTED = 'disconnected',\n CONNECTING = 'connecting',\n CONNECTED = 'connected',\n RECONNECTING = 'reconnecting',\n FAILED = 'failed'\n}\n\nexport enum BroadcastState {\n IDLE = 'idle',\n BROADCASTING = 'broadcasting',\n ERROR = 'error'\n}\n\nexport enum SubscriptionState {\n PENDING = 'pending',\n SUBSCRIBED = 'subscribed',\n RETRYING = 'retrying',\n FAILED = 'failed'\n}\n\nexport interface SessionStatus {\n state: SessionState;\n reconnectAttempts: number;\n lastError?: Error;\n connectedAt?: Date;\n}\n\nexport interface BroadcastStatus {\n state: BroadcastState;\n trackName: string;\n bytesSent: number;\n lastError?: Error;\n}\n\nexport interface SubscriptionStatus {\n state: SubscriptionState;\n trackName: string;\n bytesReceived: number;\n retryAttempts: number;\n lastError?: Error;\n}\n\nexport interface DataReceived {\n trackName: string;\n data: Uint8Array;\n timestamp: number;\n frameIndex: number;\n}\n\n// Event types\nexport interface BroadcastAnnouncement {\n path: string;\n active: boolean;\n}\n\nexport interface SessionEvents {\n stateChange: (status: SessionStatus) => void;\n error: (error: Error) => void;\n broadcastAnnounced: (announcement: BroadcastAnnouncement) => void;\n data: (trackName: string, data: Uint8Array, frameIndex: number) => void;\n broadcastStateChange: (trackName: string, status: BroadcastStatus) => void;\n subscriptionStateChange: (trackName: string, status: SubscriptionStatus) => void;\n broadcastError: (trackName: string, error: Error) => void;\n subscriptionError: (trackName: string, error: Error) => void;\n trackRequested: (trackName: string) => void;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n [key: string]: (...args: any[]) => void;\n}\n\nexport interface BroadcastEvents {\n stateChange: (status: BroadcastStatus) => void;\n error: (error: Error) => void;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n [key: string]: (...args: any[]) => void;\n}\n\nexport interface SubscriptionEvents {\n stateChange: (status: SubscriptionStatus) => void;\n data: (data: DataReceived) => void;\n error: (error: Error) => void;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n [key: string]: (...args: any[]) => void;\n}","import { Group, Track } from '@kixelated/moq';\nimport { EventEmitter } from './event-emitter';\nimport {\n BroadcastConfig,\n BroadcastState,\n BroadcastStatus,\n BroadcastEvents\n} from './types';\n\nexport class MoQBroadcast extends EventEmitter<BroadcastEvents> {\n private _config: BroadcastConfig;\n private state: BroadcastState = BroadcastState.IDLE;\n private bytesSent = 0;\n private lastError?: Error;\n private track?: Track;\n private group?: Group;\n\n constructor(config: BroadcastConfig) {\n super();\n this._config = config;\n }\n\n get status(): BroadcastStatus {\n return {\n state: this.state,\n trackName: this._config.trackName,\n bytesSent: this.bytesSent,\n lastError: this.lastError\n };\n }\n\n get config(): BroadcastConfig {\n return { ...this._config };\n }\n\n updateTrack(track: Track): void {\n this.track = track;\n if (track) {\n this.setState(BroadcastState.BROADCASTING);\n }\n }\n\n async send(data: Uint8Array, newGroup: boolean): Promise<void> {\n if (this.state !== BroadcastState.BROADCASTING || !this.track) {\n throw new Error('Broadcast is not active');\n }\n\n try {\n if (newGroup || !this.group) {\n if (this.group) {\n this.group.close();\n }\n this.group = this.track.appendGroup();\n }\n await this.group.writeFrame(data);\n this.bytesSent += data.length;\n } catch (error) {\n this.handleError(error as Error);\n throw error;\n }\n }\n\n async stop(): Promise<void> {\n if (this.track) {\n try {\n this.track.close();\n } catch (error) {\n console.warn('Error closing track:', error);\n }\n this.track = undefined;\n }\n \n this.setState(BroadcastState.IDLE);\n }\n\n private setState(newState: BroadcastState): void {\n if (this.state !== newState) {\n this.state = newState;\n this.emit('stateChange', this.status);\n }\n }\n\n private handleError(error: Error): void {\n this.lastError = error;\n this.setState(BroadcastState.ERROR);\n this.emit('error', error);\n }\n\n public dispose(): void {\n this.stop().catch(console.error);\n this.removeAllListeners();\n }\n}","import { Broadcast, Track, Connection, Path } from '@kixelated/moq';\nimport { EventEmitter } from './event-emitter';\nimport {\n SubscriptionConfig,\n SubscriptionState,\n SubscriptionStatus,\n SubscriptionEvents,\n DataReceived\n} from './types';\n\nexport class MoQSubscription extends EventEmitter<SubscriptionEvents> {\n private _config: SubscriptionConfig;\n private state: SubscriptionState = SubscriptionState.PENDING;\n private bytesReceived = 0;\n private retryAttempts = 0;\n private lastError?: Error;\n private subscription?: Track;\n private broadcast?: Broadcast;\n private retryTimer?: ReturnType<typeof setTimeout>;\n private connection?: Connection.Established;\n private namespace?: string;\n\n constructor(config: SubscriptionConfig) {\n super();\n this._config = config;\n }\n\n get status(): SubscriptionStatus {\n return {\n state: this.state,\n trackName: this._config.trackName,\n bytesReceived: this.bytesReceived,\n retryAttempts: this.retryAttempts,\n lastError: this.lastError\n };\n }\n\n get config(): SubscriptionConfig {\n return { ...this._config };\n }\n\n async start(connection: Connection.Established, namespace: string): Promise<void> {\n this.connection = connection;\n this.namespace = namespace;\n try {\n await this.subscribe(connection, namespace);\n } catch (error) {\n this.handleError(error as Error);\n this.scheduleRetry(connection, namespace);\n }\n }\n\n private async subscribe(connection: Connection.Established, namespace: string): Promise<void> {\n this.setState(SubscriptionState.PENDING);\n\n const broadcastPath = Path.from(namespace);\n this.broadcast = connection.consume(broadcastPath);\n\n // Subscribe to the specific track within the broadcast\n this.subscription = this.broadcast.subscribe(this._config.trackName, this._config.priority || 0);\n this.setState(SubscriptionState.SUBSCRIBED);\n this.retryAttempts = 0;\n\n // Set up data reception\n this.readFrames();\n }\n\n private async readFrames(): Promise<void> {\n if (!this.subscription) return;\n\n try {\n // eslint-disable-next-line no-constant-condition\n while (true) {\n let framesInGroup = 0;\n const group = await this.subscription.nextGroup();\n if (!group) break; // Track is closed\n\n // Read all frames from the group\n // eslint-disable-next-line no-constant-condition\n while (true) {\n const frame = await group.readFrame();\n if (!frame) break; // Group is finished\n framesInGroup++;\n\n this.bytesReceived += frame.length;\n const receivedData: DataReceived = {\n trackName: this._config.trackName,\n data: frame,\n timestamp: Date.now(),\n frameIndex: framesInGroup,\n };\n this.emit('data', receivedData);\n }\n }\n } catch (error) {\n this.handleError(error as Error);\n // Trigger retry when stream gets reset/closed\n if (this.connection && this.namespace) {\n this.scheduleRetry(this.connection, this.namespace);\n }\n }\n }\n \n private scheduleRetry(connection: Connection.Established, namespace: string): void {\n const delay = this._config.retry?.delay || 2000;\n\n this.setState(SubscriptionState.RETRYING);\n this.retryAttempts++;\n\n this.retryTimer = setTimeout(async () => {\n try {\n await this.subscribe(connection, namespace);\n } catch (error) {\n this.handleError(error as Error);\n this.scheduleRetry(connection, namespace);\n }\n }, delay);\n }\n\n async stop(): Promise<void> {\n this.connection = undefined;\n this.namespace = undefined;\n \n if (this.retryTimer) {\n clearTimeout(this.retryTimer);\n this.retryTimer = undefined;\n }\n\n if (this.subscription) {\n try {\n this.subscription.close();\n } catch (error) {\n console.warn('Error closing subscription:', error);\n }\n this.subscription = undefined;\n }\n\n if (this.broadcast) {\n try {\n this.broadcast.close();\n } catch (error) {\n console.warn('Error closing broadcast:', error);\n }\n this.broadcast = undefined;\n }\n\n this.setState(SubscriptionState.PENDING);\n }\n\n private setState(newState: SubscriptionState): void {\n if (this.state !== newState) {\n this.state = newState;\n this.emit('stateChange', this.status);\n }\n }\n\n private handleError(error: Error): void {\n this.lastError = error;\n this.emit('error', error);\n }\n\n dispose(): void {\n this.stop().catch((error) => {\n console.warn('Error during dispose:', error);\n });\n this.removeAllListeners();\n }\n}","import { Broadcast, Connection, Path } from '@kixelated/moq';\nimport { EventEmitter } from './event-emitter';\nimport { MoQBroadcast } from './broadcast';\nimport { MoQSubscription } from './subscription';\nimport {\n MoQSessionConfig,\n SessionState,\n SessionStatus,\n SessionEvents,\n BroadcastConfig,\n SubscriptionConfig\n} from './types';\n\nexport class MoQSession extends EventEmitter<SessionEvents> {\n private config: MoQSessionConfig;\n private url: URL;\n private state: SessionState = SessionState.DISCONNECTED;\n private connection?: Connection.Established;\n private reconnectAttempts = 0;\n private lastError?: Error;\n private connectedAt?: Date;\n private reconnectTimer?: ReturnType<typeof setTimeout>;\n private broadcasts = new Map<string, MoQBroadcast>();\n private subscriptions = new Map<string, MoQSubscription>();\n private announcedBroadcasts = new Set<string>();\n private doReconnect = true;\n private broadcast?: Broadcast;\n\n constructor(config: MoQSessionConfig) {\n super();\n this.config = {\n ...config,\n reconnection: {\n delay: Math.max(config.reconnection?.delay || 1000, 1000), // Enforce minimum 1 second\n },\n connectionTimeout: config.connectionTimeout || 10000\n };\n\n this.url = new URL(this.config.relayUrl);\n }\n\n get status(): SessionStatus {\n return {\n state: this.state,\n reconnectAttempts: this.reconnectAttempts,\n lastError: this.lastError,\n connectedAt: this.connectedAt\n };\n }\n\n async connect(): Promise<void> {\n if (this.state === SessionState.CONNECTING || this.state === SessionState.CONNECTED) {\n return;\n }\n\n this.setState(SessionState.CONNECTING);\n\n try {\n this.doReconnect = true;\n // Connect using the @kixelated/moq library with WebSocket fallback disabled\n this.connection = await Connection.connect(this.url, {\n websocket: {\n enabled: false // Disable WebSocket fallback\n }\n });\n\n this.setState(SessionState.CONNECTED);\n this.connectedAt = new Date();\n this.reconnectAttempts = 0;\n\n // Set up connection close handling\n this.connection.closed.then(() => {\n if (this.state === SessionState.CONNECTED) {\n this.handleDisconnection();\n }\n });\n\n // Start discovering announced broadcasts\n this.startAnnouncementDiscovery();\n\n // Restart all broadcasts and subscriptions\n await this.restartBroadcasts();\n await this.restartSubscriptions();\n\n } catch (error) {\n this.handleError(error as Error);\n this.scheduleReconnect();\n throw error;\n }\n }\n\n async disconnect(): Promise<void> {\n this.doReconnect = false;\n\n if (this.reconnectTimer) {\n clearTimeout(this.reconnectTimer);\n this.reconnectTimer = undefined;\n }\n\n // Stop all broadcasts and subscriptions\n await this.stopAllBroadcasts();\n await this.stopAllSubscriptions();\n\n if (this.connection) {\n try {\n this.connection.close();\n } catch (error) {\n console.warn('Error closing connection:', error);\n }\n this.connection = undefined;\n }\n\n this.setState(SessionState.DISCONNECTED);\n this.connectedAt = undefined;\n }\n\n /**\n * Get all active broadcast track names\n */\n getAllBroadcastTrackNames(): string[] {\n return Array.from(this.broadcasts.keys());\n }\n\n /**\n * Get all active subscription track names\n */\n getAllSubscriptionTrackNames(): string[] {\n return Array.from(this.subscriptions.keys());\n }\n\n /**\n * Declaratively update broadcasts - add, remove, or update broadcasts to match the desired state.\n * \n * @param configs Array of broadcast configurations representing the desired state\n */\n updateBroadcasts(configs: BroadcastConfig[]): void {\n // Check for duplicate track names in the input\n const trackNames = configs.map(config => config.trackName);\n const uniqueTrackNames = new Set(trackNames);\n if (trackNames.length !== uniqueTrackNames.size) {\n const duplicates = trackNames.filter((name, index) => trackNames.indexOf(name) !== index);\n throw new Error(`Duplicate broadcast track name: ${duplicates[0]}`);\n }\n\n const desiredTracks = new Set(configs.map(config => config.trackName));\n const currentTracks = new Set(this.broadcasts.keys());\n\n // Remove broadcasts that are no longer needed\n for (const trackName of currentTracks) {\n if (!desiredTracks.has(trackName)) {\n this._removeBroadcast(trackName);\n }\n }\n\n // Add new broadcasts or update existing ones\n for (const config of configs) {\n const existing = this.broadcasts.get(config.trackName);\n if (!existing) {\n // Create new broadcast\n this._createBroadcast(config);\n } else {\n // Update existing broadcast config if needed\n if (existing.config.priority !== config.priority) {\n // For now, we recreate if priority changed\n // In future, we could support dynamic priority updates\n this._removeBroadcast(config.trackName);\n this._createBroadcast(config);\n }\n }\n }\n }\n\n /**\n * Declaratively update subscriptions - add, remove, or update subscriptions to match the desired state.\n * \n * @param configs Array of subscription configurations representing the desired state\n */\n updateSubscriptions(configs: SubscriptionConfig[]): void {\n // Check for duplicate track names in the input\n const trackNames = configs.map(config => config.trackName);\n const uniqueTrackNames = new Set(trackNames);\n if (trackNames.length !== uniqueTrackNames.size) {\n const duplicates = trackNames.filter((name, index) => trackNames.indexOf(name) !== index);\n throw new Error(`Duplicate subscription track name: ${duplicates[0]}`);\n }\n\n const desiredTracks = new Set(configs.map(config => config.trackName));\n const currentTracks = new Set(this.subscriptions.keys());\n\n // Remove subscriptions that are no longer needed\n for (const trackName of currentTracks) {\n if (!desiredTracks.has(trackName)) {\n this._removeSubscription(trackName);\n }\n }\n\n // Add new subscriptions or update existing ones\n for (const config of configs) {\n const existing = this.subscriptions.get(config.trackName);\n if (!existing) {\n // Create new subscription\n this._createSubscription(config);\n } else {\n // Update existing subscription config if needed\n if (existing.config.priority !== config.priority || \n existing.config.retry?.delay !== config.retry?.delay) {\n // For now, we recreate if config changed\n // In future, we could support dynamic config updates\n this._removeSubscription(config.trackName);\n this._createSubscription(config);\n }\n }\n }\n }\n\n getAnnouncedBroadcasts(): string[] {\n return Array.from(this.announcedBroadcasts);\n }\n\n /**\n * Send data to a broadcast track\n * @param trackName Name of the track to send data to\n * @param data Binary data to send\n */\n async send(trackName: string, data: Uint8Array, newGroup: boolean): Promise<void> {\n const broadcast = this.broadcasts.get(trackName);\n if (!broadcast) {\n throw new Error(`No broadcast found for track: ${trackName}`);\n }\n await broadcast.send(data, newGroup);\n }\n\n /**\n * Get the status of a specific broadcast track\n * @param trackName Name of the track\n */\n getBroadcastStatus(trackName: string) {\n const broadcast = this.broadcasts.get(trackName);\n return broadcast?.status;\n }\n\n /**\n * Get the status of a specific subscription track\n * @param trackName Name of the track\n */\n getSubscriptionStatus(trackName: string) {\n const subscription = this.subscriptions.get(trackName);\n return subscription?.status;\n }\n\n private _createBroadcast(config: BroadcastConfig): MoQBroadcast {\n const broadcast = new MoQBroadcast(config);\n this.broadcasts.set(config.trackName, broadcast);\n\n // Forward broadcast events to session\n broadcast.on('stateChange', (status) => {\n this.emit('broadcastStateChange', config.trackName, status);\n });\n\n broadcast.on('error', (error) => {\n this.emit('broadcastError', config.trackName, error);\n });\n\n this.initBroadcasting();\n\n return broadcast;\n }\n\n private _createSubscription(config: SubscriptionConfig): MoQSubscription {\n const subscription = new MoQSubscription(config);\n this.subscriptions.set(config.trackName, subscription);\n\n // Forward subscription events to session\n subscription.on('data', (received) => {\n this.emit('data', received.trackName, received.data, received.frameIndex);\n });\n\n subscription.on('stateChange', (status) => {\n this.emit('subscriptionStateChange', config.trackName, status);\n });\n\n subscription.on('error', (error) => {\n this.emit('subscriptionError', config.trackName, error);\n });\n\n // Start subscription if we're connected\n if (this.state === SessionState.CONNECTED && this.connection) {\n subscription.start(this.connection, this.config.namespace).catch(error => {\n console.error('Failed to start subscription:', error);\n });\n }\n\n return subscription;\n }\n\n private _removeBroadcast(trackName: string): void {\n const broadcast = this.broadcasts.get(trackName);\n if (broadcast) {\n broadcast.stop().catch(error => {\n console.warn('Error stopping broadcast:', error);\n });\n this.broadcasts.delete(trackName);\n }\n }\n\n private _removeSubscription(trackName: string): void {\n const subscription = this.subscriptions.get(trackName);\n if (subscription) {\n subscription.stop().catch(error => {\n console.warn('Error stopping subscription:', error);\n });\n this.subscriptions.delete(trackName);\n }\n }\n\n private async startAnnouncementDiscovery(): Promise<void> {\n if (!this.connection) return;\n\n try {\n // Listen for announcements with our namespace as prefix\n const namespacePath = Path.from(this.config.namespace);\n const announced = this.connection.announced(namespacePath);\n \n // Process announcements in the background\n this.processAnnouncements(announced);\n \n } catch (error) {\n console.error('Failed to start announcement discovery:', error);\n }\n }\n\n private async processAnnouncements(announced: ReturnType<Connection.Established['announced']>): Promise<void> {\n try {\n for (;;) {\n const announcement = await announced.next();\n if (!announcement) break; // Announcements closed\n \n if (announcement.active) {\n this.announcedBroadcasts.add(announcement.path);\n this.emit('broadcastAnnounced', {\n path: announcement.path,\n active: true\n });\n } else {\n this.announcedBroadcasts.delete(announcement.path);\n this.emit('broadcastAnnounced', {\n path: announcement.path,\n active: false\n });\n }\n }\n } catch (error) {\n console.error('Error processing announcements:', error);\n }\n }\n\n private async restartBroadcasts(): Promise<void> {\n await this.stopAllBroadcasts();\n this.initBroadcasting();\n }\n\n private initBroadcasting(): void {\n if (this.broadcast) return;\n if (this.broadcasts.size === 0) return;\n\n this.broadcast = new Broadcast();\n if (this.connection) {\n this.connection.publish(Path.from(this.config.namespace), this.broadcast);\n this.handleTrackRequests().catch(error => {\n console.error('Error handling track requests:', error);\n });\n }\n }\n\n private async handleTrackRequests(): Promise<void> {\n if (!this.broadcast) return;\n \n try {\n for (;;) {\n const request = await this.broadcast.requested();\n if (!request) return; // No more requests, broadcast closed;\n const broadcast = this.broadcasts.get(request.track.name);\n if (broadcast) {\n broadcast.updateTrack(request.track);\n this.emit('trackRequested', request.track.name);\n }\n }\n\n } catch (error) {\n console.warn('Error handling track requests:', error);\n this.handleError(error as Error);\n }\n}\n\n private async restartSubscriptions(): Promise<void> {\n if (!this.connection) return;\n\n const promises = Array.from(this.subscriptions.values()).map(subscription => \n subscription.start(this.connection!, this.config.namespace).catch(error => {\n console.error('Failed to restart subscription:', error);\n })\n );\n\n await Promise.allSettled(promises);\n }\n\n private async stopAllBroadcasts(): Promise<void> {\n this.broadcast?.close();\n this.broadcast = undefined;\n const promises = Array.from(this.broadcasts.values()).map(broadcast => \n broadcast.stop().catch(error => {\n console.warn('Error stopping broadcast:', error);\n })\n );\n\n await Promise.allSettled(promises);\n }\n\n private async stopAllSubscriptions(): Promise<void> {\n const promises = Array.from(this.subscriptions.values()).map(subscription => \n subscription.stop().catch(error => {\n console.warn('Error stopping subscription:', error);\n })\n );\n\n await Promise.allSettled(promises);\n }\n\n private handleDisconnection(): void {\n this.setState(SessionState.DISCONNECTED);\n this.scheduleReconnect();\n }\n\n private scheduleReconnect(): void {\n const delay = this.config.reconnection?.delay || 1000;\n\n this.setState(SessionState.RECONNECTING);\n this.reconnectAttempts++;\n\n this.reconnectTimer = setTimeout(() => {\n if (!this.doReconnect) return;\n this.connect().catch(error => {\n console.error('Reconnection failed:', error);\n });\n }, delay);\n }\n\n private setState(newState: SessionState): void {\n if (this.state !== newState) {\n this.state = newState;\n this.emit('stateChange', this.status);\n }\n }\n\n private handleError(error: Error): void {\n this.lastError = error;\n this.emit('error', error);\n }\n\n public dispose(): void {\n this.disconnect().catch((error) => {\n console.warn('Error during dispose:', error);\n });\n this.removeAllListeners();\n\n this.subscriptions.forEach(sub => sub.dispose());\n this.broadcasts.forEach(bc => bc.dispose());\n this.subscriptions.clear();\n this.broadcasts.clear();\n }\n}"],"names":["EventEmitter","event","listener","eventListeners","args","error","SessionState","BroadcastState","SubscriptionState","MoQBroadcast","config","track","data","newGroup","newState","MoQSubscription","connection","namespace","broadcastPath","Path","framesInGroup","group","frame","receivedData","delay","_a","MoQSession","Connection","configs","trackNames","uniqueTrackNames","duplicates","name","index","desiredTracks","currentTracks","trackName","existing","_b","broadcast","subscription","status","received","namespacePath","announced","announcement","Broadcast","request","promises","sub","bc"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../src/event-emitter.ts","../src/types.ts","../src/broadcast.ts","../src/subscription.ts","../src/session.ts"],"sourcesContent":["// Simple event emitter for type-safe events\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport class EventEmitter<T extends Record<string, (...args: any[]) => void>> {\n private listeners = new Map<keyof T, Set<T[keyof T]>>();\n\n on<K extends keyof T>(event: K, listener: T[K]): void {\n if (!this.listeners.has(event)) {\n this.listeners.set(event, new Set());\n }\n this.listeners.get(event)!.add(listener);\n }\n\n off<K extends keyof T>(event: K, listener: T[K]): void {\n const eventListeners = this.listeners.get(event);\n if (eventListeners) {\n eventListeners.delete(listener);\n }\n }\n\n emit<K extends keyof T>(event: K, ...args: Parameters<T[K]>): void {\n const eventListeners = this.listeners.get(event);\n if (eventListeners) {\n eventListeners.forEach(listener => {\n try {\n listener(...args);\n } catch (error) {\n console.error('Error in event listener:', error);\n }\n });\n }\n }\n\n removeAllListeners<K extends keyof T>(event?: K): void {\n if (event) {\n this.listeners.delete(event);\n } else {\n this.listeners.clear();\n }\n }\n}","// Types for the library\nexport interface MoQSessionConfig {\n /** URL of the MoQ relay server */\n relayUrl: string;\n /** MoQ namespace (broadcast name) */\n namespace: string;\n /** Reconnection configuration */\n reconnection?: {\n /** Delay between reconnection attempts in ms (minimum: 1000) */\n delay?: number;\n };\n /** Connection timeout in ms (default: 10000) */\n connectionTimeout?: number;\n}\n\nexport interface BroadcastConfig {\n /** Track name for the broadcast */\n trackName: string;\n /** Priority for the track (default: 0) */\n priority?: number;\n}\n\nexport interface SubscriptionConfig {\n /** Track name to subscribe to */\n trackName: string;\n /** Priority for the subscription (default: 0) */\n priority?: number;\n /** Retry configuration for failed subscriptions */\n retry?: {\n /** Delay between retry attempts in ms (default: 2000) */\n delay?: number;\n };\n}\n\nexport enum SessionState {\n DISCONNECTED = 'disconnected',\n CONNECTING = 'connecting',\n CONNECTED = 'connected',\n RECONNECTING = 'reconnecting',\n FAILED = 'failed'\n}\n\nexport enum BroadcastState {\n IDLE = 'idle',\n BROADCASTING = 'broadcasting',\n ERROR = 'error'\n}\n\nexport enum SubscriptionState {\n PENDING = 'pending',\n SUBSCRIBED = 'subscribed',\n RETRYING = 'retrying',\n FAILED = 'failed'\n}\n\nexport interface SessionStatus {\n state: SessionState;\n reconnectAttempts: number;\n lastError?: Error;\n connectedAt?: Date;\n}\n\nexport interface BroadcastStatus {\n state: BroadcastState;\n trackName: string;\n bytesSent: number;\n lastError?: Error;\n}\n\nexport interface SubscriptionStatus {\n state: SubscriptionState;\n trackName: string;\n bytesReceived: number;\n retryAttempts: number;\n lastError?: Error;\n}\n\nexport interface DataReceived {\n trackName: string;\n data: Uint8Array;\n timestamp: number;\n frameIndex: number;\n}\n\n// Event types\nexport interface BroadcastAnnouncement {\n path: string;\n active: boolean;\n}\n\nexport interface SessionEvents {\n stateChange: (status: SessionStatus) => void;\n error: (error: Error) => void;\n broadcastAnnounced: (announcement: BroadcastAnnouncement) => void;\n data: (trackName: string, data: Uint8Array, frameIndex: number) => void;\n broadcastStateChange: (trackName: string, status: BroadcastStatus) => void;\n subscriptionStateChange: (trackName: string, status: SubscriptionStatus) => void;\n broadcastError: (trackName: string, error: Error) => void;\n subscriptionError: (trackName: string, error: Error) => void;\n trackRequested: (trackName: string) => void;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n [key: string]: (...args: any[]) => void;\n}\n\nexport interface BroadcastEvents {\n stateChange: (status: BroadcastStatus) => void;\n error: (error: Error) => void;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n [key: string]: (...args: any[]) => void;\n}\n\nexport interface SubscriptionEvents {\n stateChange: (status: SubscriptionStatus) => void;\n data: (data: DataReceived) => void;\n error: (error: Error) => void;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n [key: string]: (...args: any[]) => void;\n}","import { Group, Track } from '@kixelated/moq';\nimport { EventEmitter } from './event-emitter';\nimport {\n BroadcastConfig,\n BroadcastState,\n BroadcastStatus,\n BroadcastEvents\n} from './types';\n\nexport class MoQBroadcast extends EventEmitter<BroadcastEvents> {\n private _config: BroadcastConfig;\n private state: BroadcastState = BroadcastState.IDLE;\n private bytesSent = 0;\n private lastError?: Error;\n private track?: Track;\n private group?: Group;\n\n constructor(config: BroadcastConfig) {\n super();\n this._config = config;\n }\n\n get status(): BroadcastStatus {\n return {\n state: this.state,\n trackName: this._config.trackName,\n bytesSent: this.bytesSent,\n lastError: this.lastError\n };\n }\n\n get config(): BroadcastConfig {\n return { ...this._config };\n }\n\n updateTrack(track: Track): void {\n this.track = track;\n if (track) {\n this.setState(BroadcastState.BROADCASTING);\n }\n }\n\n async send(data: Uint8Array, newGroup: boolean): Promise<void> {\n if (this.state !== BroadcastState.BROADCASTING || !this.track) {\n throw new Error('Broadcast is not active');\n }\n\n try {\n if (newGroup || !this.group) {\n if (this.group) {\n this.group.close();\n }\n this.group = this.track.appendGroup();\n }\n await this.group.writeFrame(data);\n this.bytesSent += data.length;\n } catch (error) {\n this.handleError(error as Error);\n throw error;\n }\n }\n\n async stop(): Promise<void> {\n if (this.track) {\n try {\n this.track.close();\n } catch (error) {\n console.warn('Error closing track:', error);\n }\n this.track = undefined;\n }\n \n this.setState(BroadcastState.IDLE);\n }\n\n private setState(newState: BroadcastState): void {\n if (this.state !== newState) {\n this.state = newState;\n this.emit('stateChange', this.status);\n }\n }\n\n private handleError(error: Error): void {\n this.lastError = error;\n this.setState(BroadcastState.ERROR);\n this.emit('error', error);\n }\n\n public dispose(): void {\n this.stop().catch(console.error);\n this.removeAllListeners();\n }\n}","import { Broadcast, Track, Connection, Path } from '@kixelated/moq';\nimport { EventEmitter } from './event-emitter';\nimport {\n SubscriptionConfig,\n SubscriptionState,\n SubscriptionStatus,\n SubscriptionEvents,\n DataReceived\n} from './types';\n\nexport class MoQSubscription extends EventEmitter<SubscriptionEvents> {\n private _config: SubscriptionConfig;\n private state: SubscriptionState = SubscriptionState.PENDING;\n private bytesReceived = 0;\n private retryAttempts = 0;\n private lastError?: Error;\n private subscription?: Track;\n private broadcast?: Broadcast;\n private retryTimer?: ReturnType<typeof setTimeout>;\n private connection?: Connection.Established;\n private namespace?: string;\n\n constructor(config: SubscriptionConfig) {\n super();\n this._config = config;\n }\n\n get status(): SubscriptionStatus {\n return {\n state: this.state,\n trackName: this._config.trackName,\n bytesReceived: this.bytesReceived,\n retryAttempts: this.retryAttempts,\n lastError: this.lastError\n };\n }\n\n get config(): SubscriptionConfig {\n return { ...this._config };\n }\n\n async start(connection: Connection.Established, namespace: string): Promise<void> {\n this.connection = connection;\n this.namespace = namespace;\n try {\n await this.subscribe(connection, namespace);\n } catch (error) {\n this.handleError(error as Error);\n this.scheduleRetry(connection, namespace);\n }\n }\n\n private async subscribe(connection: Connection.Established, namespace: string): Promise<void> {\n this.setState(SubscriptionState.PENDING);\n\n const broadcastPath = Path.from(namespace);\n this.broadcast = connection.consume(broadcastPath);\n\n // Subscribe to the specific track within the broadcast\n this.subscription = this.broadcast.subscribe(this._config.trackName, this._config.priority || 0);\n this.setState(SubscriptionState.SUBSCRIBED);\n this.retryAttempts = 0;\n\n // Set up data reception\n this.readFrames();\n }\n\n private async readFrames(): Promise<void> {\n if (!this.subscription) return;\n\n try {\n // eslint-disable-next-line no-constant-condition\n while (true) {\n let framesInGroup = 0;\n const group = await this.subscription.nextGroup();\n if (!group) break; // Track is closed\n\n // Read all frames from the group\n // eslint-disable-next-line no-constant-condition\n while (true) {\n const frame = await group.readFrame();\n if (!frame) break; // Group is finished\n framesInGroup++;\n\n this.bytesReceived += frame.length;\n const receivedData: DataReceived = {\n trackName: this._config.trackName,\n data: frame,\n timestamp: Date.now(),\n frameIndex: framesInGroup,\n };\n this.emit('data', receivedData);\n }\n }\n } catch (error) {\n this.handleError(error as Error);\n // Trigger retry when stream gets reset/closed\n if (this.connection && this.namespace) {\n this.scheduleRetry(this.connection, this.namespace);\n }\n }\n }\n \n private scheduleRetry(connection: Connection.Established, namespace: string): void {\n const delay = this._config.retry?.delay || 2000;\n\n this.setState(SubscriptionState.RETRYING);\n this.retryAttempts++;\n\n this.retryTimer = setTimeout(async () => {\n try {\n await this.subscribe(connection, namespace);\n } catch (error) {\n this.handleError(error as Error);\n this.scheduleRetry(connection, namespace);\n }\n }, delay);\n }\n\n async stop(): Promise<void> {\n this.connection = undefined;\n this.namespace = undefined;\n \n if (this.retryTimer) {\n clearTimeout(this.retryTimer);\n this.retryTimer = undefined;\n }\n\n if (this.subscription) {\n try {\n this.subscription.close();\n } catch (error) {\n console.warn('Error closing subscription:', error);\n }\n this.subscription = undefined;\n }\n\n if (this.broadcast) {\n try {\n this.broadcast.close();\n } catch (error) {\n console.warn('Error closing broadcast:', error);\n }\n this.broadcast = undefined;\n }\n\n this.setState(SubscriptionState.PENDING);\n }\n\n private setState(newState: SubscriptionState): void {\n if (this.state !== newState) {\n this.state = newState;\n this.emit('stateChange', this.status);\n }\n }\n\n private handleError(error: Error): void {\n this.lastError = error;\n this.emit('error', error);\n }\n\n dispose(): void {\n this.stop().catch((error) => {\n console.warn('Error during dispose:', error);\n });\n this.removeAllListeners();\n }\n}","import { Broadcast, Connection, Path } from '@kixelated/moq';\nimport { EventEmitter } from './event-emitter';\nimport { MoQBroadcast } from './broadcast';\nimport { MoQSubscription } from './subscription';\nimport {\n MoQSessionConfig,\n SessionState,\n SessionStatus,\n SessionEvents,\n BroadcastConfig,\n SubscriptionConfig\n} from './types';\n\nexport class MoQSession extends EventEmitter<SessionEvents> {\n private config: MoQSessionConfig;\n private url: URL;\n private state: SessionState = SessionState.DISCONNECTED;\n private connection?: Connection.Established;\n private reconnectAttempts = 0;\n private lastError?: Error;\n private connectedAt?: Date;\n private reconnectTimer?: ReturnType<typeof setTimeout>;\n private broadcasts = new Map<string, MoQBroadcast>();\n private subscriptions = new Map<string, MoQSubscription>();\n private announcedBroadcasts = new Set<string>();\n private doReconnect = true;\n private broadcast?: Broadcast;\n\n constructor(config: MoQSessionConfig) {\n super();\n this.config = {\n ...config,\n reconnection: {\n delay: Math.max(config.reconnection?.delay || 1000, 1000), // Enforce minimum 1 second\n },\n connectionTimeout: config.connectionTimeout || 10000\n };\n\n this.url = new URL(this.config.relayUrl);\n }\n\n get status(): SessionStatus {\n return {\n state: this.state,\n reconnectAttempts: this.reconnectAttempts,\n lastError: this.lastError,\n connectedAt: this.connectedAt\n };\n }\n\n async connect(): Promise<void> {\n if (this.state === SessionState.CONNECTING || this.state === SessionState.CONNECTED) {\n return;\n }\n\n this.setState(SessionState.CONNECTING);\n\n try {\n this.doReconnect = true;\n this.connection = await Connection.connect(this.url, {\n websocket: {\n enabled: false\n }\n });\n\n this.setState(SessionState.CONNECTED);\n this.connectedAt = new Date();\n this.reconnectAttempts = 0;\n\n // Set up connection close handling\n this.connection.closed.then(() => {\n if (this.state === SessionState.CONNECTED) {\n this.handleDisconnection();\n }\n });\n\n // Start discovering announced broadcasts\n this.startAnnouncementDiscovery();\n\n // Restart all broadcasts and subscriptions\n await this.restartBroadcasts();\n await this.restartSubscriptions();\n\n } catch (error) {\n this.handleError(error as Error);\n this.scheduleReconnect();\n throw error;\n }\n }\n\n async disconnect(): Promise<void> {\n this.doReconnect = false;\n\n if (this.reconnectTimer) {\n clearTimeout(this.reconnectTimer);\n this.reconnectTimer = undefined;\n }\n\n // Stop all broadcasts and subscriptions\n await this.stopAllBroadcasts();\n await this.stopAllSubscriptions();\n\n if (this.connection) {\n try {\n this.connection.close();\n } catch (error) {\n console.warn('Error closing connection:', error);\n }\n this.connection = undefined;\n }\n\n this.setState(SessionState.DISCONNECTED);\n this.connectedAt = undefined;\n }\n\n /**\n * Get all active broadcast track names\n */\n getAllBroadcastTrackNames(): string[] {\n return Array.from(this.broadcasts.keys());\n }\n\n /**\n * Get all active subscription track names\n */\n getAllSubscriptionTrackNames(): string[] {\n return Array.from(this.subscriptions.keys());\n }\n\n /**\n * Declaratively update broadcasts - add, remove, or update broadcasts to match the desired state.\n * \n * @param configs Array of broadcast configurations representing the desired state\n */\n updateBroadcasts(configs: BroadcastConfig[]): void {\n // Check for duplicate track names in the input\n const trackNames = configs.map(config => config.trackName);\n const uniqueTrackNames = new Set(trackNames);\n if (trackNames.length !== uniqueTrackNames.size) {\n const duplicates = trackNames.filter((name, index) => trackNames.indexOf(name) !== index);\n throw new Error(`Duplicate broadcast track name: ${duplicates[0]}`);\n }\n\n const desiredTracks = new Set(configs.map(config => config.trackName));\n const currentTracks = new Set(this.broadcasts.keys());\n\n // Remove broadcasts that are no longer needed\n for (const trackName of currentTracks) {\n if (!desiredTracks.has(trackName)) {\n this._removeBroadcast(trackName);\n }\n }\n\n // Add new broadcasts or update existing ones\n for (const config of configs) {\n const existing = this.broadcasts.get(config.trackName);\n if (!existing) {\n // Create new broadcast\n this._createBroadcast(config);\n } else {\n // Update existing broadcast config if needed\n if (existing.config.priority !== config.priority) {\n // For now, we recreate if priority changed\n // In future, we could support dynamic priority updates\n this._removeBroadcast(config.trackName);\n this._createBroadcast(config);\n }\n }\n }\n }\n\n /**\n * Declaratively update subscriptions - add, remove, or update subscriptions to match the desired state.\n * \n * @param configs Array of subscription configurations representing the desired state\n */\n updateSubscriptions(configs: SubscriptionConfig[]): void {\n // Check for duplicate track names in the input\n const trackNames = configs.map(config => config.trackName);\n const uniqueTrackNames = new Set(trackNames);\n if (trackNames.length !== uniqueTrackNames.size) {\n const duplicates = trackNames.filter((name, index) => trackNames.indexOf(name) !== index);\n throw new Error(`Duplicate subscription track name: ${duplicates[0]}`);\n }\n\n const desiredTracks = new Set(configs.map(config => config.trackName));\n const currentTracks = new Set(this.subscriptions.keys());\n\n // Remove subscriptions that are no longer needed\n for (const trackName of currentTracks) {\n if (!desiredTracks.has(trackName)) {\n this._removeSubscription(trackName);\n }\n }\n\n // Add new subscriptions or update existing ones\n for (const config of configs) {\n const existing = this.subscriptions.get(config.trackName);\n if (!existing) {\n // Create new subscription\n this._createSubscription(config);\n } else {\n // Update existing subscription config if needed\n if (existing.config.priority !== config.priority || \n existing.config.retry?.delay !== config.retry?.delay) {\n // For now, we recreate if config changed\n // In future, we could support dynamic config updates\n this._removeSubscription(config.trackName);\n this._createSubscription(config);\n }\n }\n }\n }\n\n getAnnouncedBroadcasts(): string[] {\n return Array.from(this.announcedBroadcasts);\n }\n\n /**\n * Send data to a broadcast track\n * @param trackName Name of the track to send data to\n * @param data Binary data to send\n */\n async send(trackName: string, data: Uint8Array, newGroup: boolean): Promise<void> {\n const broadcast = this.broadcasts.get(trackName);\n if (!broadcast) {\n throw new Error(`No broadcast found for track: ${trackName}`);\n }\n await broadcast.send(data, newGroup);\n }\n\n /**\n * Get the status of a specific broadcast track\n * @param trackName Name of the track\n */\n getBroadcastStatus(trackName: string) {\n const broadcast = this.broadcasts.get(trackName);\n return broadcast?.status;\n }\n\n /**\n * Get the status of a specific subscription track\n * @param trackName Name of the track\n */\n getSubscriptionStatus(trackName: string) {\n const subscription = this.subscriptions.get(trackName);\n return subscription?.status;\n }\n\n private _createBroadcast(config: BroadcastConfig): MoQBroadcast {\n const broadcast = new MoQBroadcast(config);\n this.broadcasts.set(config.trackName, broadcast);\n\n // Forward broadcast events to session\n broadcast.on('stateChange', (status) => {\n this.emit('broadcastStateChange', config.trackName, status);\n });\n\n broadcast.on('error', (error) => {\n this.emit('broadcastError', config.trackName, error);\n });\n\n this.initBroadcasting();\n\n return broadcast;\n }\n\n private _createSubscription(config: SubscriptionConfig): MoQSubscription {\n const subscription = new MoQSubscription(config);\n this.subscriptions.set(config.trackName, subscription);\n\n // Forward subscription events to session\n subscription.on('data', (received) => {\n this.emit('data', received.trackName, received.data, received.frameIndex);\n });\n\n subscription.on('stateChange', (status) => {\n this.emit('subscriptionStateChange', config.trackName, status);\n });\n\n subscription.on('error', (error) => {\n this.emit('subscriptionError', config.trackName, error);\n });\n\n // Start subscription if we're connected\n if (this.state === SessionState.CONNECTED && this.connection) {\n subscription.start(this.connection, this.config.namespace).catch(error => {\n console.error('Failed to start subscription:', error);\n });\n }\n\n return subscription;\n }\n\n private _removeBroadcast(trackName: string): void {\n const broadcast = this.broadcasts.get(trackName);\n if (broadcast) {\n broadcast.stop().catch(error => {\n console.warn('Error stopping broadcast:', error);\n });\n this.broadcasts.delete(trackName);\n }\n }\n\n private _removeSubscription(trackName: string): void {\n const subscription = this.subscriptions.get(trackName);\n if (subscription) {\n subscription.stop().catch(error => {\n console.warn('Error stopping subscription:', error);\n });\n this.subscriptions.delete(trackName);\n }\n }\n\n private async startAnnouncementDiscovery(): Promise<void> {\n if (!this.connection) return;\n\n try {\n // Listen for announcements with our namespace as prefix\n const namespacePath = Path.from(this.config.namespace);\n const announced = this.connection.announced(namespacePath);\n \n // Process announcements in the background\n this.processAnnouncements(announced);\n \n } catch (error) {\n console.error('Failed to start announcement discovery:', error);\n }\n }\n\n private async processAnnouncements(announced: ReturnType<Connection.Established['announced']>): Promise<void> {\n try {\n for (;;) {\n const announcement = await announced.next();\n if (!announcement) break; // Announcements closed\n \n if (announcement.active) {\n this.announcedBroadcasts.add(announcement.path);\n this.emit('broadcastAnnounced', {\n path: announcement.path,\n active: true\n });\n } else {\n this.announcedBroadcasts.delete(announcement.path);\n this.emit('broadcastAnnounced', {\n path: announcement.path,\n active: false\n });\n }\n }\n } catch (error) {\n console.error('Error processing announcements:', error);\n }\n }\n\n private async restartBroadcasts(): Promise<void> {\n await this.stopAllBroadcasts();\n this.initBroadcasting();\n }\n\n private initBroadcasting(): void {\n if (this.broadcast) return;\n if (this.broadcasts.size === 0) return;\n\n this.broadcast = new Broadcast();\n if (this.connection) {\n this.connection.publish(Path.from(this.config.namespace), this.broadcast);\n this.handleTrackRequests().catch(error => {\n console.error('Error handling track requests:', error);\n });\n }\n }\n\n private async handleTrackRequests(): Promise<void> {\n if (!this.broadcast) return;\n \n try {\n for (;;) {\n const request = await this.broadcast.requested();\n if (!request) return; // No more requests, broadcast closed;\n const broadcast = this.broadcasts.get(request.track.name);\n if (broadcast) {\n broadcast.updateTrack(request.track);\n this.emit('trackRequested', request.track.name);\n }\n }\n\n } catch (error) {\n console.warn('Error handling track requests:', error);\n this.handleError(error as Error);\n }\n}\n\n private async restartSubscriptions(): Promise<void> {\n if (!this.connection) return;\n\n const promises = Array.from(this.subscriptions.values()).map(subscription => \n subscription.start(this.connection!, this.config.namespace).catch(error => {\n console.error('Failed to restart subscription:', error);\n })\n );\n\n await Promise.allSettled(promises);\n }\n\n private async stopAllBroadcasts(): Promise<void> {\n this.broadcast?.close();\n this.broadcast = undefined;\n const promises = Array.from(this.broadcasts.values()).map(broadcast => \n broadcast.stop().catch(error => {\n console.warn('Error stopping broadcast:', error);\n })\n );\n\n await Promise.allSettled(promises);\n }\n\n private async stopAllSubscriptions(): Promise<void> {\n const promises = Array.from(this.subscriptions.values()).map(subscription => \n subscription.stop().catch(error => {\n console.warn('Error stopping subscription:', error);\n })\n );\n\n await Promise.allSettled(promises);\n }\n\n private handleDisconnection(): void {\n this.setState(SessionState.DISCONNECTED);\n this.scheduleReconnect();\n }\n\n private scheduleReconnect(): void {\n if (!this.config.reconnection || !this.doReconnect) return;\n\n const delay = this.config.reconnection?.delay || 1000;\n\n this.setState(SessionState.RECONNECTING);\n this.reconnectAttempts++;\n\n this.reconnectTimer = setTimeout(() => {\n if (!this.doReconnect) return;\n if (this.state !== SessionState.RECONNECTING) return;\n this.connect().catch(error => {\n console.error('Reconnection failed:', error);\n });\n }, delay);\n }\n\n private setState(newState: SessionState): void {\n if (this.state !== newState) {\n this.state = newState;\n this.emit('stateChange', this.status);\n }\n }\n\n private handleError(error: Error): void {\n this.lastError = error;\n this.emit('error', error);\n }\n\n public dispose(): void {\n // Immediately stop reconnection attempts\n this.doReconnect = false;\n \n // Clear any pending reconnect timer immediately\n if (this.reconnectTimer) {\n clearTimeout(this.reconnectTimer);\n this.reconnectTimer = undefined;\n }\n \n // Disconnect (but don't await to keep dispose synchronous)\n this.disconnect().catch((error) => {\n console.warn('Error during session disconnect:', error);\n });\n this.removeAllListeners();\n\n this.subscriptions.forEach(sub => sub.dispose());\n this.broadcasts.forEach(bc => bc.dispose());\n this.subscriptions.clear();\n this.broadcasts.clear();\n }\n}"],"names":["EventEmitter","event","listener","eventListeners","args","error","SessionState","BroadcastState","SubscriptionState","MoQBroadcast","config","track","data","newGroup","newState","MoQSubscription","connection","namespace","broadcastPath","Path","framesInGroup","group","frame","receivedData","delay","_a","MoQSession","Connection","configs","trackNames","uniqueTrackNames","duplicates","name","index","desiredTracks","currentTracks","trackName","existing","_b","broadcast","subscription","status","received","namespacePath","announced","announcement","Broadcast","request","promises","sub","bc"],"mappings":"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"}
|
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Path as
|
|
2
|
-
class
|
|
1
|
+
import { Path as m, Connection as b, Broadcast as E } from "@kixelated/moq";
|
|
2
|
+
class p {
|
|
3
3
|
constructor() {
|
|
4
4
|
this.listeners = /* @__PURE__ */ new Map();
|
|
5
5
|
}
|
|
@@ -25,7 +25,7 @@ class m {
|
|
|
25
25
|
}
|
|
26
26
|
}
|
|
27
27
|
var c = /* @__PURE__ */ ((r) => (r.DISCONNECTED = "disconnected", r.CONNECTING = "connecting", r.CONNECTED = "connected", r.RECONNECTING = "reconnecting", r.FAILED = "failed", r))(c || {}), d = /* @__PURE__ */ ((r) => (r.IDLE = "idle", r.BROADCASTING = "broadcasting", r.ERROR = "error", r))(d || {}), l = /* @__PURE__ */ ((r) => (r.PENDING = "pending", r.SUBSCRIBED = "subscribed", r.RETRYING = "retrying", r.FAILED = "failed", r))(l || {});
|
|
28
|
-
class y extends
|
|
28
|
+
class y extends p {
|
|
29
29
|
constructor(t) {
|
|
30
30
|
super(), this.state = d.IDLE, this.bytesSent = 0, this._config = t;
|
|
31
31
|
}
|
|
@@ -73,7 +73,7 @@ class y extends m {
|
|
|
73
73
|
this.stop().catch(console.error), this.removeAllListeners();
|
|
74
74
|
}
|
|
75
75
|
}
|
|
76
|
-
class N extends
|
|
76
|
+
class N extends p {
|
|
77
77
|
constructor(t) {
|
|
78
78
|
super(), this.state = l.PENDING, this.bytesReceived = 0, this.retryAttempts = 0, this._config = t;
|
|
79
79
|
}
|
|
@@ -99,7 +99,7 @@ class N extends m {
|
|
|
99
99
|
}
|
|
100
100
|
async subscribe(t, s) {
|
|
101
101
|
this.setState(l.PENDING);
|
|
102
|
-
const e =
|
|
102
|
+
const e = m.from(s);
|
|
103
103
|
this.broadcast = t.consume(e), this.subscription = this.broadcast.subscribe(this._config.trackName, this._config.priority || 0), this.setState(l.SUBSCRIBED), this.retryAttempts = 0, this.readFrames();
|
|
104
104
|
}
|
|
105
105
|
async readFrames() {
|
|
@@ -168,7 +168,7 @@ class N extends m {
|
|
|
168
168
|
}), this.removeAllListeners();
|
|
169
169
|
}
|
|
170
170
|
}
|
|
171
|
-
class k extends
|
|
171
|
+
class k extends p {
|
|
172
172
|
constructor(t) {
|
|
173
173
|
var s;
|
|
174
174
|
super(), this.state = c.DISCONNECTED, this.reconnectAttempts = 0, this.broadcasts = /* @__PURE__ */ new Map(), this.subscriptions = /* @__PURE__ */ new Map(), this.announcedBroadcasts = /* @__PURE__ */ new Set(), this.doReconnect = !0, this.config = {
|
|
@@ -192,10 +192,9 @@ class k extends m {
|
|
|
192
192
|
if (!(this.state === c.CONNECTING || this.state === c.CONNECTED)) {
|
|
193
193
|
this.setState(c.CONNECTING);
|
|
194
194
|
try {
|
|
195
|
-
this.doReconnect = !0, this.connection = await
|
|
195
|
+
this.doReconnect = !0, this.connection = await b.connect(this.url, {
|
|
196
196
|
websocket: {
|
|
197
197
|
enabled: !1
|
|
198
|
-
// Disable WebSocket fallback
|
|
199
198
|
}
|
|
200
199
|
}), this.setState(c.CONNECTED), this.connectedAt = /* @__PURE__ */ new Date(), this.reconnectAttempts = 0, this.connection.closed.then(() => {
|
|
201
200
|
this.state === c.CONNECTED && this.handleDisconnection();
|
|
@@ -256,7 +255,7 @@ class k extends m {
|
|
|
256
255
|
var i, h;
|
|
257
256
|
const s = t.map((a) => a.trackName), e = new Set(s);
|
|
258
257
|
if (s.length !== e.size) {
|
|
259
|
-
const a = s.filter((u,
|
|
258
|
+
const a = s.filter((u, f) => s.indexOf(u) !== f);
|
|
260
259
|
throw new Error(`Duplicate subscription track name: ${a[0]}`);
|
|
261
260
|
}
|
|
262
261
|
const o = new Set(t.map((a) => a.trackName)), n = new Set(this.subscriptions.keys());
|
|
@@ -332,7 +331,7 @@ class k extends m {
|
|
|
332
331
|
async startAnnouncementDiscovery() {
|
|
333
332
|
if (this.connection)
|
|
334
333
|
try {
|
|
335
|
-
const t =
|
|
334
|
+
const t = m.from(this.config.namespace), s = this.connection.announced(t);
|
|
336
335
|
this.processAnnouncements(s);
|
|
337
336
|
} catch (t) {
|
|
338
337
|
console.error("Failed to start announcement discovery:", t);
|
|
@@ -359,7 +358,7 @@ class k extends m {
|
|
|
359
358
|
await this.stopAllBroadcasts(), this.initBroadcasting();
|
|
360
359
|
}
|
|
361
360
|
initBroadcasting() {
|
|
362
|
-
this.broadcast || this.broadcasts.size !== 0 && (this.broadcast = new E(), this.connection && (this.connection.publish(
|
|
361
|
+
this.broadcast || this.broadcasts.size !== 0 && (this.broadcast = new E(), this.connection && (this.connection.publish(m.from(this.config.namespace), this.broadcast), this.handleTrackRequests().catch((t) => {
|
|
363
362
|
console.error("Error handling track requests:", t);
|
|
364
363
|
})));
|
|
365
364
|
}
|
|
@@ -408,9 +407,10 @@ class k extends m {
|
|
|
408
407
|
}
|
|
409
408
|
scheduleReconnect() {
|
|
410
409
|
var s;
|
|
410
|
+
if (!this.config.reconnection || !this.doReconnect) return;
|
|
411
411
|
const t = ((s = this.config.reconnection) == null ? void 0 : s.delay) || 1e3;
|
|
412
412
|
this.setState(c.RECONNECTING), this.reconnectAttempts++, this.reconnectTimer = setTimeout(() => {
|
|
413
|
-
this.doReconnect && this.connect().catch((e) => {
|
|
413
|
+
this.doReconnect && this.state === c.RECONNECTING && this.connect().catch((e) => {
|
|
414
414
|
console.error("Reconnection failed:", e);
|
|
415
415
|
});
|
|
416
416
|
}, t);
|
|
@@ -422,8 +422,8 @@ class k extends m {
|
|
|
422
422
|
this.lastError = t, this.emit("error", t);
|
|
423
423
|
}
|
|
424
424
|
dispose() {
|
|
425
|
-
this.disconnect().catch((t) => {
|
|
426
|
-
console.warn("Error during
|
|
425
|
+
this.doReconnect = !1, this.reconnectTimer && (clearTimeout(this.reconnectTimer), this.reconnectTimer = void 0), this.disconnect().catch((t) => {
|
|
426
|
+
console.warn("Error during session disconnect:", t);
|
|
427
427
|
}), this.removeAllListeners(), this.subscriptions.forEach((t) => t.dispose()), this.broadcasts.forEach((t) => t.dispose()), this.subscriptions.clear(), this.broadcasts.clear();
|
|
428
428
|
}
|
|
429
429
|
}
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","sources":["../src/event-emitter.ts","../src/types.ts","../src/broadcast.ts","../src/subscription.ts","../src/session.ts"],"sourcesContent":["// Simple event emitter for type-safe events\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport class EventEmitter<T extends Record<string, (...args: any[]) => void>> {\n private listeners = new Map<keyof T, Set<T[keyof T]>>();\n\n on<K extends keyof T>(event: K, listener: T[K]): void {\n if (!this.listeners.has(event)) {\n this.listeners.set(event, new Set());\n }\n this.listeners.get(event)!.add(listener);\n }\n\n off<K extends keyof T>(event: K, listener: T[K]): void {\n const eventListeners = this.listeners.get(event);\n if (eventListeners) {\n eventListeners.delete(listener);\n }\n }\n\n emit<K extends keyof T>(event: K, ...args: Parameters<T[K]>): void {\n const eventListeners = this.listeners.get(event);\n if (eventListeners) {\n eventListeners.forEach(listener => {\n try {\n listener(...args);\n } catch (error) {\n console.error('Error in event listener:', error);\n }\n });\n }\n }\n\n removeAllListeners<K extends keyof T>(event?: K): void {\n if (event) {\n this.listeners.delete(event);\n } else {\n this.listeners.clear();\n }\n }\n}","// Types for the library\nexport interface MoQSessionConfig {\n /** URL of the MoQ relay server */\n relayUrl: string;\n /** MoQ namespace (broadcast name) */\n namespace: string;\n /** Reconnection configuration */\n reconnection?: {\n /** Delay between reconnection attempts in ms (minimum: 1000) */\n delay?: number;\n };\n /** Connection timeout in ms (default: 10000) */\n connectionTimeout?: number;\n}\n\nexport interface BroadcastConfig {\n /** Track name for the broadcast */\n trackName: string;\n /** Priority for the track (default: 0) */\n priority?: number;\n}\n\nexport interface SubscriptionConfig {\n /** Track name to subscribe to */\n trackName: string;\n /** Priority for the subscription (default: 0) */\n priority?: number;\n /** Retry configuration for failed subscriptions */\n retry?: {\n /** Delay between retry attempts in ms (default: 2000) */\n delay?: number;\n };\n}\n\nexport enum SessionState {\n DISCONNECTED = 'disconnected',\n CONNECTING = 'connecting',\n CONNECTED = 'connected',\n RECONNECTING = 'reconnecting',\n FAILED = 'failed'\n}\n\nexport enum BroadcastState {\n IDLE = 'idle',\n BROADCASTING = 'broadcasting',\n ERROR = 'error'\n}\n\nexport enum SubscriptionState {\n PENDING = 'pending',\n SUBSCRIBED = 'subscribed',\n RETRYING = 'retrying',\n FAILED = 'failed'\n}\n\nexport interface SessionStatus {\n state: SessionState;\n reconnectAttempts: number;\n lastError?: Error;\n connectedAt?: Date;\n}\n\nexport interface BroadcastStatus {\n state: BroadcastState;\n trackName: string;\n bytesSent: number;\n lastError?: Error;\n}\n\nexport interface SubscriptionStatus {\n state: SubscriptionState;\n trackName: string;\n bytesReceived: number;\n retryAttempts: number;\n lastError?: Error;\n}\n\nexport interface DataReceived {\n trackName: string;\n data: Uint8Array;\n timestamp: number;\n frameIndex: number;\n}\n\n// Event types\nexport interface BroadcastAnnouncement {\n path: string;\n active: boolean;\n}\n\nexport interface SessionEvents {\n stateChange: (status: SessionStatus) => void;\n error: (error: Error) => void;\n broadcastAnnounced: (announcement: BroadcastAnnouncement) => void;\n data: (trackName: string, data: Uint8Array, frameIndex: number) => void;\n broadcastStateChange: (trackName: string, status: BroadcastStatus) => void;\n subscriptionStateChange: (trackName: string, status: SubscriptionStatus) => void;\n broadcastError: (trackName: string, error: Error) => void;\n subscriptionError: (trackName: string, error: Error) => void;\n trackRequested: (trackName: string) => void;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n [key: string]: (...args: any[]) => void;\n}\n\nexport interface BroadcastEvents {\n stateChange: (status: BroadcastStatus) => void;\n error: (error: Error) => void;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n [key: string]: (...args: any[]) => void;\n}\n\nexport interface SubscriptionEvents {\n stateChange: (status: SubscriptionStatus) => void;\n data: (data: DataReceived) => void;\n error: (error: Error) => void;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n [key: string]: (...args: any[]) => void;\n}","import { Group, Track } from '@kixelated/moq';\nimport { EventEmitter } from './event-emitter';\nimport {\n BroadcastConfig,\n BroadcastState,\n BroadcastStatus,\n BroadcastEvents\n} from './types';\n\nexport class MoQBroadcast extends EventEmitter<BroadcastEvents> {\n private _config: BroadcastConfig;\n private state: BroadcastState = BroadcastState.IDLE;\n private bytesSent = 0;\n private lastError?: Error;\n private track?: Track;\n private group?: Group;\n\n constructor(config: BroadcastConfig) {\n super();\n this._config = config;\n }\n\n get status(): BroadcastStatus {\n return {\n state: this.state,\n trackName: this._config.trackName,\n bytesSent: this.bytesSent,\n lastError: this.lastError\n };\n }\n\n get config(): BroadcastConfig {\n return { ...this._config };\n }\n\n updateTrack(track: Track): void {\n this.track = track;\n if (track) {\n this.setState(BroadcastState.BROADCASTING);\n }\n }\n\n async send(data: Uint8Array, newGroup: boolean): Promise<void> {\n if (this.state !== BroadcastState.BROADCASTING || !this.track) {\n throw new Error('Broadcast is not active');\n }\n\n try {\n if (newGroup || !this.group) {\n if (this.group) {\n this.group.close();\n }\n this.group = this.track.appendGroup();\n }\n await this.group.writeFrame(data);\n this.bytesSent += data.length;\n } catch (error) {\n this.handleError(error as Error);\n throw error;\n }\n }\n\n async stop(): Promise<void> {\n if (this.track) {\n try {\n this.track.close();\n } catch (error) {\n console.warn('Error closing track:', error);\n }\n this.track = undefined;\n }\n \n this.setState(BroadcastState.IDLE);\n }\n\n private setState(newState: BroadcastState): void {\n if (this.state !== newState) {\n this.state = newState;\n this.emit('stateChange', this.status);\n }\n }\n\n private handleError(error: Error): void {\n this.lastError = error;\n this.setState(BroadcastState.ERROR);\n this.emit('error', error);\n }\n\n public dispose(): void {\n this.stop().catch(console.error);\n this.removeAllListeners();\n }\n}","import { Broadcast, Track, Connection, Path } from '@kixelated/moq';\nimport { EventEmitter } from './event-emitter';\nimport {\n SubscriptionConfig,\n SubscriptionState,\n SubscriptionStatus,\n SubscriptionEvents,\n DataReceived\n} from './types';\n\nexport class MoQSubscription extends EventEmitter<SubscriptionEvents> {\n private _config: SubscriptionConfig;\n private state: SubscriptionState = SubscriptionState.PENDING;\n private bytesReceived = 0;\n private retryAttempts = 0;\n private lastError?: Error;\n private subscription?: Track;\n private broadcast?: Broadcast;\n private retryTimer?: ReturnType<typeof setTimeout>;\n private connection?: Connection.Established;\n private namespace?: string;\n\n constructor(config: SubscriptionConfig) {\n super();\n this._config = config;\n }\n\n get status(): SubscriptionStatus {\n return {\n state: this.state,\n trackName: this._config.trackName,\n bytesReceived: this.bytesReceived,\n retryAttempts: this.retryAttempts,\n lastError: this.lastError\n };\n }\n\n get config(): SubscriptionConfig {\n return { ...this._config };\n }\n\n async start(connection: Connection.Established, namespace: string): Promise<void> {\n this.connection = connection;\n this.namespace = namespace;\n try {\n await this.subscribe(connection, namespace);\n } catch (error) {\n this.handleError(error as Error);\n this.scheduleRetry(connection, namespace);\n }\n }\n\n private async subscribe(connection: Connection.Established, namespace: string): Promise<void> {\n this.setState(SubscriptionState.PENDING);\n\n const broadcastPath = Path.from(namespace);\n this.broadcast = connection.consume(broadcastPath);\n\n // Subscribe to the specific track within the broadcast\n this.subscription = this.broadcast.subscribe(this._config.trackName, this._config.priority || 0);\n this.setState(SubscriptionState.SUBSCRIBED);\n this.retryAttempts = 0;\n\n // Set up data reception\n this.readFrames();\n }\n\n private async readFrames(): Promise<void> {\n if (!this.subscription) return;\n\n try {\n // eslint-disable-next-line no-constant-condition\n while (true) {\n let framesInGroup = 0;\n const group = await this.subscription.nextGroup();\n if (!group) break; // Track is closed\n\n // Read all frames from the group\n // eslint-disable-next-line no-constant-condition\n while (true) {\n const frame = await group.readFrame();\n if (!frame) break; // Group is finished\n framesInGroup++;\n\n this.bytesReceived += frame.length;\n const receivedData: DataReceived = {\n trackName: this._config.trackName,\n data: frame,\n timestamp: Date.now(),\n frameIndex: framesInGroup,\n };\n this.emit('data', receivedData);\n }\n }\n } catch (error) {\n this.handleError(error as Error);\n // Trigger retry when stream gets reset/closed\n if (this.connection && this.namespace) {\n this.scheduleRetry(this.connection, this.namespace);\n }\n }\n }\n \n private scheduleRetry(connection: Connection.Established, namespace: string): void {\n const delay = this._config.retry?.delay || 2000;\n\n this.setState(SubscriptionState.RETRYING);\n this.retryAttempts++;\n\n this.retryTimer = setTimeout(async () => {\n try {\n await this.subscribe(connection, namespace);\n } catch (error) {\n this.handleError(error as Error);\n this.scheduleRetry(connection, namespace);\n }\n }, delay);\n }\n\n async stop(): Promise<void> {\n this.connection = undefined;\n this.namespace = undefined;\n \n if (this.retryTimer) {\n clearTimeout(this.retryTimer);\n this.retryTimer = undefined;\n }\n\n if (this.subscription) {\n try {\n this.subscription.close();\n } catch (error) {\n console.warn('Error closing subscription:', error);\n }\n this.subscription = undefined;\n }\n\n if (this.broadcast) {\n try {\n this.broadcast.close();\n } catch (error) {\n console.warn('Error closing broadcast:', error);\n }\n this.broadcast = undefined;\n }\n\n this.setState(SubscriptionState.PENDING);\n }\n\n private setState(newState: SubscriptionState): void {\n if (this.state !== newState) {\n this.state = newState;\n this.emit('stateChange', this.status);\n }\n }\n\n private handleError(error: Error): void {\n this.lastError = error;\n this.emit('error', error);\n }\n\n dispose(): void {\n this.stop().catch((error) => {\n console.warn('Error during dispose:', error);\n });\n this.removeAllListeners();\n }\n}","import { Broadcast, Connection, Path } from '@kixelated/moq';\nimport { EventEmitter } from './event-emitter';\nimport { MoQBroadcast } from './broadcast';\nimport { MoQSubscription } from './subscription';\nimport {\n MoQSessionConfig,\n SessionState,\n SessionStatus,\n SessionEvents,\n BroadcastConfig,\n SubscriptionConfig\n} from './types';\n\nexport class MoQSession extends EventEmitter<SessionEvents> {\n private config: MoQSessionConfig;\n private url: URL;\n private state: SessionState = SessionState.DISCONNECTED;\n private connection?: Connection.Established;\n private reconnectAttempts = 0;\n private lastError?: Error;\n private connectedAt?: Date;\n private reconnectTimer?: ReturnType<typeof setTimeout>;\n private broadcasts = new Map<string, MoQBroadcast>();\n private subscriptions = new Map<string, MoQSubscription>();\n private announcedBroadcasts = new Set<string>();\n private doReconnect = true;\n private broadcast?: Broadcast;\n\n constructor(config: MoQSessionConfig) {\n super();\n this.config = {\n ...config,\n reconnection: {\n delay: Math.max(config.reconnection?.delay || 1000, 1000), // Enforce minimum 1 second\n },\n connectionTimeout: config.connectionTimeout || 10000\n };\n\n this.url = new URL(this.config.relayUrl);\n }\n\n get status(): SessionStatus {\n return {\n state: this.state,\n reconnectAttempts: this.reconnectAttempts,\n lastError: this.lastError,\n connectedAt: this.connectedAt\n };\n }\n\n async connect(): Promise<void> {\n if (this.state === SessionState.CONNECTING || this.state === SessionState.CONNECTED) {\n return;\n }\n\n this.setState(SessionState.CONNECTING);\n\n try {\n this.doReconnect = true;\n // Connect using the @kixelated/moq library with WebSocket fallback disabled\n this.connection = await Connection.connect(this.url, {\n websocket: {\n enabled: false // Disable WebSocket fallback\n }\n });\n\n this.setState(SessionState.CONNECTED);\n this.connectedAt = new Date();\n this.reconnectAttempts = 0;\n\n // Set up connection close handling\n this.connection.closed.then(() => {\n if (this.state === SessionState.CONNECTED) {\n this.handleDisconnection();\n }\n });\n\n // Start discovering announced broadcasts\n this.startAnnouncementDiscovery();\n\n // Restart all broadcasts and subscriptions\n await this.restartBroadcasts();\n await this.restartSubscriptions();\n\n } catch (error) {\n this.handleError(error as Error);\n this.scheduleReconnect();\n throw error;\n }\n }\n\n async disconnect(): Promise<void> {\n this.doReconnect = false;\n\n if (this.reconnectTimer) {\n clearTimeout(this.reconnectTimer);\n this.reconnectTimer = undefined;\n }\n\n // Stop all broadcasts and subscriptions\n await this.stopAllBroadcasts();\n await this.stopAllSubscriptions();\n\n if (this.connection) {\n try {\n this.connection.close();\n } catch (error) {\n console.warn('Error closing connection:', error);\n }\n this.connection = undefined;\n }\n\n this.setState(SessionState.DISCONNECTED);\n this.connectedAt = undefined;\n }\n\n /**\n * Get all active broadcast track names\n */\n getAllBroadcastTrackNames(): string[] {\n return Array.from(this.broadcasts.keys());\n }\n\n /**\n * Get all active subscription track names\n */\n getAllSubscriptionTrackNames(): string[] {\n return Array.from(this.subscriptions.keys());\n }\n\n /**\n * Declaratively update broadcasts - add, remove, or update broadcasts to match the desired state.\n * \n * @param configs Array of broadcast configurations representing the desired state\n */\n updateBroadcasts(configs: BroadcastConfig[]): void {\n // Check for duplicate track names in the input\n const trackNames = configs.map(config => config.trackName);\n const uniqueTrackNames = new Set(trackNames);\n if (trackNames.length !== uniqueTrackNames.size) {\n const duplicates = trackNames.filter((name, index) => trackNames.indexOf(name) !== index);\n throw new Error(`Duplicate broadcast track name: ${duplicates[0]}`);\n }\n\n const desiredTracks = new Set(configs.map(config => config.trackName));\n const currentTracks = new Set(this.broadcasts.keys());\n\n // Remove broadcasts that are no longer needed\n for (const trackName of currentTracks) {\n if (!desiredTracks.has(trackName)) {\n this._removeBroadcast(trackName);\n }\n }\n\n // Add new broadcasts or update existing ones\n for (const config of configs) {\n const existing = this.broadcasts.get(config.trackName);\n if (!existing) {\n // Create new broadcast\n this._createBroadcast(config);\n } else {\n // Update existing broadcast config if needed\n if (existing.config.priority !== config.priority) {\n // For now, we recreate if priority changed\n // In future, we could support dynamic priority updates\n this._removeBroadcast(config.trackName);\n this._createBroadcast(config);\n }\n }\n }\n }\n\n /**\n * Declaratively update subscriptions - add, remove, or update subscriptions to match the desired state.\n * \n * @param configs Array of subscription configurations representing the desired state\n */\n updateSubscriptions(configs: SubscriptionConfig[]): void {\n // Check for duplicate track names in the input\n const trackNames = configs.map(config => config.trackName);\n const uniqueTrackNames = new Set(trackNames);\n if (trackNames.length !== uniqueTrackNames.size) {\n const duplicates = trackNames.filter((name, index) => trackNames.indexOf(name) !== index);\n throw new Error(`Duplicate subscription track name: ${duplicates[0]}`);\n }\n\n const desiredTracks = new Set(configs.map(config => config.trackName));\n const currentTracks = new Set(this.subscriptions.keys());\n\n // Remove subscriptions that are no longer needed\n for (const trackName of currentTracks) {\n if (!desiredTracks.has(trackName)) {\n this._removeSubscription(trackName);\n }\n }\n\n // Add new subscriptions or update existing ones\n for (const config of configs) {\n const existing = this.subscriptions.get(config.trackName);\n if (!existing) {\n // Create new subscription\n this._createSubscription(config);\n } else {\n // Update existing subscription config if needed\n if (existing.config.priority !== config.priority || \n existing.config.retry?.delay !== config.retry?.delay) {\n // For now, we recreate if config changed\n // In future, we could support dynamic config updates\n this._removeSubscription(config.trackName);\n this._createSubscription(config);\n }\n }\n }\n }\n\n getAnnouncedBroadcasts(): string[] {\n return Array.from(this.announcedBroadcasts);\n }\n\n /**\n * Send data to a broadcast track\n * @param trackName Name of the track to send data to\n * @param data Binary data to send\n */\n async send(trackName: string, data: Uint8Array, newGroup: boolean): Promise<void> {\n const broadcast = this.broadcasts.get(trackName);\n if (!broadcast) {\n throw new Error(`No broadcast found for track: ${trackName}`);\n }\n await broadcast.send(data, newGroup);\n }\n\n /**\n * Get the status of a specific broadcast track\n * @param trackName Name of the track\n */\n getBroadcastStatus(trackName: string) {\n const broadcast = this.broadcasts.get(trackName);\n return broadcast?.status;\n }\n\n /**\n * Get the status of a specific subscription track\n * @param trackName Name of the track\n */\n getSubscriptionStatus(trackName: string) {\n const subscription = this.subscriptions.get(trackName);\n return subscription?.status;\n }\n\n private _createBroadcast(config: BroadcastConfig): MoQBroadcast {\n const broadcast = new MoQBroadcast(config);\n this.broadcasts.set(config.trackName, broadcast);\n\n // Forward broadcast events to session\n broadcast.on('stateChange', (status) => {\n this.emit('broadcastStateChange', config.trackName, status);\n });\n\n broadcast.on('error', (error) => {\n this.emit('broadcastError', config.trackName, error);\n });\n\n this.initBroadcasting();\n\n return broadcast;\n }\n\n private _createSubscription(config: SubscriptionConfig): MoQSubscription {\n const subscription = new MoQSubscription(config);\n this.subscriptions.set(config.trackName, subscription);\n\n // Forward subscription events to session\n subscription.on('data', (received) => {\n this.emit('data', received.trackName, received.data, received.frameIndex);\n });\n\n subscription.on('stateChange', (status) => {\n this.emit('subscriptionStateChange', config.trackName, status);\n });\n\n subscription.on('error', (error) => {\n this.emit('subscriptionError', config.trackName, error);\n });\n\n // Start subscription if we're connected\n if (this.state === SessionState.CONNECTED && this.connection) {\n subscription.start(this.connection, this.config.namespace).catch(error => {\n console.error('Failed to start subscription:', error);\n });\n }\n\n return subscription;\n }\n\n private _removeBroadcast(trackName: string): void {\n const broadcast = this.broadcasts.get(trackName);\n if (broadcast) {\n broadcast.stop().catch(error => {\n console.warn('Error stopping broadcast:', error);\n });\n this.broadcasts.delete(trackName);\n }\n }\n\n private _removeSubscription(trackName: string): void {\n const subscription = this.subscriptions.get(trackName);\n if (subscription) {\n subscription.stop().catch(error => {\n console.warn('Error stopping subscription:', error);\n });\n this.subscriptions.delete(trackName);\n }\n }\n\n private async startAnnouncementDiscovery(): Promise<void> {\n if (!this.connection) return;\n\n try {\n // Listen for announcements with our namespace as prefix\n const namespacePath = Path.from(this.config.namespace);\n const announced = this.connection.announced(namespacePath);\n \n // Process announcements in the background\n this.processAnnouncements(announced);\n \n } catch (error) {\n console.error('Failed to start announcement discovery:', error);\n }\n }\n\n private async processAnnouncements(announced: ReturnType<Connection.Established['announced']>): Promise<void> {\n try {\n for (;;) {\n const announcement = await announced.next();\n if (!announcement) break; // Announcements closed\n \n if (announcement.active) {\n this.announcedBroadcasts.add(announcement.path);\n this.emit('broadcastAnnounced', {\n path: announcement.path,\n active: true\n });\n } else {\n this.announcedBroadcasts.delete(announcement.path);\n this.emit('broadcastAnnounced', {\n path: announcement.path,\n active: false\n });\n }\n }\n } catch (error) {\n console.error('Error processing announcements:', error);\n }\n }\n\n private async restartBroadcasts(): Promise<void> {\n await this.stopAllBroadcasts();\n this.initBroadcasting();\n }\n\n private initBroadcasting(): void {\n if (this.broadcast) return;\n if (this.broadcasts.size === 0) return;\n\n this.broadcast = new Broadcast();\n if (this.connection) {\n this.connection.publish(Path.from(this.config.namespace), this.broadcast);\n this.handleTrackRequests().catch(error => {\n console.error('Error handling track requests:', error);\n });\n }\n }\n\n private async handleTrackRequests(): Promise<void> {\n if (!this.broadcast) return;\n \n try {\n for (;;) {\n const request = await this.broadcast.requested();\n if (!request) return; // No more requests, broadcast closed;\n const broadcast = this.broadcasts.get(request.track.name);\n if (broadcast) {\n broadcast.updateTrack(request.track);\n this.emit('trackRequested', request.track.name);\n }\n }\n\n } catch (error) {\n console.warn('Error handling track requests:', error);\n this.handleError(error as Error);\n }\n}\n\n private async restartSubscriptions(): Promise<void> {\n if (!this.connection) return;\n\n const promises = Array.from(this.subscriptions.values()).map(subscription => \n subscription.start(this.connection!, this.config.namespace).catch(error => {\n console.error('Failed to restart subscription:', error);\n })\n );\n\n await Promise.allSettled(promises);\n }\n\n private async stopAllBroadcasts(): Promise<void> {\n this.broadcast?.close();\n this.broadcast = undefined;\n const promises = Array.from(this.broadcasts.values()).map(broadcast => \n broadcast.stop().catch(error => {\n console.warn('Error stopping broadcast:', error);\n })\n );\n\n await Promise.allSettled(promises);\n }\n\n private async stopAllSubscriptions(): Promise<void> {\n const promises = Array.from(this.subscriptions.values()).map(subscription => \n subscription.stop().catch(error => {\n console.warn('Error stopping subscription:', error);\n })\n );\n\n await Promise.allSettled(promises);\n }\n\n private handleDisconnection(): void {\n this.setState(SessionState.DISCONNECTED);\n this.scheduleReconnect();\n }\n\n private scheduleReconnect(): void {\n const delay = this.config.reconnection?.delay || 1000;\n\n this.setState(SessionState.RECONNECTING);\n this.reconnectAttempts++;\n\n this.reconnectTimer = setTimeout(() => {\n if (!this.doReconnect) return;\n this.connect().catch(error => {\n console.error('Reconnection failed:', error);\n });\n }, delay);\n }\n\n private setState(newState: SessionState): void {\n if (this.state !== newState) {\n this.state = newState;\n this.emit('stateChange', this.status);\n }\n }\n\n private handleError(error: Error): void {\n this.lastError = error;\n this.emit('error', error);\n }\n\n public dispose(): void {\n this.disconnect().catch((error) => {\n console.warn('Error during dispose:', error);\n });\n this.removeAllListeners();\n\n this.subscriptions.forEach(sub => sub.dispose());\n this.broadcasts.forEach(bc => bc.dispose());\n this.subscriptions.clear();\n this.broadcasts.clear();\n }\n}"],"names":["EventEmitter","event","listener","eventListeners","args","error","SessionState","BroadcastState","SubscriptionState","MoQBroadcast","config","track","data","newGroup","newState","MoQSubscription","connection","namespace","broadcastPath","Path","framesInGroup","group","frame","receivedData","delay","_a","MoQSession","Connection","configs","trackNames","uniqueTrackNames","duplicates","name","index","desiredTracks","currentTracks","trackName","existing","_b","broadcast","subscription","status","received","namespacePath","announced","announcement","Broadcast","request","promises","sub","bc"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.mjs","sources":["../src/event-emitter.ts","../src/types.ts","../src/broadcast.ts","../src/subscription.ts","../src/session.ts"],"sourcesContent":["// Simple event emitter for type-safe events\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport class EventEmitter<T extends Record<string, (...args: any[]) => void>> {\n private listeners = new Map<keyof T, Set<T[keyof T]>>();\n\n on<K extends keyof T>(event: K, listener: T[K]): void {\n if (!this.listeners.has(event)) {\n this.listeners.set(event, new Set());\n }\n this.listeners.get(event)!.add(listener);\n }\n\n off<K extends keyof T>(event: K, listener: T[K]): void {\n const eventListeners = this.listeners.get(event);\n if (eventListeners) {\n eventListeners.delete(listener);\n }\n }\n\n emit<K extends keyof T>(event: K, ...args: Parameters<T[K]>): void {\n const eventListeners = this.listeners.get(event);\n if (eventListeners) {\n eventListeners.forEach(listener => {\n try {\n listener(...args);\n } catch (error) {\n console.error('Error in event listener:', error);\n }\n });\n }\n }\n\n removeAllListeners<K extends keyof T>(event?: K): void {\n if (event) {\n this.listeners.delete(event);\n } else {\n this.listeners.clear();\n }\n }\n}","// Types for the library\nexport interface MoQSessionConfig {\n /** URL of the MoQ relay server */\n relayUrl: string;\n /** MoQ namespace (broadcast name) */\n namespace: string;\n /** Reconnection configuration */\n reconnection?: {\n /** Delay between reconnection attempts in ms (minimum: 1000) */\n delay?: number;\n };\n /** Connection timeout in ms (default: 10000) */\n connectionTimeout?: number;\n}\n\nexport interface BroadcastConfig {\n /** Track name for the broadcast */\n trackName: string;\n /** Priority for the track (default: 0) */\n priority?: number;\n}\n\nexport interface SubscriptionConfig {\n /** Track name to subscribe to */\n trackName: string;\n /** Priority for the subscription (default: 0) */\n priority?: number;\n /** Retry configuration for failed subscriptions */\n retry?: {\n /** Delay between retry attempts in ms (default: 2000) */\n delay?: number;\n };\n}\n\nexport enum SessionState {\n DISCONNECTED = 'disconnected',\n CONNECTING = 'connecting',\n CONNECTED = 'connected',\n RECONNECTING = 'reconnecting',\n FAILED = 'failed'\n}\n\nexport enum BroadcastState {\n IDLE = 'idle',\n BROADCASTING = 'broadcasting',\n ERROR = 'error'\n}\n\nexport enum SubscriptionState {\n PENDING = 'pending',\n SUBSCRIBED = 'subscribed',\n RETRYING = 'retrying',\n FAILED = 'failed'\n}\n\nexport interface SessionStatus {\n state: SessionState;\n reconnectAttempts: number;\n lastError?: Error;\n connectedAt?: Date;\n}\n\nexport interface BroadcastStatus {\n state: BroadcastState;\n trackName: string;\n bytesSent: number;\n lastError?: Error;\n}\n\nexport interface SubscriptionStatus {\n state: SubscriptionState;\n trackName: string;\n bytesReceived: number;\n retryAttempts: number;\n lastError?: Error;\n}\n\nexport interface DataReceived {\n trackName: string;\n data: Uint8Array;\n timestamp: number;\n frameIndex: number;\n}\n\n// Event types\nexport interface BroadcastAnnouncement {\n path: string;\n active: boolean;\n}\n\nexport interface SessionEvents {\n stateChange: (status: SessionStatus) => void;\n error: (error: Error) => void;\n broadcastAnnounced: (announcement: BroadcastAnnouncement) => void;\n data: (trackName: string, data: Uint8Array, frameIndex: number) => void;\n broadcastStateChange: (trackName: string, status: BroadcastStatus) => void;\n subscriptionStateChange: (trackName: string, status: SubscriptionStatus) => void;\n broadcastError: (trackName: string, error: Error) => void;\n subscriptionError: (trackName: string, error: Error) => void;\n trackRequested: (trackName: string) => void;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n [key: string]: (...args: any[]) => void;\n}\n\nexport interface BroadcastEvents {\n stateChange: (status: BroadcastStatus) => void;\n error: (error: Error) => void;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n [key: string]: (...args: any[]) => void;\n}\n\nexport interface SubscriptionEvents {\n stateChange: (status: SubscriptionStatus) => void;\n data: (data: DataReceived) => void;\n error: (error: Error) => void;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n [key: string]: (...args: any[]) => void;\n}","import { Group, Track } from '@kixelated/moq';\nimport { EventEmitter } from './event-emitter';\nimport {\n BroadcastConfig,\n BroadcastState,\n BroadcastStatus,\n BroadcastEvents\n} from './types';\n\nexport class MoQBroadcast extends EventEmitter<BroadcastEvents> {\n private _config: BroadcastConfig;\n private state: BroadcastState = BroadcastState.IDLE;\n private bytesSent = 0;\n private lastError?: Error;\n private track?: Track;\n private group?: Group;\n\n constructor(config: BroadcastConfig) {\n super();\n this._config = config;\n }\n\n get status(): BroadcastStatus {\n return {\n state: this.state,\n trackName: this._config.trackName,\n bytesSent: this.bytesSent,\n lastError: this.lastError\n };\n }\n\n get config(): BroadcastConfig {\n return { ...this._config };\n }\n\n updateTrack(track: Track): void {\n this.track = track;\n if (track) {\n this.setState(BroadcastState.BROADCASTING);\n }\n }\n\n async send(data: Uint8Array, newGroup: boolean): Promise<void> {\n if (this.state !== BroadcastState.BROADCASTING || !this.track) {\n throw new Error('Broadcast is not active');\n }\n\n try {\n if (newGroup || !this.group) {\n if (this.group) {\n this.group.close();\n }\n this.group = this.track.appendGroup();\n }\n await this.group.writeFrame(data);\n this.bytesSent += data.length;\n } catch (error) {\n this.handleError(error as Error);\n throw error;\n }\n }\n\n async stop(): Promise<void> {\n if (this.track) {\n try {\n this.track.close();\n } catch (error) {\n console.warn('Error closing track:', error);\n }\n this.track = undefined;\n }\n \n this.setState(BroadcastState.IDLE);\n }\n\n private setState(newState: BroadcastState): void {\n if (this.state !== newState) {\n this.state = newState;\n this.emit('stateChange', this.status);\n }\n }\n\n private handleError(error: Error): void {\n this.lastError = error;\n this.setState(BroadcastState.ERROR);\n this.emit('error', error);\n }\n\n public dispose(): void {\n this.stop().catch(console.error);\n this.removeAllListeners();\n }\n}","import { Broadcast, Track, Connection, Path } from '@kixelated/moq';\nimport { EventEmitter } from './event-emitter';\nimport {\n SubscriptionConfig,\n SubscriptionState,\n SubscriptionStatus,\n SubscriptionEvents,\n DataReceived\n} from './types';\n\nexport class MoQSubscription extends EventEmitter<SubscriptionEvents> {\n private _config: SubscriptionConfig;\n private state: SubscriptionState = SubscriptionState.PENDING;\n private bytesReceived = 0;\n private retryAttempts = 0;\n private lastError?: Error;\n private subscription?: Track;\n private broadcast?: Broadcast;\n private retryTimer?: ReturnType<typeof setTimeout>;\n private connection?: Connection.Established;\n private namespace?: string;\n\n constructor(config: SubscriptionConfig) {\n super();\n this._config = config;\n }\n\n get status(): SubscriptionStatus {\n return {\n state: this.state,\n trackName: this._config.trackName,\n bytesReceived: this.bytesReceived,\n retryAttempts: this.retryAttempts,\n lastError: this.lastError\n };\n }\n\n get config(): SubscriptionConfig {\n return { ...this._config };\n }\n\n async start(connection: Connection.Established, namespace: string): Promise<void> {\n this.connection = connection;\n this.namespace = namespace;\n try {\n await this.subscribe(connection, namespace);\n } catch (error) {\n this.handleError(error as Error);\n this.scheduleRetry(connection, namespace);\n }\n }\n\n private async subscribe(connection: Connection.Established, namespace: string): Promise<void> {\n this.setState(SubscriptionState.PENDING);\n\n const broadcastPath = Path.from(namespace);\n this.broadcast = connection.consume(broadcastPath);\n\n // Subscribe to the specific track within the broadcast\n this.subscription = this.broadcast.subscribe(this._config.trackName, this._config.priority || 0);\n this.setState(SubscriptionState.SUBSCRIBED);\n this.retryAttempts = 0;\n\n // Set up data reception\n this.readFrames();\n }\n\n private async readFrames(): Promise<void> {\n if (!this.subscription) return;\n\n try {\n // eslint-disable-next-line no-constant-condition\n while (true) {\n let framesInGroup = 0;\n const group = await this.subscription.nextGroup();\n if (!group) break; // Track is closed\n\n // Read all frames from the group\n // eslint-disable-next-line no-constant-condition\n while (true) {\n const frame = await group.readFrame();\n if (!frame) break; // Group is finished\n framesInGroup++;\n\n this.bytesReceived += frame.length;\n const receivedData: DataReceived = {\n trackName: this._config.trackName,\n data: frame,\n timestamp: Date.now(),\n frameIndex: framesInGroup,\n };\n this.emit('data', receivedData);\n }\n }\n } catch (error) {\n this.handleError(error as Error);\n // Trigger retry when stream gets reset/closed\n if (this.connection && this.namespace) {\n this.scheduleRetry(this.connection, this.namespace);\n }\n }\n }\n \n private scheduleRetry(connection: Connection.Established, namespace: string): void {\n const delay = this._config.retry?.delay || 2000;\n\n this.setState(SubscriptionState.RETRYING);\n this.retryAttempts++;\n\n this.retryTimer = setTimeout(async () => {\n try {\n await this.subscribe(connection, namespace);\n } catch (error) {\n this.handleError(error as Error);\n this.scheduleRetry(connection, namespace);\n }\n }, delay);\n }\n\n async stop(): Promise<void> {\n this.connection = undefined;\n this.namespace = undefined;\n \n if (this.retryTimer) {\n clearTimeout(this.retryTimer);\n this.retryTimer = undefined;\n }\n\n if (this.subscription) {\n try {\n this.subscription.close();\n } catch (error) {\n console.warn('Error closing subscription:', error);\n }\n this.subscription = undefined;\n }\n\n if (this.broadcast) {\n try {\n this.broadcast.close();\n } catch (error) {\n console.warn('Error closing broadcast:', error);\n }\n this.broadcast = undefined;\n }\n\n this.setState(SubscriptionState.PENDING);\n }\n\n private setState(newState: SubscriptionState): void {\n if (this.state !== newState) {\n this.state = newState;\n this.emit('stateChange', this.status);\n }\n }\n\n private handleError(error: Error): void {\n this.lastError = error;\n this.emit('error', error);\n }\n\n dispose(): void {\n this.stop().catch((error) => {\n console.warn('Error during dispose:', error);\n });\n this.removeAllListeners();\n }\n}","import { Broadcast, Connection, Path } from '@kixelated/moq';\nimport { EventEmitter } from './event-emitter';\nimport { MoQBroadcast } from './broadcast';\nimport { MoQSubscription } from './subscription';\nimport {\n MoQSessionConfig,\n SessionState,\n SessionStatus,\n SessionEvents,\n BroadcastConfig,\n SubscriptionConfig\n} from './types';\n\nexport class MoQSession extends EventEmitter<SessionEvents> {\n private config: MoQSessionConfig;\n private url: URL;\n private state: SessionState = SessionState.DISCONNECTED;\n private connection?: Connection.Established;\n private reconnectAttempts = 0;\n private lastError?: Error;\n private connectedAt?: Date;\n private reconnectTimer?: ReturnType<typeof setTimeout>;\n private broadcasts = new Map<string, MoQBroadcast>();\n private subscriptions = new Map<string, MoQSubscription>();\n private announcedBroadcasts = new Set<string>();\n private doReconnect = true;\n private broadcast?: Broadcast;\n\n constructor(config: MoQSessionConfig) {\n super();\n this.config = {\n ...config,\n reconnection: {\n delay: Math.max(config.reconnection?.delay || 1000, 1000), // Enforce minimum 1 second\n },\n connectionTimeout: config.connectionTimeout || 10000\n };\n\n this.url = new URL(this.config.relayUrl);\n }\n\n get status(): SessionStatus {\n return {\n state: this.state,\n reconnectAttempts: this.reconnectAttempts,\n lastError: this.lastError,\n connectedAt: this.connectedAt\n };\n }\n\n async connect(): Promise<void> {\n if (this.state === SessionState.CONNECTING || this.state === SessionState.CONNECTED) {\n return;\n }\n\n this.setState(SessionState.CONNECTING);\n\n try {\n this.doReconnect = true;\n this.connection = await Connection.connect(this.url, {\n websocket: {\n enabled: false\n }\n });\n\n this.setState(SessionState.CONNECTED);\n this.connectedAt = new Date();\n this.reconnectAttempts = 0;\n\n // Set up connection close handling\n this.connection.closed.then(() => {\n if (this.state === SessionState.CONNECTED) {\n this.handleDisconnection();\n }\n });\n\n // Start discovering announced broadcasts\n this.startAnnouncementDiscovery();\n\n // Restart all broadcasts and subscriptions\n await this.restartBroadcasts();\n await this.restartSubscriptions();\n\n } catch (error) {\n this.handleError(error as Error);\n this.scheduleReconnect();\n throw error;\n }\n }\n\n async disconnect(): Promise<void> {\n this.doReconnect = false;\n\n if (this.reconnectTimer) {\n clearTimeout(this.reconnectTimer);\n this.reconnectTimer = undefined;\n }\n\n // Stop all broadcasts and subscriptions\n await this.stopAllBroadcasts();\n await this.stopAllSubscriptions();\n\n if (this.connection) {\n try {\n this.connection.close();\n } catch (error) {\n console.warn('Error closing connection:', error);\n }\n this.connection = undefined;\n }\n\n this.setState(SessionState.DISCONNECTED);\n this.connectedAt = undefined;\n }\n\n /**\n * Get all active broadcast track names\n */\n getAllBroadcastTrackNames(): string[] {\n return Array.from(this.broadcasts.keys());\n }\n\n /**\n * Get all active subscription track names\n */\n getAllSubscriptionTrackNames(): string[] {\n return Array.from(this.subscriptions.keys());\n }\n\n /**\n * Declaratively update broadcasts - add, remove, or update broadcasts to match the desired state.\n * \n * @param configs Array of broadcast configurations representing the desired state\n */\n updateBroadcasts(configs: BroadcastConfig[]): void {\n // Check for duplicate track names in the input\n const trackNames = configs.map(config => config.trackName);\n const uniqueTrackNames = new Set(trackNames);\n if (trackNames.length !== uniqueTrackNames.size) {\n const duplicates = trackNames.filter((name, index) => trackNames.indexOf(name) !== index);\n throw new Error(`Duplicate broadcast track name: ${duplicates[0]}`);\n }\n\n const desiredTracks = new Set(configs.map(config => config.trackName));\n const currentTracks = new Set(this.broadcasts.keys());\n\n // Remove broadcasts that are no longer needed\n for (const trackName of currentTracks) {\n if (!desiredTracks.has(trackName)) {\n this._removeBroadcast(trackName);\n }\n }\n\n // Add new broadcasts or update existing ones\n for (const config of configs) {\n const existing = this.broadcasts.get(config.trackName);\n if (!existing) {\n // Create new broadcast\n this._createBroadcast(config);\n } else {\n // Update existing broadcast config if needed\n if (existing.config.priority !== config.priority) {\n // For now, we recreate if priority changed\n // In future, we could support dynamic priority updates\n this._removeBroadcast(config.trackName);\n this._createBroadcast(config);\n }\n }\n }\n }\n\n /**\n * Declaratively update subscriptions - add, remove, or update subscriptions to match the desired state.\n * \n * @param configs Array of subscription configurations representing the desired state\n */\n updateSubscriptions(configs: SubscriptionConfig[]): void {\n // Check for duplicate track names in the input\n const trackNames = configs.map(config => config.trackName);\n const uniqueTrackNames = new Set(trackNames);\n if (trackNames.length !== uniqueTrackNames.size) {\n const duplicates = trackNames.filter((name, index) => trackNames.indexOf(name) !== index);\n throw new Error(`Duplicate subscription track name: ${duplicates[0]}`);\n }\n\n const desiredTracks = new Set(configs.map(config => config.trackName));\n const currentTracks = new Set(this.subscriptions.keys());\n\n // Remove subscriptions that are no longer needed\n for (const trackName of currentTracks) {\n if (!desiredTracks.has(trackName)) {\n this._removeSubscription(trackName);\n }\n }\n\n // Add new subscriptions or update existing ones\n for (const config of configs) {\n const existing = this.subscriptions.get(config.trackName);\n if (!existing) {\n // Create new subscription\n this._createSubscription(config);\n } else {\n // Update existing subscription config if needed\n if (existing.config.priority !== config.priority || \n existing.config.retry?.delay !== config.retry?.delay) {\n // For now, we recreate if config changed\n // In future, we could support dynamic config updates\n this._removeSubscription(config.trackName);\n this._createSubscription(config);\n }\n }\n }\n }\n\n getAnnouncedBroadcasts(): string[] {\n return Array.from(this.announcedBroadcasts);\n }\n\n /**\n * Send data to a broadcast track\n * @param trackName Name of the track to send data to\n * @param data Binary data to send\n */\n async send(trackName: string, data: Uint8Array, newGroup: boolean): Promise<void> {\n const broadcast = this.broadcasts.get(trackName);\n if (!broadcast) {\n throw new Error(`No broadcast found for track: ${trackName}`);\n }\n await broadcast.send(data, newGroup);\n }\n\n /**\n * Get the status of a specific broadcast track\n * @param trackName Name of the track\n */\n getBroadcastStatus(trackName: string) {\n const broadcast = this.broadcasts.get(trackName);\n return broadcast?.status;\n }\n\n /**\n * Get the status of a specific subscription track\n * @param trackName Name of the track\n */\n getSubscriptionStatus(trackName: string) {\n const subscription = this.subscriptions.get(trackName);\n return subscription?.status;\n }\n\n private _createBroadcast(config: BroadcastConfig): MoQBroadcast {\n const broadcast = new MoQBroadcast(config);\n this.broadcasts.set(config.trackName, broadcast);\n\n // Forward broadcast events to session\n broadcast.on('stateChange', (status) => {\n this.emit('broadcastStateChange', config.trackName, status);\n });\n\n broadcast.on('error', (error) => {\n this.emit('broadcastError', config.trackName, error);\n });\n\n this.initBroadcasting();\n\n return broadcast;\n }\n\n private _createSubscription(config: SubscriptionConfig): MoQSubscription {\n const subscription = new MoQSubscription(config);\n this.subscriptions.set(config.trackName, subscription);\n\n // Forward subscription events to session\n subscription.on('data', (received) => {\n this.emit('data', received.trackName, received.data, received.frameIndex);\n });\n\n subscription.on('stateChange', (status) => {\n this.emit('subscriptionStateChange', config.trackName, status);\n });\n\n subscription.on('error', (error) => {\n this.emit('subscriptionError', config.trackName, error);\n });\n\n // Start subscription if we're connected\n if (this.state === SessionState.CONNECTED && this.connection) {\n subscription.start(this.connection, this.config.namespace).catch(error => {\n console.error('Failed to start subscription:', error);\n });\n }\n\n return subscription;\n }\n\n private _removeBroadcast(trackName: string): void {\n const broadcast = this.broadcasts.get(trackName);\n if (broadcast) {\n broadcast.stop().catch(error => {\n console.warn('Error stopping broadcast:', error);\n });\n this.broadcasts.delete(trackName);\n }\n }\n\n private _removeSubscription(trackName: string): void {\n const subscription = this.subscriptions.get(trackName);\n if (subscription) {\n subscription.stop().catch(error => {\n console.warn('Error stopping subscription:', error);\n });\n this.subscriptions.delete(trackName);\n }\n }\n\n private async startAnnouncementDiscovery(): Promise<void> {\n if (!this.connection) return;\n\n try {\n // Listen for announcements with our namespace as prefix\n const namespacePath = Path.from(this.config.namespace);\n const announced = this.connection.announced(namespacePath);\n \n // Process announcements in the background\n this.processAnnouncements(announced);\n \n } catch (error) {\n console.error('Failed to start announcement discovery:', error);\n }\n }\n\n private async processAnnouncements(announced: ReturnType<Connection.Established['announced']>): Promise<void> {\n try {\n for (;;) {\n const announcement = await announced.next();\n if (!announcement) break; // Announcements closed\n \n if (announcement.active) {\n this.announcedBroadcasts.add(announcement.path);\n this.emit('broadcastAnnounced', {\n path: announcement.path,\n active: true\n });\n } else {\n this.announcedBroadcasts.delete(announcement.path);\n this.emit('broadcastAnnounced', {\n path: announcement.path,\n active: false\n });\n }\n }\n } catch (error) {\n console.error('Error processing announcements:', error);\n }\n }\n\n private async restartBroadcasts(): Promise<void> {\n await this.stopAllBroadcasts();\n this.initBroadcasting();\n }\n\n private initBroadcasting(): void {\n if (this.broadcast) return;\n if (this.broadcasts.size === 0) return;\n\n this.broadcast = new Broadcast();\n if (this.connection) {\n this.connection.publish(Path.from(this.config.namespace), this.broadcast);\n this.handleTrackRequests().catch(error => {\n console.error('Error handling track requests:', error);\n });\n }\n }\n\n private async handleTrackRequests(): Promise<void> {\n if (!this.broadcast) return;\n \n try {\n for (;;) {\n const request = await this.broadcast.requested();\n if (!request) return; // No more requests, broadcast closed;\n const broadcast = this.broadcasts.get(request.track.name);\n if (broadcast) {\n broadcast.updateTrack(request.track);\n this.emit('trackRequested', request.track.name);\n }\n }\n\n } catch (error) {\n console.warn('Error handling track requests:', error);\n this.handleError(error as Error);\n }\n}\n\n private async restartSubscriptions(): Promise<void> {\n if (!this.connection) return;\n\n const promises = Array.from(this.subscriptions.values()).map(subscription => \n subscription.start(this.connection!, this.config.namespace).catch(error => {\n console.error('Failed to restart subscription:', error);\n })\n );\n\n await Promise.allSettled(promises);\n }\n\n private async stopAllBroadcasts(): Promise<void> {\n this.broadcast?.close();\n this.broadcast = undefined;\n const promises = Array.from(this.broadcasts.values()).map(broadcast => \n broadcast.stop().catch(error => {\n console.warn('Error stopping broadcast:', error);\n })\n );\n\n await Promise.allSettled(promises);\n }\n\n private async stopAllSubscriptions(): Promise<void> {\n const promises = Array.from(this.subscriptions.values()).map(subscription => \n subscription.stop().catch(error => {\n console.warn('Error stopping subscription:', error);\n })\n );\n\n await Promise.allSettled(promises);\n }\n\n private handleDisconnection(): void {\n this.setState(SessionState.DISCONNECTED);\n this.scheduleReconnect();\n }\n\n private scheduleReconnect(): void {\n if (!this.config.reconnection || !this.doReconnect) return;\n\n const delay = this.config.reconnection?.delay || 1000;\n\n this.setState(SessionState.RECONNECTING);\n this.reconnectAttempts++;\n\n this.reconnectTimer = setTimeout(() => {\n if (!this.doReconnect) return;\n if (this.state !== SessionState.RECONNECTING) return;\n this.connect().catch(error => {\n console.error('Reconnection failed:', error);\n });\n }, delay);\n }\n\n private setState(newState: SessionState): void {\n if (this.state !== newState) {\n this.state = newState;\n this.emit('stateChange', this.status);\n }\n }\n\n private handleError(error: Error): void {\n this.lastError = error;\n this.emit('error', error);\n }\n\n public dispose(): void {\n // Immediately stop reconnection attempts\n this.doReconnect = false;\n \n // Clear any pending reconnect timer immediately\n if (this.reconnectTimer) {\n clearTimeout(this.reconnectTimer);\n this.reconnectTimer = undefined;\n }\n \n // Disconnect (but don't await to keep dispose synchronous)\n this.disconnect().catch((error) => {\n console.warn('Error during session disconnect:', error);\n });\n this.removeAllListeners();\n\n this.subscriptions.forEach(sub => sub.dispose());\n this.broadcasts.forEach(bc => bc.dispose());\n this.subscriptions.clear();\n this.broadcasts.clear();\n }\n}"],"names":["EventEmitter","event","listener","eventListeners","args","error","SessionState","BroadcastState","SubscriptionState","MoQBroadcast","config","track","data","newGroup","newState","MoQSubscription","connection","namespace","broadcastPath","Path","framesInGroup","group","frame","receivedData","delay","_a","MoQSession","Connection","configs","trackNames","uniqueTrackNames","duplicates","name","index","desiredTracks","currentTracks","trackName","existing","_b","broadcast","subscription","status","received","namespacePath","announced","announcement","Broadcast","request","promises","sub","bc"],"mappings":"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"}
|
package/dist/session.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../src/session.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAG/C,OAAO,EACL,gBAAgB,EAEhB,aAAa,EACb,aAAa,EACb,eAAe,EACf,kBAAkB,EACnB,MAAM,SAAS,CAAC;AAEjB,qBAAa,UAAW,SAAQ,YAAY,CAAC,aAAa,CAAC;IACzD,OAAO,CAAC,MAAM,CAAmB;IACjC,OAAO,CAAC,GAAG,CAAM;IACjB,OAAO,CAAC,KAAK,CAA2C;IACxD,OAAO,CAAC,UAAU,CAAC,CAAyB;IAC5C,OAAO,CAAC,iBAAiB,CAAK;IAC9B,OAAO,CAAC,SAAS,CAAC,CAAQ;IAC1B,OAAO,CAAC,WAAW,CAAC,CAAO;IAC3B,OAAO,CAAC,cAAc,CAAC,CAAgC;IACvD,OAAO,CAAC,UAAU,CAAmC;IACrD,OAAO,CAAC,aAAa,CAAsC;IAC3D,OAAO,CAAC,mBAAmB,CAAqB;IAChD,OAAO,CAAC,WAAW,CAAQ;IAC3B,OAAO,CAAC,SAAS,CAAC,CAAY;gBAElB,MAAM,EAAE,gBAAgB;IAapC,IAAI,MAAM,IAAI,aAAa,CAO1B;IAEK,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../src/session.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAG/C,OAAO,EACL,gBAAgB,EAEhB,aAAa,EACb,aAAa,EACb,eAAe,EACf,kBAAkB,EACnB,MAAM,SAAS,CAAC;AAEjB,qBAAa,UAAW,SAAQ,YAAY,CAAC,aAAa,CAAC;IACzD,OAAO,CAAC,MAAM,CAAmB;IACjC,OAAO,CAAC,GAAG,CAAM;IACjB,OAAO,CAAC,KAAK,CAA2C;IACxD,OAAO,CAAC,UAAU,CAAC,CAAyB;IAC5C,OAAO,CAAC,iBAAiB,CAAK;IAC9B,OAAO,CAAC,SAAS,CAAC,CAAQ;IAC1B,OAAO,CAAC,WAAW,CAAC,CAAO;IAC3B,OAAO,CAAC,cAAc,CAAC,CAAgC;IACvD,OAAO,CAAC,UAAU,CAAmC;IACrD,OAAO,CAAC,aAAa,CAAsC;IAC3D,OAAO,CAAC,mBAAmB,CAAqB;IAChD,OAAO,CAAC,WAAW,CAAQ;IAC3B,OAAO,CAAC,SAAS,CAAC,CAAY;gBAElB,MAAM,EAAE,gBAAgB;IAapC,IAAI,MAAM,IAAI,aAAa,CAO1B;IAEK,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAwCxB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAyBjC;;OAEG;IACH,yBAAyB,IAAI,MAAM,EAAE;IAIrC;;OAEG;IACH,4BAA4B,IAAI,MAAM,EAAE;IAIxC;;;;OAIG;IACH,gBAAgB,CAAC,OAAO,EAAE,eAAe,EAAE,GAAG,IAAI;IAqClD;;;;OAIG;IACH,mBAAmB,CAAC,OAAO,EAAE,kBAAkB,EAAE,GAAG,IAAI;IAsCxD,sBAAsB,IAAI,MAAM,EAAE;IAIlC;;;;OAIG;IACG,IAAI,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAQjF;;;OAGG;IACH,kBAAkB,CAAC,SAAS,EAAE,MAAM;IAKpC;;;OAGG;IACH,qBAAqB,CAAC,SAAS,EAAE,MAAM;IAKvC,OAAO,CAAC,gBAAgB;IAkBxB,OAAO,CAAC,mBAAmB;IA2B3B,OAAO,CAAC,gBAAgB;IAUxB,OAAO,CAAC,mBAAmB;YAUb,0BAA0B;YAgB1B,oBAAoB;YAyBpB,iBAAiB;IAK/B,OAAO,CAAC,gBAAgB;YAaV,mBAAmB;YAoBnB,oBAAoB;YAYpB,iBAAiB;YAYjB,oBAAoB;IAUlC,OAAO,CAAC,mBAAmB;IAK3B,OAAO,CAAC,iBAAiB;IAiBzB,OAAO,CAAC,QAAQ;IAOhB,OAAO,CAAC,WAAW;IAKZ,OAAO,IAAI,IAAI;CAqBvB"}
|