@urun-sh/core 0.1.36 → 0.1.38

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.mjs CHANGED
@@ -1 +1 @@
1
- import{a as M,b as v,c as k}from"./chunk-FTLHEH7Y.mjs";var H="session-api.prod.cloud.urun.sh",K=["https://session-api.use2.prod.cloud.urun.sh","https://session-api.usw2.prod.cloud.urun.sh"];function b(n){return n.trim().replace(/\/+$/,"")}function C(n,e){let t=[],r=s=>{if(!s)return;let o=b(s);o&&!t.includes(o)&&t.push(o)};r(n);for(let s of e??[])r(s);for(let s of ee(n))r(s);return t}var q=120,V=1e3,W=3;function Y(n){if(!n)return null;try{let e=new URL(n),t=e.pathname.replace(/\/api\/sessions\/create\/?$/,"");return b(`${e.origin}${t}`)}catch{return null}}async function D(n){let e=C(n.baseUrl,n.fallbackUrls),t=null,r=e.length>1;for(let s of e)try{return await z(s,n,{pollAttempts:q,retryAfterLimitMs:r?V:void 0})}catch(o){if(t=o instanceof Error?o:new Error(String(o)),t instanceof w)throw t}throw t??new Error("[urun] session allocation failed")}async function z(n,e,t){let r,s,o,i=n,l=0,h=new Set;for(let p=0;p<t.pollAttempts;p++){s=o??await E(e),o=void 0;let d=r?await fetch(`${i}/api/session-requests/${encodeURIComponent(r)}`,{headers:A(e,s)}):await fetch(`${i}/api/sessions/create`,{method:"POST",redirect:"manual",headers:{...A(e,s),"Content-Type":"application/json","Idempotency-Key":e.idempotencyKey},body:JSON.stringify(X(e))});if(!r&&(d.status===307||d.status===308)){let u=Y(d.headers.get("location"));if(u&&u!==i&&l<W){l+=1,i=u;continue}throw new Error(`[urun] session create redirected from ${i} without a usable target`)}let a=await j(d);if(d.ok&&(a.status==="allocated"||!a.status&&!!a.session_id)&&!!a.session_id){let u=a.session_id;if(!a.ws_url)throw new w(`[urun] gateway allocated session ${u} without ws_url`);if(!$(a.ws_url))throw new w(`[urun] gateway allocated session ${u} with non-absolute ws_url`);return{baseUrl:i,sessionId:u,wsUrl:a.ws_url,response:a}}if(d.status===202||a.status==="pending"||a.status==="queued"||a.queued){if(r=a.request_id||r,!r)throw new Error("[urun] gateway queued session without request_id");await Z(Q(d,a,t.retryAfterLimitMs));continue}if((d.status===401||d.status===403)&&e.getAccessToken){let u=s??"";h.add(u);let _=await E(e,{forceRefresh:!0,reason:"unauthorized"});if(_&&!h.has(_)){o=_,r=void 0;continue}}let m=a.error_message||a.error_code||`HTTP ${d.status}`;throw new Error(`[urun] session allocation failed at ${i}: ${m}`)}throw new Error(`[urun] timed out waiting for session allocation at ${i}`)}function A(n,e){let t={"X-Tenant-Id":n.orgId,"X-Auth-Provider":n.authProvider||"default","X-User-Id":"anonymous"};return e&&(t.Authorization=`Bearer ${e}`),t}async function E(n,e){return n.getAccessToken?await n.getAccessToken(e)??void 0:n.jwt}function X(n){return{app:n.app,function:n.functionName,gpus:1,idempotency_key:n.idempotencyKey}}async function L(n){let e=C(n.baseUrl,n.fallbackUrls),t=null;for(let r of e)try{let s={baseUrl:r,app:"",functionName:"",orgId:n.orgId,jwt:n.jwt,getAccessToken:n.getAccessToken,authProvider:n.authProvider,idempotencyKey:""},o=await E(s),i=await fetch(`${b(r)}/api/sessions/${encodeURIComponent(n.sessionId)}/viewer-connect`,{headers:A(s,o)});if(!i.ok)throw new Error(`[urun] viewer-connect for ${n.sessionId} failed: HTTP ${i.status}`);let l=await j(i);if(!l.ws_url||!$(l.ws_url))throw new w(`[urun] viewer-connect returned no usable ws_url for ${n.sessionId}`);return{baseUrl:b(r),sessionId:n.sessionId,wsUrl:l.ws_url,response:l}}catch(s){if(t=s instanceof Error?s:new Error(String(s)),t instanceof w)throw t}throw t??new Error("[urun] viewer-connect failed")}async function j(n){try{let e=await n.json();return e&&typeof e=="object"?e:{}}catch{return{}}}function Q(n,e,t){let r=Number(n.headers.get("Retry-After")||""),s=Number(e.retry_after_seconds??r),o=t??1e4;return Number.isFinite(s)&&s>0?Math.min(s*1e3,o):1e3}function Z(n){return new Promise(e=>setTimeout(e,n))}var w=class extends Error{};function $(n){try{let e=new URL(n);return e.protocol==="ws:"||e.protocol==="wss:"}catch{return!1}}function ee(n){try{return new URL(n).hostname!==H?[]:K}catch{return[]}}import*as g from"yjs";var N=Symbol("urun:doc:remote"),te=Symbol("urun:doc:local");function R(n){return n!==null&&typeof n=="object"&&!Array.isArray(n)}function P(n,e){let t={...n};for(let r of Object.keys(e)){let s=e[r],o=t[r];R(s)&&R(o)?t[r]=P(o,s):t[r]=s}return t}function re(n,e){let t=e.split("."),r=n;for(let s of t){if(r==null||typeof r!="object")return;r=r[s]}return r}function B(n){return n===void 0?n:JSON.parse(JSON.stringify(n))}var I=class{_doc=new g.Doc;_root=this._doc.getMap("session");_listeners=new Set;_key;_sessionId;_transport;_transportUnsubs=[];_synced;_pendingPatches=[];_observer=()=>this.notify();_updateHandler=(e,t)=>{t!==N&&this._transport?.sendDocSync(e)};constructor(e,t,r){this._key=e,this._sessionId=t,this._transport=r??null,this._synced=this._transport===null,this._root.observeDeep(this._observer),this._doc.on("update",this._updateHandler),this._transport&&(this._transportUnsubs.push(this._transport.onDocSync(s=>this.applyRemote(s)),this._transport.onDocSyncReady(()=>this.sendHello())),this._transport.isOpen&&this.sendHello())}setSessionId(e){this._sessionId=e}set(e){if(!this._synced){this._pendingPatches.push(B(e)),this.notify();return}this.applyPatch(e)}get(e,t){let r=this.snapshot();return e?re(r,e)??t:r}on(e,t){return this._listeners.add(t),()=>this._listeners.delete(t)}dispose(){this._root.unobserveDeep(this._observer),this._doc.off("update",this._updateHandler);for(let e of this._transportUnsubs)e();this._transportUnsubs=[],this._transport=null,this._listeners.clear(),this._doc.destroy()}sendHello(){this._transport&&this._transport.sendDocSync(g.encodeStateAsUpdate(this._doc))}applyRemote(e){if(g.applyUpdate(this._doc,e,N),!this._synced){this._synced=!0;let t=this._pendingPatches.splice(0);for(let r of t)this.applyPatch(r)}}applyPatch(e){this._doc.transact(()=>{let t=this._root.toJSON();for(let[r,s]of Object.entries(e)){let o=t[r],i=R(s)&&R(o)?P(o,s):B(s);JSON.stringify(i)!==JSON.stringify(o)&&this._root.set(r,i)}},te)}snapshot(){let e=this._root.toJSON();for(let t of this._pendingPatches)e=P(e,t);return e}notify(){let e=this.snapshot();for(let t of this._listeners)t(e)}};var ne=new Set(["control"]),O=class{constructor(e,t){this._name=e;this._transport=t;this._track=this._transport.getTrackByName(this._name)??null,this._unsubscribeTransport=this._transport.on("track",()=>{let r=this._transport.getTrackByName(this._name)??null;r!==this._track&&this._setTrack(r)})}_name;_transport;_track=null;_handlers=new Map;_unsubscribeTransport=null;get track(){let e=this._transport.getTrackByName(this._name)??this._track;return e!==this._track&&this._setTrack(e),this._track}async attach(e){await this._transport.addTrack(e)}async detach(){this._transport.removeTrack()}async seek(e){if(e!=="live"&&(!Number.isFinite(e)||e<0))throw new Error('[urun] stream.seek target must be "live" or a non-negative number of seconds');this._transport.seekStream(this._name,e)}on(e,t){let r=this._handlers.get(e);return r||(r=new Set,this._handlers.set(e,r)),r.add(t),()=>{r?.delete(t),r?.size===0&&this._handlers.delete(e)}}dispose(){this._unsubscribeTransport?.(),this._unsubscribeTransport=null,this._handlers.clear()}_setTrack(e){this._track=e,e&&e.addEventListener("ended",()=>{this._track===e&&this._setTrack(null)},{once:!0});let t=this._handlers.get("track");if(t)for(let r of t)r(e)}},S=class n{_sessionId;_multiplexer;_transport;_docs=new Map;_streams=new Map;constructor(e,t,r){this._sessionId=e,this._multiplexer=t,this._transport=r,this._wireControlDocIncarnation()}_wireControlDocIncarnation(){let e=this.doc("control");this._transport.applyControlDocState(e.get()),e.on("change",t=>{this._transport.applyControlDocState(t)})}static async attach(e,t){let r=await L({baseUrl:t.baseUrl,fallbackUrls:t.fallbackUrls,sessionId:e,orgId:t.orgId,jwt:t.jwt,getAccessToken:t.getAccessToken,authProvider:t.authProvider}),s=t.getAccessToken?await t.getAccessToken()??void 0:t.jwt,o=new v,i=new k({url:r.wsUrl,orgId:t.orgId,jwt:s,authProvider:t.authProvider,sessionId:e}),l=new n(e,o,i);return i.on("connected",()=>{i.multiplexer&&o.setTarget(i.multiplexer)}),i.setConnection({url:r.wsUrl,sessionId:e}),await i.connect({role:"viewer"}),l}get id(){return this._sessionId}get phase(){return this._transport.phase}onPhase(e){return e(this._transport.phase),this._transport.on("phase",e)}setSessionId(e){if(e===this._sessionId)return;this._multiplexer.rewriteSessionChannels?.call(this._multiplexer,this._sessionId,e),this._sessionId=e;for(let r of this._docs.values())r.setSessionId(e)}stream(e){let t=this._streams.get(e);return t||(t=new O(e,this._transport),this._streams.set(e,t)),t}doc(e){let t=this._docs.get(e);return t||(t=new I(e,this._sessionId,ne.has(e)?this._transport:null),this._docs.set(e,t)),t}disconnect(){for(let e of this._docs.values())e.dispose();this._docs.clear();for(let e of this._streams.values())e.dispose();this._streams.clear(),this._transport.disconnect()}};var se=new Set(["then","catch","finally","toJSON",Symbol.toPrimitive]);function oe(n,e){return new Proxy({},{get(t,r){if(!(se.has(r)||typeof r!="string"))return s=>{let o=s??{},i=()=>`s_${Date.now()}_${Math.random().toString(36).slice(2)}`,l=i(),h=new v,p=new k({url:"",orgId:e.orgId,jwt:e.jwt,authProvider:e.authProvider,sessionId:l}),d=new S(l,h,p),a=async c=>{let m=await D({baseUrl:e.baseUrl,fallbackUrls:e.fallbackUrls,app:n,functionName:r,orgId:e.orgId,jwt:e.jwt,getAccessToken:e.getAccessToken,authProvider:e.authProvider,idempotencyKey:c}),u=e.getAccessToken?await e.getAccessToken()??void 0:e.jwt;return d.setSessionId(m.sessionId),{url:m.wsUrl,sessionId:m.sessionId,jwt:u}};return p.setConnectionResolver(()=>a(i())),p.on("connected",()=>{p.multiplexer&&h.setTarget(p.multiplexer)}),(async()=>{let c=await a(l);p.setAuth({jwt:c.jwt,authProvider:e.authProvider,orgId:e.orgId}),p.setConnection({url:c.url,sessionId:c.sessionId}),await p.connect({app:n,functionName:r,args:o})})().catch(c=>{console.error(`[urun] Failed to connect session for ${r}:`,c)}),d}}})}var G=3e4,F="stream:",x=class{_ws;_multiplexer;_pendingRpc=new Map;_rpcId=0;constructor(e,t){this._ws=e,this._multiplexer=t,this._ws.addEventListener("message",r=>{let s;try{s=JSON.parse(typeof r.data=="string"?r.data:"")}catch{return}if(s.rpcId&&this._pendingRpc.has(s.rpcId)){let o=this._pendingRpc.get(s.rpcId);this._pendingRpc.delete(s.rpcId),clearTimeout(o.timer),s.error?o.reject(new Error(s.error)):o.resolve(s.result)}})}async get(e){return this._sendRpc("store.get",{key:e})}async has(e){return await this._sendRpc("store.has",{key:e})}on(e,t){let r=`${F}${e}`;return this._multiplexer.on(r,s=>{t(s)})}emit(e,t){let r=`${F}${e}`,s=typeof t=="object"&&t!==null&&!Array.isArray(t)?t:{data:t};this._multiplexer.emit(r,s)}_getInternals(){return{multiplexer:this._multiplexer,ws:this._ws}}_sendRpc(e,t){return new Promise((r,s)=>{if(!this._ws||this._ws.readyState!==WebSocket.OPEN){s(new Error("WebSocket not open"));return}let o=String(++this._rpcId),i=setTimeout(()=>{this._pendingRpc.has(o)&&(this._pendingRpc.delete(o),s(new Error(`RPC request "${e}" timed out after ${G}ms`)))},G);this._pendingRpc.set(o,{resolve:r,reject:s,timer:i}),this._ws.send(JSON.stringify({rpcId:o,type:e,...t}))})}};function ie(n){let r=`${n.baseUrl.replace(/\/$/,"").replace(/^http/,"ws")}/store/${encodeURIComponent(n.orgId)}`,s=new WebSocket(r);(n.jwt||n.apiKey)&&s.addEventListener("open",()=>{s.send(JSON.stringify({type:"auth",orgId:n.orgId,jwt:n.jwt,authProvider:n.authProvider,apiKey:n.apiKey}))});let o=new M(s);return new x(s,o)}var ae='video/mp4; codecs="avc1.42E01E"';function ce(n,e){let t=e?.codec??ae,r=document.createElement("video");r.muted=!0,r.playsInline=!0;let s=new MediaSource,o=URL.createObjectURL(s);r.src=o,s.addEventListener("sourceopen",()=>{let c;try{c=s.addSourceBuffer(t)}catch(f){throw f instanceof DOMException&&f.name==="NotSupportedError"?new Error(`Codec not supported: "${t}". Ensure the codec string matches the fMP4 container format. Common values: video/mp4; codecs="avc1.42E01E" (H.264 Baseline), video/mp4; codecs="avc1.4D401F" (H.264 Main).`):f}let m=n.getReader();function u(){return c.updating?new Promise(f=>{c.addEventListener("updateend",()=>f(),{once:!0})}):Promise.resolve()}async function _(){try{for(;;){let{done:f,value:U}=await m.read();if(f){await u(),s.readyState==="open"&&s.endOfStream();return}await u();try{c.appendBuffer(U)}catch(y){if(y instanceof DOMException&&y.name==="QuotaExceededError"){let T=c.buffered;if(T.length>0){let J=T.start(T.length-1);c.remove(0,J),await u(),c.appendBuffer(U)}else throw y}else throw y}}}catch{if(s.readyState==="open")try{s.endOfStream("decode")}catch{}}}_()}),r.play().catch(()=>{});let i=r,l=i.captureStream??i.mozCaptureStream;if(!l)throw new Error("captureStream() is not supported in this browser. videoStream() requires HTMLMediaElement.captureStream() support.");let h=l.call(r),p=h.getTracks(),d=0,a=p.length;if(a===0)r.addEventListener("emptied",()=>{URL.revokeObjectURL(o)},{once:!0});else for(let c of p)c.addEventListener("ended",()=>{d++,d>=a&&URL.revokeObjectURL(o)});return h}export{oe as App,S as Session,ie as createStore,ce as videoStream};
1
+ import{a as W,b as U,e as M}from"./chunk-LBV7WHPF.mjs";var ae="session-api.prod.cloud.urun.sh",ce=["https://session-api.use2.prod.cloud.urun.sh","https://session-api.usw2.prod.cloud.urun.sh"];function C(r){return r.trim().replace(/\/+$/,"")}function V(r,e){let t=[],n=s=>{if(!s)return;let o=C(s);o&&!t.includes(o)&&t.push(o)};n(r);for(let s of e??[])n(s);for(let s of we(r))n(s);return t}var ue=120,le=1e3,de=3;function pe(r){if(!r)return null;try{let e=new URL(r),t=e.pathname.replace(/\/api\/sessions\/create\/?$/,"");return C(`${e.origin}${t}`)}catch{return null}}async function z(r){let e=V(r.baseUrl,r.fallbackUrls),t=null,n=e.length>1;for(let s of e)try{return await fe(s,r,{pollAttempts:ue,retryAfterLimitMs:n?le:void 0})}catch(o){if(t=o instanceof Error?o:new Error(String(o)),t instanceof R)throw t}throw t??new Error("[urun] session allocation failed")}async function fe(r,e,t){let n,s,o,i=r,l=0,h=new Set;for(let d=0;d<t.pollAttempts;d++){s=o??await $(e),o=void 0;let a=n?await fetch(`${i}/api/session-requests/${encodeURIComponent(n)}`,{headers:j(e,s)}):await fetch(`${i}/api/sessions/create`,{method:"POST",redirect:"manual",headers:{...j(e,s),"Content-Type":"application/json","Idempotency-Key":e.idempotencyKey},body:JSON.stringify(he(e))});if(!n&&(a.status===307||a.status===308)){let f=pe(a.headers.get("location"));if(f&&f!==i&&l<de){l+=1,i=f;continue}throw new Error(`[urun] session create redirected from ${i} without a usable target`)}let u=await Q(a);if(a.ok&&(u.status==="allocated"||!u.status&&!!u.session_id)&&!!u.session_id){let f=u.session_id;if(!u.ws_url)throw new R(`[urun] gateway allocated session ${f} without ws_url`);if(!Z(u.ws_url))throw new R(`[urun] gateway allocated session ${f} with non-absolute ws_url`);return{baseUrl:i,sessionId:f,wsUrl:u.ws_url,response:u}}if(a.status===202||u.status==="pending"||u.status==="queued"||u.queued){if(n=u.request_id||n,!n)throw new Error("[urun] gateway queued session without request_id");await ge(me(a,u,t.retryAfterLimitMs));continue}if((a.status===401||a.status===403)&&e.getAccessToken){let f=s??"";h.add(f);let w=await $(e,{forceRefresh:!0,reason:"unauthorized"});if(w&&!h.has(w)){o=w,n=void 0;continue}}let g=u.error_message||u.error_code||`HTTP ${a.status}`;throw new Error(`[urun] session allocation failed at ${i}: ${g}`)}throw new Error(`[urun] timed out waiting for session allocation at ${i}`)}function j(r,e){let t={"X-Tenant-Id":r.orgId,"X-Auth-Provider":r.authProvider||"default","X-User-Id":"anonymous"};return e&&(t.Authorization=`Bearer ${e}`),t}async function $(r,e){return r.getAccessToken?await r.getAccessToken(e)??void 0:r.jwt}function he(r){return{app:r.app,function:r.functionName,gpus:1,idempotency_key:r.idempotencyKey}}async function X(r){let e=V(r.baseUrl,r.fallbackUrls),t=null;for(let n of e)try{let s={baseUrl:n,app:"",functionName:"",orgId:r.orgId,jwt:r.jwt,getAccessToken:r.getAccessToken,authProvider:r.authProvider,idempotencyKey:""},o=await $(s),i=await fetch(`${C(n)}/api/sessions/${encodeURIComponent(r.sessionId)}/viewer-connect`,{headers:j(s,o)});if(!i.ok)throw new Error(`[urun] viewer-connect for ${r.sessionId} failed: HTTP ${i.status}`);let l=await Q(i);if(!l.ws_url||!Z(l.ws_url))throw new R(`[urun] viewer-connect returned no usable ws_url for ${r.sessionId}`);return{baseUrl:C(n),sessionId:r.sessionId,wsUrl:l.ws_url,response:l}}catch(s){if(t=s instanceof Error?s:new Error(String(s)),t instanceof R)throw t}throw t??new Error("[urun] viewer-connect failed")}async function Q(r){try{let e=await r.json();return e&&typeof e=="object"?e:{}}catch{return{}}}function me(r,e,t){let n=Number(r.headers.get("Retry-After")||""),s=Number(e.retry_after_seconds??n),o=t??1e4;return Number.isFinite(s)&&s>0?Math.min(s*1e3,o):1e3}function ge(r){return new Promise(e=>setTimeout(e,r))}var R=class extends Error{};function Z(r){try{let e=new URL(r);return e.protocol==="ws:"||e.protocol==="wss:"}catch{return!1}}function we(r){try{return new URL(r).hostname!==ae?[]:ce}catch{return[]}}import*as T from"yjs";var ee=Symbol("urun:doc:remote"),_e=Symbol("urun:doc:local");function q(r){return r!==null&&typeof r=="object"&&!Array.isArray(r)}function N(r,e){let t={...r};for(let n of Object.keys(e)){let s=e[n],o=t[n];q(s)&&q(o)?t[n]=N(o,s):t[n]=s}return t}function ve(r,e){let t=e.split("."),n=r;for(let s of t){if(n==null||typeof n!="object")return;n=n[s]}return n}function te(r){return r===void 0?r:JSON.parse(JSON.stringify(r))}var L=class{_doc=new T.Doc;_root=this._doc.getMap("session");_listeners=new Set;_key;_sessionId;_transport;_transportUnsubs=[];_synced;_pendingPatches=[];_texts=new Map;_observer=()=>this.notify();_updateHandler=(e,t)=>{t!==ee&&this._transport?.sendDocSync(this._key,e)};constructor(e,t,n){this._key=e,this._sessionId=t,this._transport=n??null,this._synced=this._transport===null,this._root.observeDeep(this._observer),this._doc.on("update",this._updateHandler),this._transport&&(this._transportUnsubs.push(this._transport.onDocSync(this._key,s=>this.applyRemote(s)),this._transport.onDocSyncReady(()=>this.sendHello())),this._transport.isOpen&&this.sendHello())}setSessionId(e){this._sessionId=e}set(e){if(!this._synced){this._pendingPatches.push(te(e)),this.notify();return}this.applyPatch(e)}get(e,t){let n=this.snapshot();return e?ve(n,e)??t:n}on(e,t){return this._listeners.add(t),()=>this._listeners.delete(t)}text(e){let t=this._texts.get(e);return t||(t=new B(this._doc.getText(`text:${e}`)),this._texts.set(e,t)),t}dispose(){this._root.unobserveDeep(this._observer),this._doc.off("update",this._updateHandler);for(let e of this._transportUnsubs)e();this._transportUnsubs=[],this._transport=null,this._listeners.clear();for(let e of this._texts.values())e.dispose();this._texts.clear(),this._doc.destroy()}sendHello(){this._transport&&this._transport.sendDocSync(this._key,T.encodeStateAsUpdate(this._doc))}applyRemote(e){if(T.applyUpdate(this._doc,e,ee),!this._synced){this._synced=!0;let t=this._pendingPatches.splice(0);for(let n of t)this.applyPatch(n)}}applyPatch(e){this._doc.transact(()=>{let t=this._root.toJSON();for(let[n,s]of Object.entries(e)){let o=t[n],i=q(s)&&q(o)?N(o,s):te(s);JSON.stringify(i)!==JSON.stringify(o)&&this._root.set(n,i)}},_e)}snapshot(){let e=this._root.toJSON();for(let t of this._pendingPatches)e=N(e,t);return e}notify(){let e=this.snapshot();for(let t of this._listeners)t(e)}},B=class{constructor(e){this._ytext=e;this._observer=t=>{for(let n of t.delta)if(typeof n.insert=="string"&&n.insert.length>0){let s=n.insert;for(let o of this._delta)o(s)}},this._ytext.observe(this._observer)}_ytext;_delta=new Set;_observer;append(e){e.length!==0&&this._ytext.insert(this._ytext.length,e)}toString(){return this._ytext.toString()}get length(){return this._ytext.length}on(e,t){return this._delta.add(t),()=>this._delta.delete(t)}dispose(){this._ytext.unobserve(this._observer),this._delta.clear()}};var S=class extends Error{requestId;code;constructor(e,t){super(e),this.name="RequestError",this.requestId=t?.requestId,this.code=t?.code,t?.cause!==void 0&&(this.cause=t.cause),Object.setPrototypeOf(this,new.target.prototype)}},x=class extends S{timeoutMs;constructor(e,t){super(`[urun] request timed out after ${e}ms`,{requestId:t}),this.name="RequestTimeoutError",this.timeoutMs=e,Object.setPrototypeOf(this,new.target.prototype)}},k=class extends S{constructor(e){super("[urun] request aborted",{requestId:e}),this.name="RequestAbortError",Object.setPrototypeOf(this,new.target.prototype)}},E=class extends S{constructor(e){super("[urun] request cancelled: session disconnected",{requestId:e}),this.name="RequestCancelledError",Object.setPrototypeOf(this,new.target.prototype)}};var ye=new Set,Se="rpc",be="llm",ke="llm-resp";function Re(r){return`${ke}:${r}`}function F(){let r=globalThis.crypto;return r?.randomUUID?r.randomUUID():`req_${Date.now().toString(36)}_${Math.random().toString(36).slice(2)}`}function Ie(r){if(r&&typeof r=="object"){let e=r.error;if(e&&typeof e=="object"){let{message:t,code:n}=e;return{message:typeof t=="string"?t:JSON.stringify(e),code:typeof n=="string"?n:void 0}}if(typeof e=="string")return{message:e}}return{message:typeof r=="string"?r:JSON.stringify(r)}}function Ae(r,e,t,n,s,o,i,l){let h=[],d=null,a=!1,u=null,p=!1,g,f,w=new Promise((c,b)=>{g=c,f=b});w.catch(()=>{});let _=o(),v=null,m=null,y=!0,I=()=>{y=!1,v?.(),v=null,m?.(),m=null,i?.removeEventListener("abort",Y),_.dispose(),p&&r.set({requests:{[e]:null}})},D=()=>{if(d){if(h.length>0){let c=d;d=null,c.resolve({value:h.shift(),done:!1})}else if(u!==null){let c=d;d=null,c.reject(u)}else if(a){let c=d;d=null,c.resolve({value:void 0,done:!0})}}},re=c=>{a||(h.push(c),D())},P=c=>{a||(u=c,a=!0,f(c),I(),D())},G=c=>{a||(a=!0,g(c),I(),D())},Y=()=>P(new k(e)),oe=c=>{if(!(a||!c||typeof c!="object"))switch(c.t){case"delta":typeof c.delta=="string"&&re(c.delta);break;case"response":G(c.body);break;case"error":{let{message:b,code:A}=Ie(c.body);P(new S(b,{requestId:e,code:c.code??A}));break}}},ie=()=>{let c=_.messages()[Symbol.asyncIterator]();v=()=>{c.return?.(void 0)};let b=()=>{y&&c.next().then(A=>{if(y){if(A.done){a||G(void 0);return}oe(A.value),b()}},A=>{y&&P(A)})};b()},H=()=>{if(!p){if(p=!0,i){if(i.aborted){P(new k(e));return}i.addEventListener("abort",Y,{once:!0})}m=l?.(c=>P(c))??null,ie(),r.set({requests:{[e]:{payload:t,consumer_id:n,stream:s}}})}};return{deltas:{[Symbol.asyncIterator](){return{next(){if(H(),h.length>0)return Promise.resolve({value:h.shift(),done:!1});if(u!==null){let c=u;return u=null,Promise.reject(c)}return a?Promise.resolve({value:void 0,done:!0}):new Promise((c,b)=>{d={resolve:c,reject:b}})},return(){return a||(a=!0,g(void 0),I()),Promise.resolve({value:void 0,done:!0})},throw(c){return a||(a=!0,f(c),I()),Promise.reject(c)}}}},body:w,start:H}}function Te(r,e){return[`streams/${r}/${e}`,`streams/${r}/*`]}var K=class{constructor(e,t,n){this._name=e;this._transport=t;this._laneDoc=n;this._track=this._transport.getTrackByName(this._name)??null,this._unsubscribeTransport=this._transport.on("track",()=>{let s=this._transport.getTrackByName(this._name)??null;s!==this._track&&this._setTrack(s)})}_name;_transport;_laneDoc;_track=null;_handlers=new Map;_unsubscribeTransport=null;_subscribed=!1;_messageConsumers=new Set;_laneUnsubs=[];_laneSeen=new Map;_disposed=!1;messages(){this._ensureSubscribed();let e=this;return{[Symbol.asyncIterator](){let t=[],n=null,s=!1,o={push(l){if(!s)if(n){let h=n;n=null,h({value:l,done:!1})}else t.push(l)},end(){if(s=!0,n){let l=n;n=null,l({value:void 0,done:!0})}}};e._messageConsumers.add(o);let i=()=>{s=!0,e._messageConsumers.delete(o)};return{next(){return t.length>0?Promise.resolve({value:t.shift(),done:!1}):s?Promise.resolve({value:void 0,done:!0}):new Promise(l=>{n=l})},return(){return i(),Promise.resolve({value:void 0,done:!0})}}}}}_ensureSubscribed(){if(!(this._subscribed||this._disposed)&&(this._subscribed=!0,this._transport.subscribeStream(this._name),!!this._laneDoc))for(let e of Te(this._name,this._transport.consumerId)){let t=this._laneDoc(e);this._laneSeen.set(e,0);let n=s=>this._drainLane(e,s);n(t.get()),this._laneUnsubs.push(t.on("change",n))}}_drainLane(e,t){let n=t.messages;if(!Array.isArray(n))return;let s=this._laneSeen.get(e)??0;for(;s<n.length;s++){let o=n[s];for(let i of this._messageConsumers)i.push(o)}this._laneSeen.set(e,s)}get track(){let e=this._transport.getTrackByName(this._name)??this._track;return e!==this._track&&this._setTrack(e),this._track}async attach(e){await this._transport.addTrack(e)}async detach(){this._transport.removeTrack()}async seek(e){if(e!=="live"&&(!Number.isFinite(e)||e<0))throw new Error('[urun] stream.seek target must be "live" or a non-negative number of seconds');this._transport.seekStream(this._name,e)}on(e,t){let n=this._handlers.get(e);return n||(n=new Set,this._handlers.set(e,n)),n.add(t),()=>{n?.delete(t),n?.size===0&&this._handlers.delete(e)}}dispose(){this._disposed=!0,this._unsubscribeTransport?.(),this._unsubscribeTransport=null,this._handlers.clear(),this._subscribed&&this._transport.unsubscribeStream(this._name);for(let e of this._laneUnsubs)e();this._laneUnsubs=[];for(let e of this._messageConsumers)e.end();this._messageConsumers.clear()}_setTrack(e){this._track=e,e&&e.addEventListener("ended",()=>{this._track===e&&this._setTrack(null)},{once:!0});let t=this._handlers.get("track");if(t)for(let n of t)n(e)}},O=class r{_sessionId;_multiplexer;_transport;_docs=new Map;_streams=new Map;_activeRequests=new Set;constructor(e,t,n){this._sessionId=e,this._multiplexer=t,this._transport=n,this._wireControlDocIncarnation()}_wireControlDocIncarnation(){let e=this.doc("control");this._transport.applyControlDocState(e.get()),e.on("change",t=>{this._transport.applyControlDocState(t)})}static async attach(e,t){let n=await X({baseUrl:t.baseUrl,fallbackUrls:t.fallbackUrls,sessionId:e,orgId:t.orgId,jwt:t.jwt,getAccessToken:t.getAccessToken,authProvider:t.authProvider}),s=t.getAccessToken?await t.getAccessToken()??void 0:t.jwt,o=new U,i=new M({url:n.wsUrl,orgId:t.orgId,jwt:s,authProvider:t.authProvider,sessionId:e}),l=new r(e,o,i);return i.on("connected",()=>{i.multiplexer&&o.setTarget(i.multiplexer)}),i.setConnection({url:n.wsUrl,sessionId:e}),await i.connect({role:"viewer"}),l}get id(){return this._sessionId}get phase(){return this._transport.phase}onPhase(e){return e(this._transport.phase),this._transport.on("phase",e)}setSessionId(e){if(e===this._sessionId)return;this._multiplexer.rewriteSessionChannels?.call(this._multiplexer,this._sessionId,e),this._sessionId=e;for(let n of this._docs.values())n.setSessionId(e)}stream(e){let t=this._streams.get(e);return t||(t=new K(e,this._transport,n=>this.doc(n)),this._streams.set(e,t)),t}doc(e){let t=this._docs.get(e);return t||(t=new L(e,this._sessionId,ye.has(e)?null:this._transport),this._docs.set(e,t)),t}request(e,t={}){let n=this.doc(Se),s=F();return new Promise((o,i)=>{let l=!1,h=null,d=null,a=null,u=()=>{d&&(clearTimeout(d),d=null),h&&(h(),h=null),a&&(this._activeRequests.delete(a),a=null),t.signal?.removeEventListener("abort",g),n.set({requests:{[s]:null}})},p=w=>{l||(l=!0,u(),w())},g=()=>p(()=>i(new k(s)));if(t.signal){if(t.signal.aborted){l=!0,i(new k(s));return}t.signal.addEventListener("abort",g,{once:!0})}let f=w=>{let v=w.responses?.[s];if(v==null)return;let m=v;if(m.error!==void 0&&m.error!==null){let y=typeof m.error=="string"?m.error:JSON.stringify(m.error);p(()=>i(new S(y,{requestId:s,code:m.code})))}else p(()=>o(m.result))};h=n.on("change",f),a=w=>p(()=>i(w)),this._activeRequests.add(a),typeof t.timeout=="number"&&t.timeout>=0&&(d=setTimeout(()=>p(()=>i(new x(t.timeout,s))),t.timeout)),n.set({requests:{[s]:{payload:e}}}),f(n.get())})}_consumeResponse(e,t,n,s){let o=this.doc(be);return Ae(o,e,t,this._transport.consumerId,n,()=>this.stream(Re(e)),s,i=>(this._activeRequests.add(i),()=>this._activeRequests.delete(i)))}requestStream(e,t={}){let n=F();return this._consumeResponse(n,e,!0,t.signal).deltas}complete(e,t={}){let n=F(),s=this._consumeResponse(n,e,!1,t.signal);return s.start(),s.body}disconnect(){let e=Array.from(this._activeRequests);this._activeRequests.clear();for(let t of e)try{t(new E)}catch{}for(let t of this._docs.values())t.dispose();this._docs.clear();for(let t of this._streams.values())t.dispose();this._streams.clear(),this._transport.disconnect()}};var Pe=new Set(["then","catch","finally","toJSON",Symbol.toPrimitive]);function xe(r,e){return new Proxy({},{get(t,n){if(!(Pe.has(n)||typeof n!="string"))return s=>{let o=s??{},i=()=>`s_${Date.now()}_${Math.random().toString(36).slice(2)}`,l=i(),h=new U,d=new M({url:"",orgId:e.orgId,jwt:e.jwt,authProvider:e.authProvider,sessionId:l}),a=new O(l,h,d),u=async p=>{let g=await z({baseUrl:e.baseUrl,fallbackUrls:e.fallbackUrls,app:r,functionName:n,orgId:e.orgId,jwt:e.jwt,getAccessToken:e.getAccessToken,authProvider:e.authProvider,idempotencyKey:p}),f=e.getAccessToken?await e.getAccessToken()??void 0:e.jwt;return a.setSessionId(g.sessionId),{url:g.wsUrl,sessionId:g.sessionId,jwt:f}};return d.setConnectionResolver(()=>u(i())),d.on("connected",()=>{d.multiplexer&&h.setTarget(d.multiplexer)}),(async()=>{let p=await u(l);d.setAuth({jwt:p.jwt,authProvider:e.authProvider,orgId:e.orgId}),d.setConnection({url:p.url,sessionId:p.sessionId}),await d.connect({app:r,functionName:n,args:o})})().catch(p=>{console.error(`[urun] Failed to connect session for ${n}:`,p)}),a}}})}var ne=3e4,se="stream:",J=class{_ws;_multiplexer;_pendingRpc=new Map;_rpcId=0;constructor(e,t){this._ws=e,this._multiplexer=t,this._ws.addEventListener("message",n=>{let s;try{s=JSON.parse(typeof n.data=="string"?n.data:"")}catch{return}if(s.rpcId&&this._pendingRpc.has(s.rpcId)){let o=this._pendingRpc.get(s.rpcId);this._pendingRpc.delete(s.rpcId),clearTimeout(o.timer),s.error?o.reject(new Error(s.error)):o.resolve(s.result)}})}async get(e){return this._sendRpc("store.get",{key:e})}async has(e){return await this._sendRpc("store.has",{key:e})}on(e,t){let n=`${se}${e}`;return this._multiplexer.on(n,s=>{t(s)})}emit(e,t){let n=`${se}${e}`,s=typeof t=="object"&&t!==null&&!Array.isArray(t)?t:{data:t};this._multiplexer.emit(n,s)}_getInternals(){return{multiplexer:this._multiplexer,ws:this._ws}}_sendRpc(e,t){return new Promise((n,s)=>{if(!this._ws||this._ws.readyState!==WebSocket.OPEN){s(new Error("WebSocket not open"));return}let o=String(++this._rpcId),i=setTimeout(()=>{this._pendingRpc.has(o)&&(this._pendingRpc.delete(o),s(new Error(`RPC request "${e}" timed out after ${ne}ms`)))},ne);this._pendingRpc.set(o,{resolve:n,reject:s,timer:i}),this._ws.send(JSON.stringify({rpcId:o,type:e,...t}))})}};function Ee(r){let n=`${r.baseUrl.replace(/\/$/,"").replace(/^http/,"ws")}/store/${encodeURIComponent(r.orgId)}`,s=new WebSocket(n);(r.jwt||r.apiKey)&&s.addEventListener("open",()=>{s.send(JSON.stringify({type:"auth",orgId:r.orgId,jwt:r.jwt,authProvider:r.authProvider,apiKey:r.apiKey}))});let o=new W(s);return new J(s,o)}var Oe='video/mp4; codecs="avc1.42E01E"';function Ue(r,e){let t=e?.codec??Oe,n=document.createElement("video");n.muted=!0,n.playsInline=!0;let s=new MediaSource,o=URL.createObjectURL(s);n.src=o,s.addEventListener("sourceopen",()=>{let p;try{p=s.addSourceBuffer(t)}catch(_){throw _ instanceof DOMException&&_.name==="NotSupportedError"?new Error(`Codec not supported: "${t}". Ensure the codec string matches the fMP4 container format. Common values: video/mp4; codecs="avc1.42E01E" (H.264 Baseline), video/mp4; codecs="avc1.4D401F" (H.264 Main).`):_}let g=r.getReader();function f(){return p.updating?new Promise(_=>{p.addEventListener("updateend",()=>_(),{once:!0})}):Promise.resolve()}async function w(){try{for(;;){let{done:_,value:v}=await g.read();if(_){await f(),s.readyState==="open"&&s.endOfStream();return}await f();try{p.appendBuffer(v)}catch(m){if(m instanceof DOMException&&m.name==="QuotaExceededError"){let y=p.buffered;if(y.length>0){let I=y.start(y.length-1);p.remove(0,I),await f(),p.appendBuffer(v)}else throw m}else throw m}}}catch{if(s.readyState==="open")try{s.endOfStream("decode")}catch{}}}w()}),n.play().catch(()=>{});let i=n,l=i.captureStream??i.mozCaptureStream;if(!l)throw new Error("captureStream() is not supported in this browser. videoStream() requires HTMLMediaElement.captureStream() support.");let h=l.call(n),d=h.getTracks(),a=0,u=d.length;if(u===0)n.addEventListener("emptied",()=>{URL.revokeObjectURL(o)},{once:!0});else for(let p of d)p.addEventListener("ended",()=>{a++,a>=u&&URL.revokeObjectURL(o)});return h}export{xe as App,k as RequestAbortError,E as RequestCancelledError,S as RequestError,x as RequestTimeoutError,O as Session,Ee as createStore,Ue as videoStream};
@@ -148,6 +148,17 @@ interface Store {
148
148
  emit(name: string, data: unknown): void;
149
149
  }
150
150
 
151
+ interface SessionText {
152
+
153
+ append(text: string): void;
154
+
155
+ toString(): string;
156
+
157
+ readonly length: number;
158
+
159
+ on(event: 'delta', handler: (inserted: string) => void): () => void;
160
+ }
161
+
151
162
  interface SessionDocument {
152
163
 
153
164
  set(patch: Record<string, unknown>): void;
@@ -155,6 +166,8 @@ interface SessionDocument {
155
166
  get(path?: string, defaultValue?: unknown): unknown;
156
167
 
157
168
  on(event: 'change', handler: (snapshot: Record<string, unknown>) => void): () => void;
169
+
170
+ text(field: string): SessionText;
158
171
  }
159
172
 
160
173
  interface SessionStream {
@@ -168,6 +181,20 @@ interface SessionStream {
168
181
  seek(target: number | 'live'): Promise<void>;
169
182
 
170
183
  on(event: 'track', handler: (track: MediaStreamTrack | null) => void): () => void;
184
+
185
+ messages(): AsyncIterable<unknown>;
186
+ }
187
+
188
+ interface RequestOptions {
189
+
190
+ timeout?: number;
191
+
192
+ signal?: AbortSignal;
193
+ }
194
+
195
+ interface RequestStreamOptions {
196
+
197
+ signal?: AbortSignal;
171
198
  }
172
199
 
173
200
  interface Session {
@@ -180,6 +207,12 @@ interface Session {
180
207
 
181
208
  doc(key: string): SessionDocument;
182
209
 
210
+ request(payload: unknown, options?: RequestOptions): Promise<unknown>;
211
+
212
+ requestStream(payload: unknown, options?: RequestStreamOptions): AsyncIterable<string>;
213
+
214
+ complete(payload: unknown, options?: RequestStreamOptions): Promise<unknown>;
215
+
183
216
  onPhase(handler: (phase: SessionPhase) => void): () => void;
184
217
 
185
218
  disconnect(): void;
@@ -251,6 +284,13 @@ interface TransportConnection {
251
284
  sessionId: string;
252
285
  jwt?: string;
253
286
  }
287
+
288
+ declare function encodeDocSyncFrame(docKey: string, payload: Uint8Array): Uint8Array;
289
+
290
+ declare function decodeDocSyncFrame(frame: Uint8Array): {
291
+ docKey: string;
292
+ payload: Uint8Array;
293
+ } | null;
254
294
  interface TransportEvents {
255
295
  connected: () => void;
256
296
  disconnected: () => void;
@@ -259,7 +299,7 @@ interface TransportEvents {
259
299
  started: () => void;
260
300
  audioTransportReady: () => void;
261
301
 
262
- docSync: (payload: Uint8Array) => void;
302
+ docSync: (docKey: string, payload: Uint8Array) => void;
263
303
 
264
304
  docSyncReady: () => void;
265
305
 
@@ -324,6 +364,12 @@ declare class TransportSession {
324
364
  private _mediaDeathHandled;
325
365
 
326
366
  private _currentEpoch;
367
+
368
+ private _consumerId;
369
+
370
+ private _pendingStreamSubscribes;
371
+
372
+ get consumerId(): string;
327
373
  get state(): TransportState;
328
374
 
329
375
  get currentIncarnation(): number;
@@ -351,15 +397,24 @@ declare class TransportSession {
351
397
  on<E extends keyof TransportEvents>(event: E, handler: TransportEvents[E]): () => void;
352
398
  sendInput(data: Record<string, unknown>, sequence?: number): void;
353
399
 
354
- sendDocSync(payload: Uint8Array): void;
400
+ sendDocSync(docKey: string, payload: Uint8Array): void;
355
401
 
356
- onDocSync(handler: (payload: Uint8Array) => void): () => void;
402
+ onDocSync(docKey: string, handler: (payload: Uint8Array) => void): () => void;
357
403
 
358
404
  onDocSyncReady(handler: () => void): () => void;
405
+
406
+ private _emitDocSyncFrame;
359
407
  addTrack(track: MediaStreamTrack): Promise<void>;
360
408
  removeTrack(): void;
361
409
  requestDiagnostics(): void;
362
410
  seekStream(name: string, target: number | 'live'): void;
411
+
412
+ subscribeStream(name: string): void;
413
+
414
+ unsubscribeStream(name: string): void;
415
+ private _sendStreamSubscribe;
416
+
417
+ private _flushStreamSubscribes;
363
418
  private _handleMessage;
364
419
 
365
420
  private _onStatus;
@@ -397,4 +452,4 @@ declare class TransportSession {
397
452
  private _emitError;
398
453
  }
399
454
 
400
- export { type App as A, type ChannelEndpoint as C, type Layer as L, type SceneContext as S, TransportSession as T, type AppOptions as a, type AttachOptions as b, type ChannelMessage as c, ChannelMultiplexer as d, type ChannelName as e, type LayoutConfig as f, type LayoutContext as g, type SceneGraph as h, type Session as i, type SessionDocument as j, type SessionPhase as k, type SessionPhaseName as l, type SessionStartOptions as m, type SessionStream as n, type Store as o, type StoreOptions as p, type TransportSessionOptions as q, type TransportState as r };
455
+ export { type App as A, type ChannelEndpoint as C, type Layer as L, type RequestOptions as R, type SceneContext as S, TransportSession as T, type AppOptions as a, type AttachOptions as b, type ChannelMessage as c, ChannelMultiplexer as d, type ChannelName as e, type LayoutConfig as f, type LayoutContext as g, type RequestStreamOptions as h, type SceneGraph as i, type Session as j, type SessionDocument as k, type SessionPhase as l, type SessionPhaseName as m, type SessionStartOptions as n, type SessionStream as o, type SessionText as p, type Store as q, type StoreOptions as r, type TransportSessionOptions as s, type TransportState as t, decodeDocSyncFrame as u, encodeDocSyncFrame as v };
@@ -148,6 +148,17 @@ interface Store {
148
148
  emit(name: string, data: unknown): void;
149
149
  }
150
150
 
151
+ interface SessionText {
152
+
153
+ append(text: string): void;
154
+
155
+ toString(): string;
156
+
157
+ readonly length: number;
158
+
159
+ on(event: 'delta', handler: (inserted: string) => void): () => void;
160
+ }
161
+
151
162
  interface SessionDocument {
152
163
 
153
164
  set(patch: Record<string, unknown>): void;
@@ -155,6 +166,8 @@ interface SessionDocument {
155
166
  get(path?: string, defaultValue?: unknown): unknown;
156
167
 
157
168
  on(event: 'change', handler: (snapshot: Record<string, unknown>) => void): () => void;
169
+
170
+ text(field: string): SessionText;
158
171
  }
159
172
 
160
173
  interface SessionStream {
@@ -168,6 +181,20 @@ interface SessionStream {
168
181
  seek(target: number | 'live'): Promise<void>;
169
182
 
170
183
  on(event: 'track', handler: (track: MediaStreamTrack | null) => void): () => void;
184
+
185
+ messages(): AsyncIterable<unknown>;
186
+ }
187
+
188
+ interface RequestOptions {
189
+
190
+ timeout?: number;
191
+
192
+ signal?: AbortSignal;
193
+ }
194
+
195
+ interface RequestStreamOptions {
196
+
197
+ signal?: AbortSignal;
171
198
  }
172
199
 
173
200
  interface Session {
@@ -180,6 +207,12 @@ interface Session {
180
207
 
181
208
  doc(key: string): SessionDocument;
182
209
 
210
+ request(payload: unknown, options?: RequestOptions): Promise<unknown>;
211
+
212
+ requestStream(payload: unknown, options?: RequestStreamOptions): AsyncIterable<string>;
213
+
214
+ complete(payload: unknown, options?: RequestStreamOptions): Promise<unknown>;
215
+
183
216
  onPhase(handler: (phase: SessionPhase) => void): () => void;
184
217
 
185
218
  disconnect(): void;
@@ -251,6 +284,13 @@ interface TransportConnection {
251
284
  sessionId: string;
252
285
  jwt?: string;
253
286
  }
287
+
288
+ declare function encodeDocSyncFrame(docKey: string, payload: Uint8Array): Uint8Array;
289
+
290
+ declare function decodeDocSyncFrame(frame: Uint8Array): {
291
+ docKey: string;
292
+ payload: Uint8Array;
293
+ } | null;
254
294
  interface TransportEvents {
255
295
  connected: () => void;
256
296
  disconnected: () => void;
@@ -259,7 +299,7 @@ interface TransportEvents {
259
299
  started: () => void;
260
300
  audioTransportReady: () => void;
261
301
 
262
- docSync: (payload: Uint8Array) => void;
302
+ docSync: (docKey: string, payload: Uint8Array) => void;
263
303
 
264
304
  docSyncReady: () => void;
265
305
 
@@ -324,6 +364,12 @@ declare class TransportSession {
324
364
  private _mediaDeathHandled;
325
365
 
326
366
  private _currentEpoch;
367
+
368
+ private _consumerId;
369
+
370
+ private _pendingStreamSubscribes;
371
+
372
+ get consumerId(): string;
327
373
  get state(): TransportState;
328
374
 
329
375
  get currentIncarnation(): number;
@@ -351,15 +397,24 @@ declare class TransportSession {
351
397
  on<E extends keyof TransportEvents>(event: E, handler: TransportEvents[E]): () => void;
352
398
  sendInput(data: Record<string, unknown>, sequence?: number): void;
353
399
 
354
- sendDocSync(payload: Uint8Array): void;
400
+ sendDocSync(docKey: string, payload: Uint8Array): void;
355
401
 
356
- onDocSync(handler: (payload: Uint8Array) => void): () => void;
402
+ onDocSync(docKey: string, handler: (payload: Uint8Array) => void): () => void;
357
403
 
358
404
  onDocSyncReady(handler: () => void): () => void;
405
+
406
+ private _emitDocSyncFrame;
359
407
  addTrack(track: MediaStreamTrack): Promise<void>;
360
408
  removeTrack(): void;
361
409
  requestDiagnostics(): void;
362
410
  seekStream(name: string, target: number | 'live'): void;
411
+
412
+ subscribeStream(name: string): void;
413
+
414
+ unsubscribeStream(name: string): void;
415
+ private _sendStreamSubscribe;
416
+
417
+ private _flushStreamSubscribes;
363
418
  private _handleMessage;
364
419
 
365
420
  private _onStatus;
@@ -397,4 +452,4 @@ declare class TransportSession {
397
452
  private _emitError;
398
453
  }
399
454
 
400
- export { type App as A, type ChannelEndpoint as C, type Layer as L, type SceneContext as S, TransportSession as T, type AppOptions as a, type AttachOptions as b, type ChannelMessage as c, ChannelMultiplexer as d, type ChannelName as e, type LayoutConfig as f, type LayoutContext as g, type SceneGraph as h, type Session as i, type SessionDocument as j, type SessionPhase as k, type SessionPhaseName as l, type SessionStartOptions as m, type SessionStream as n, type Store as o, type StoreOptions as p, type TransportSessionOptions as q, type TransportState as r };
455
+ export { type App as A, type ChannelEndpoint as C, type Layer as L, type RequestOptions as R, type SceneContext as S, TransportSession as T, type AppOptions as a, type AttachOptions as b, type ChannelMessage as c, ChannelMultiplexer as d, type ChannelName as e, type LayoutConfig as f, type LayoutContext as g, type RequestStreamOptions as h, type SceneGraph as i, type Session as j, type SessionDocument as k, type SessionPhase as l, type SessionPhaseName as m, type SessionStartOptions as n, type SessionStream as o, type SessionText as p, type Store as q, type StoreOptions as r, type TransportSessionOptions as s, type TransportState as t, decodeDocSyncFrame as u, encodeDocSyncFrame as v };
@@ -1 +1 @@
1
- export { c as ChannelMessage, d as ChannelMultiplexer, e as ChannelName, m as SessionStartOptions, T as TransportSession, q as TransportSessionOptions } from './internal-BYsSyqG4.mjs';
1
+ export { c as ChannelMessage, d as ChannelMultiplexer, e as ChannelName, n as SessionStartOptions, T as TransportSession, s as TransportSessionOptions, u as decodeDocSyncFrame, v as encodeDocSyncFrame } from './internal-CrXsIQMr.mjs';
@@ -1 +1 @@
1
- export { c as ChannelMessage, d as ChannelMultiplexer, e as ChannelName, m as SessionStartOptions, T as TransportSession, q as TransportSessionOptions } from './internal-BYsSyqG4.js';
1
+ export { c as ChannelMessage, d as ChannelMultiplexer, e as ChannelName, n as SessionStartOptions, T as TransportSession, s as TransportSessionOptions, u as decodeDocSyncFrame, v as encodeDocSyncFrame } from './internal-CrXsIQMr.js';