@urun-sh/core 0.1.35 → 0.1.37
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/{chunk-BSNDJBHD.mjs → chunk-FPOLGUA2.mjs} +5 -5
- package/dist/index.d.mts +55 -5
- package/dist/index.d.ts +55 -5
- package/dist/index.js +5 -5
- package/dist/index.mjs +1 -1
- package/dist/{internal-B-5h9uZU.d.mts → internal-B7GoThNN.d.mts} +82 -5
- package/dist/{internal-B-5h9uZU.d.ts → internal-B7GoThNN.d.ts} +82 -5
- package/dist/internal.d.mts +1 -1
- package/dist/internal.d.ts +1 -1
- package/dist/internal.js +5 -5
- package/dist/internal.mjs +1 -1
- package/package.json +6 -1
package/dist/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{a as M,b as v,c as k}from"./chunk-BSNDJBHD.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(s){return s.trim().replace(/\/+$/,"")}function C(s,e){let t=[],r=n=>{if(!n)return;let o=b(n);o&&!t.includes(o)&&t.push(o)};r(s);for(let n of e??[])r(n);for(let n of ee(s))r(n);return t}var q=120,V=1e3,W=3;function Y(s){if(!s)return null;try{let e=new URL(s),t=e.pathname.replace(/\/api\/sessions\/create\/?$/,"");return b(`${e.origin}${t}`)}catch{return null}}async function L(s){let e=C(s.baseUrl,s.fallbackUrls),t=null,r=e.length>1;for(let n of e)try{return await z(n,s,{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(s,e,t){let r,n,o,i=s,l=0,h=new Set;for(let p=0;p<t.pollAttempts;p++){n=o??await E(e),o=void 0;let d=r?await fetch(`${i}/api/session-requests/${encodeURIComponent(r)}`,{headers:A(e,n)}):await fetch(`${i}/api/sessions/create`,{method:"POST",redirect:"manual",headers:{...A(e,n),"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 $(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(!D(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=n??"";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(s,e){let t={"X-Tenant-Id":s.orgId,"X-Auth-Provider":s.authProvider||"default","X-User-Id":"anonymous"};return e&&(t.Authorization=`Bearer ${e}`),t}async function E(s,e){return s.getAccessToken?await s.getAccessToken(e)??void 0:s.jwt}function X(s){return{app:s.app,function:s.functionName,gpus:1,idempotency_key:s.idempotencyKey}}async function j(s){let e=C(s.baseUrl,s.fallbackUrls),t=null;for(let r of e)try{let n={baseUrl:r,app:"",functionName:"",orgId:s.orgId,jwt:s.jwt,getAccessToken:s.getAccessToken,authProvider:s.authProvider,idempotencyKey:""},o=await E(n),i=await fetch(`${b(r)}/api/sessions/${encodeURIComponent(s.sessionId)}/viewer-connect`,{headers:A(n,o)});if(!i.ok)throw new Error(`[urun] viewer-connect for ${s.sessionId} failed: HTTP ${i.status}`);let l=await $(i);if(!l.ws_url||!D(l.ws_url))throw new w(`[urun] viewer-connect returned no usable ws_url for ${s.sessionId}`);return{baseUrl:b(r),sessionId:s.sessionId,wsUrl:l.ws_url,response:l}}catch(n){if(t=n instanceof Error?n:new Error(String(n)),t instanceof w)throw t}throw t??new Error("[urun] viewer-connect failed")}async function $(s){try{let e=await s.json();return e&&typeof e=="object"?e:{}}catch{return{}}}function Q(s,e,t){let r=Number(s.headers.get("Retry-After")||""),n=Number(e.retry_after_seconds??r),o=t??1e4;return Number.isFinite(n)&&n>0?Math.min(n*1e3,o):1e3}function Z(s){return new Promise(e=>setTimeout(e,s))}var w=class extends Error{};function D(s){try{let e=new URL(s);return e.protocol==="ws:"||e.protocol==="wss:"}catch{return!1}}function ee(s){try{return new URL(s).hostname!==H?[]:K}catch{return[]}}import*as g from"yjs";var N=Symbol("urun:doc:remote"),te=Symbol("urun:doc:local");function R(s){return s!==null&&typeof s=="object"&&!Array.isArray(s)}function P(s,e){let t={...s};for(let r of Object.keys(e)){let n=e[r],o=t[r];R(n)&&R(o)?t[r]=P(o,n):t[r]=n}return t}function re(s,e){let t=e.split("."),r=s;for(let n of t){if(r==null||typeof r!="object")return;r=r[n]}return r}function B(s){return s===void 0?s:JSON.parse(JSON.stringify(s))}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(n=>this.applyRemote(n)),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,n]of Object.entries(e)){let o=t[r],i=R(n)&&R(o)?P(o,n):B(n);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 se=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 s{_sessionId;_multiplexer;_transport;_docs=new Map;_streams=new Map;constructor(e,t,r){this._sessionId=e,this._multiplexer=t,this._transport=r}static async attach(e,t){let r=await j({baseUrl:t.baseUrl,fallbackUrls:t.fallbackUrls,sessionId:e,orgId:t.orgId,jwt:t.jwt,getAccessToken:t.getAccessToken,authProvider:t.authProvider}),n=t.getAccessToken?await t.getAccessToken()??void 0:t.jwt,o=new v,i=new k({url:r.wsUrl,orgId:t.orgId,jwt:n,authProvider:t.authProvider,sessionId:e}),l=new s(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,se.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 ne=new Set(["then","catch","finally","toJSON",Symbol.toPrimitive]);function oe(s,e){return new Proxy({},{get(t,r){if(!(ne.has(r)||typeof r!="string"))return n=>{let o=n??{},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 L({baseUrl:e.baseUrl,fallbackUrls:e.fallbackUrls,app:s,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:s,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 n;try{n=JSON.parse(typeof r.data=="string"?r.data:"")}catch{return}if(n.rpcId&&this._pendingRpc.has(n.rpcId)){let o=this._pendingRpc.get(n.rpcId);this._pendingRpc.delete(n.rpcId),clearTimeout(o.timer),n.error?o.reject(new Error(n.error)):o.resolve(n.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,n=>{t(n)})}emit(e,t){let r=`${F}${e}`,n=typeof t=="object"&&t!==null&&!Array.isArray(t)?t:{data:t};this._multiplexer.emit(r,n)}_getInternals(){return{multiplexer:this._multiplexer,ws:this._ws}}_sendRpc(e,t){return new Promise((r,n)=>{if(!this._ws||this._ws.readyState!==WebSocket.OPEN){n(new Error("WebSocket not open"));return}let o=String(++this._rpcId),i=setTimeout(()=>{this._pendingRpc.has(o)&&(this._pendingRpc.delete(o),n(new Error(`RPC request "${e}" timed out after ${G}ms`)))},G);this._pendingRpc.set(o,{resolve:r,reject:n,timer:i}),this._ws.send(JSON.stringify({rpcId:o,type:e,...t}))})}};function ie(s){let r=`${s.baseUrl.replace(/\/$/,"").replace(/^http/,"ws")}/store/${encodeURIComponent(s.orgId)}`,n=new WebSocket(r);(s.jwt||s.apiKey)&&n.addEventListener("open",()=>{n.send(JSON.stringify({type:"auth",orgId:s.orgId,jwt:s.jwt,authProvider:s.authProvider,apiKey:s.apiKey}))});let o=new M(n);return new x(n,o)}var ae='video/mp4; codecs="avc1.42E01E"';function ce(s,e){let t=e?.codec??ae,r=document.createElement("video");r.muted=!0,r.playsInline=!0;let n=new MediaSource,o=URL.createObjectURL(n);r.src=o,n.addEventListener("sourceopen",()=>{let c;try{c=n.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=s.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(),n.readyState==="open"&&n.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(n.readyState==="open")try{n.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 F,b as P,e as O}from"./chunk-FPOLGUA2.mjs";var re="session-api.prod.cloud.urun.sh",ne=["https://session-api.use2.prod.cloud.urun.sh","https://session-api.usw2.prod.cloud.urun.sh"];function U(n){return n.trim().replace(/\/+$/,"")}function G(n,e){let t=[],r=s=>{if(!s)return;let o=U(s);o&&!t.includes(o)&&t.push(o)};r(n);for(let s of e??[])r(s);for(let s of pe(n))r(s);return t}var se=120,oe=1e3,ie=3;function ae(n){if(!n)return null;try{let e=new URL(n),t=e.pathname.replace(/\/api\/sessions\/create\/?$/,"");return U(`${e.origin}${t}`)}catch{return null}}async function J(n){let e=G(n.baseUrl,n.fallbackUrls),t=null,r=e.length>1;for(let s of e)try{return await ce(s,n,{pollAttempts:se,retryAfterLimitMs:r?oe:void 0})}catch(o){if(t=o instanceof Error?o:new Error(String(o)),t instanceof b)throw t}throw t??new Error("[urun] session allocation failed")}async function ce(n,e,t){let r,s,o,i=n,a=0,f=new Set;for(let p=0;p<t.pollAttempts;p++){s=o??await L(e),o=void 0;let d=r?await fetch(`${i}/api/session-requests/${encodeURIComponent(r)}`,{headers:D(e,s)}):await fetch(`${i}/api/sessions/create`,{method:"POST",redirect:"manual",headers:{...D(e,s),"Content-Type":"application/json","Idempotency-Key":e.idempotencyKey},body:JSON.stringify(ue(e))});if(!r&&(d.status===307||d.status===308)){let h=ae(d.headers.get("location"));if(h&&h!==i&&a<ie){a+=1,i=h;continue}throw new Error(`[urun] session create redirected from ${i} without a usable target`)}let c=await H(d);if(d.ok&&(c.status==="allocated"||!c.status&&!!c.session_id)&&!!c.session_id){let h=c.session_id;if(!c.ws_url)throw new b(`[urun] gateway allocated session ${h} without ws_url`);if(!Y(c.ws_url))throw new b(`[urun] gateway allocated session ${h} with non-absolute ws_url`);return{baseUrl:i,sessionId:h,wsUrl:c.ws_url,response:c}}if(d.status===202||c.status==="pending"||c.status==="queued"||c.queued){if(r=c.request_id||r,!r)throw new Error("[urun] gateway queued session without request_id");await de(le(d,c,t.retryAfterLimitMs));continue}if((d.status===401||d.status===403)&&e.getAccessToken){let h=s??"";f.add(h);let g=await L(e,{forceRefresh:!0,reason:"unauthorized"});if(g&&!f.has(g)){o=g,r=void 0;continue}}let m=c.error_message||c.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 D(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 L(n,e){return n.getAccessToken?await n.getAccessToken(e)??void 0:n.jwt}function ue(n){return{app:n.app,function:n.functionName,gpus:1,idempotency_key:n.idempotencyKey}}async function K(n){let e=G(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 L(s),i=await fetch(`${U(r)}/api/sessions/${encodeURIComponent(n.sessionId)}/viewer-connect`,{headers:D(s,o)});if(!i.ok)throw new Error(`[urun] viewer-connect for ${n.sessionId} failed: HTTP ${i.status}`);let a=await H(i);if(!a.ws_url||!Y(a.ws_url))throw new b(`[urun] viewer-connect returned no usable ws_url for ${n.sessionId}`);return{baseUrl:U(r),sessionId:n.sessionId,wsUrl:a.ws_url,response:a}}catch(s){if(t=s instanceof Error?s:new Error(String(s)),t instanceof b)throw t}throw t??new Error("[urun] viewer-connect failed")}async function H(n){try{let e=await n.json();return e&&typeof e=="object"?e:{}}catch{return{}}}function le(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 de(n){return new Promise(e=>setTimeout(e,n))}var b=class extends Error{};function Y(n){try{let e=new URL(n);return e.protocol==="ws:"||e.protocol==="wss:"}catch{return!1}}function pe(n){try{return new URL(n).hostname!==re?[]:ne}catch{return[]}}import*as R from"yjs";var V=Symbol("urun:doc:remote"),he=Symbol("urun:doc:local");function M(n){return n!==null&&typeof n=="object"&&!Array.isArray(n)}function j(n,e){let t={...n};for(let r of Object.keys(e)){let s=e[r],o=t[r];M(s)&&M(o)?t[r]=j(o,s):t[r]=s}return t}function fe(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 W(n){return n===void 0?n:JSON.parse(JSON.stringify(n))}var q=class{_doc=new R.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!==V&&this._transport?.sendDocSync(this._key,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(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(W(e)),this.notify();return}this.applyPatch(e)}get(e,t){let r=this.snapshot();return e?fe(r,e)??t:r}on(e,t){return this._listeners.add(t),()=>this._listeners.delete(t)}text(e){let t=this._texts.get(e);return t||(t=new $(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,R.encodeStateAsUpdate(this._doc))}applyRemote(e){if(R.applyUpdate(this._doc,e,V),!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=M(s)&&M(o)?j(o,s):W(s);JSON.stringify(i)!==JSON.stringify(o)&&this._root.set(r,i)}},he)}snapshot(){let e=this._root.toJSON();for(let t of this._pendingPatches)e=j(e,t);return e}notify(){let e=this.snapshot();for(let t of this._listeners)t(e)}},$=class{constructor(e){this._ytext=e;this._observer=t=>{for(let r of t.delta)if(typeof r.insert=="string"&&r.insert.length>0){let s=r.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 y=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)}},T=class extends y{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 y{constructor(e){super("[urun] request aborted",{requestId:e}),this.name="RequestAbortError",Object.setPrototypeOf(this,new.target.prototype)}},x=class extends y{constructor(e){super("[urun] request cancelled: session disconnected",{requestId:e}),this.name="RequestCancelledError",Object.setPrototypeOf(this,new.target.prototype)}};var ge=new Set,z="rpc";function X(){let n=globalThis.crypto;return n?.randomUUID?n.randomUUID():`req_${Date.now().toString(36)}_${Math.random().toString(36).slice(2)}`}function me(n,e,t,r,s){return{[Symbol.asyncIterator](){let o=[],i=null,a=!1,f=null,p=!1,d=n.text(e),c=null,u=null,m=null,h=()=>{c?.(),c=null,u?.(),u=null,m?.(),m=null,r?.removeEventListener("abort",S),p&&n.set({requests:{[e]:null}})},g=()=>{if(i){if(o.length>0){let l=i;i=null,l.resolve({value:o.shift(),done:!1})}else if(f!==null){let l=i;i=null,l.reject(f)}else if(a){let l=i;i=null,l.resolve({value:void 0,done:!0})}}},_=l=>{a||(o.push(l),g())},v=l=>{a||(f=l,a=!0,h(),g())},w=()=>{a||(a=!0,h(),g())},S=()=>v(new k(e)),E=l=>{if(l)if(l.error!==void 0&&l.error!==null){let I=typeof l.error=="string"?l.error:JSON.stringify(l.error);v(new y(I,{requestId:e,code:l.code}))}else l.done&&w()},ee=()=>{if(p)return;if(p=!0,r){if(r.aborted){v(new k(e));return}r.addEventListener("abort",S,{once:!0})}m=s?.(C=>v(C))??null,c=d.on("delta",_),u=n.on("change",C=>{if(a)return;let te=C.responses;E(te?.[e])}),n.set({requests:{[e]:{payload:t,stream:!0}}});let l=d.toString();l.length>0&&o.push(l);let I=n.get();E(I.responses?.[e])};return{next(){if(ee(),o.length>0)return Promise.resolve({value:o.shift(),done:!1});if(f!==null){let l=f;return f=null,Promise.reject(l)}return a?Promise.resolve({value:void 0,done:!0}):new Promise((l,I)=>{i={resolve:l,reject:I}})},return(){return a||(a=!0,h()),Promise.resolve({value:void 0,done:!0})},throw(l){return a||(a=!0,h()),Promise.reject(l)}}}}}var N=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)}},A=class n{_sessionId;_multiplexer;_transport;_docs=new Map;_streams=new Map;_activeRequests=new Set;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 K({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 P,i=new O({url:r.wsUrl,orgId:t.orgId,jwt:s,authProvider:t.authProvider,sessionId:e}),a=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"}),a}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 N(e,this._transport),this._streams.set(e,t)),t}doc(e){let t=this._docs.get(e);return t||(t=new q(e,this._sessionId,ge.has(e)?null:this._transport),this._docs.set(e,t)),t}request(e,t={}){let r=this.doc(z),s=X();return new Promise((o,i)=>{let a=!1,f=null,p=null,d=null,c=()=>{p&&(clearTimeout(p),p=null),f&&(f(),f=null),d&&(this._activeRequests.delete(d),d=null),t.signal?.removeEventListener("abort",m),r.set({requests:{[s]:null}})},u=g=>{a||(a=!0,c(),g())},m=()=>u(()=>i(new k(s)));if(t.signal){if(t.signal.aborted){a=!0,i(new k(s));return}t.signal.addEventListener("abort",m,{once:!0})}let h=g=>{let v=g.responses?.[s];if(v==null)return;let w=v;if(w.error!==void 0&&w.error!==null){let S=typeof w.error=="string"?w.error:JSON.stringify(w.error);u(()=>i(new y(S,{requestId:s,code:w.code})))}else u(()=>o(w.result))};f=r.on("change",h),d=g=>u(()=>i(g)),this._activeRequests.add(d),typeof t.timeout=="number"&&t.timeout>=0&&(p=setTimeout(()=>u(()=>i(new T(t.timeout,s))),t.timeout)),r.set({requests:{[s]:{payload:e}}}),h(r.get())})}requestStream(e,t={}){let r=this.doc(z),s=X();return me(r,s,e,t.signal,o=>(this._activeRequests.add(o),()=>this._activeRequests.delete(o)))}disconnect(){let e=Array.from(this._activeRequests);this._activeRequests.clear();for(let t of e)try{t(new x)}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 we=new Set(["then","catch","finally","toJSON",Symbol.toPrimitive]);function _e(n,e){return new Proxy({},{get(t,r){if(!(we.has(r)||typeof r!="string"))return s=>{let o=s??{},i=()=>`s_${Date.now()}_${Math.random().toString(36).slice(2)}`,a=i(),f=new P,p=new O({url:"",orgId:e.orgId,jwt:e.jwt,authProvider:e.authProvider,sessionId:a}),d=new A(a,f,p),c=async u=>{let m=await J({baseUrl:e.baseUrl,fallbackUrls:e.fallbackUrls,app:n,functionName:r,orgId:e.orgId,jwt:e.jwt,getAccessToken:e.getAccessToken,authProvider:e.authProvider,idempotencyKey:u}),h=e.getAccessToken?await e.getAccessToken()??void 0:e.jwt;return d.setSessionId(m.sessionId),{url:m.wsUrl,sessionId:m.sessionId,jwt:h}};return p.setConnectionResolver(()=>c(i())),p.on("connected",()=>{p.multiplexer&&f.setTarget(p.multiplexer)}),(async()=>{let u=await c(a);p.setAuth({jwt:u.jwt,authProvider:e.authProvider,orgId:e.orgId}),p.setConnection({url:u.url,sessionId:u.sessionId}),await p.connect({app:n,functionName:r,args:o})})().catch(u=>{console.error(`[urun] Failed to connect session for ${r}:`,u)}),d}}})}var Q=3e4,Z="stream:",B=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=`${Z}${e}`;return this._multiplexer.on(r,s=>{t(s)})}emit(e,t){let r=`${Z}${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 ${Q}ms`)))},Q);this._pendingRpc.set(o,{resolve:r,reject:s,timer:i}),this._ws.send(JSON.stringify({rpcId:o,type:e,...t}))})}};function ve(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 F(s);return new B(s,o)}var ye='video/mp4; codecs="avc1.42E01E"';function Se(n,e){let t=e?.codec??ye,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 u;try{u=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 m=n.getReader();function h(){return u.updating?new Promise(_=>{u.addEventListener("updateend",()=>_(),{once:!0})}):Promise.resolve()}async function g(){try{for(;;){let{done:_,value:v}=await m.read();if(_){await h(),s.readyState==="open"&&s.endOfStream();return}await h();try{u.appendBuffer(v)}catch(w){if(w instanceof DOMException&&w.name==="QuotaExceededError"){let S=u.buffered;if(S.length>0){let E=S.start(S.length-1);u.remove(0,E),await h(),u.appendBuffer(v)}else throw w}else throw w}}}catch{if(s.readyState==="open")try{s.endOfStream("decode")}catch{}}}g()}),r.play().catch(()=>{});let i=r,a=i.captureStream??i.mozCaptureStream;if(!a)throw new Error("captureStream() is not supported in this browser. videoStream() requires HTMLMediaElement.captureStream() support.");let f=a.call(r),p=f.getTracks(),d=0,c=p.length;if(c===0)r.addEventListener("emptied",()=>{URL.revokeObjectURL(o)},{once:!0});else for(let u of p)u.addEventListener("ended",()=>{d++,d>=c&&URL.revokeObjectURL(o)});return f}export{_e as App,k as RequestAbortError,x as RequestCancelledError,y as RequestError,T as RequestTimeoutError,A as Session,ve as createStore,Se as videoStream};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
|
|
2
2
|
|
|
3
|
-
type TransportState = 'connecting' | 'connected' | 'reconnecting' | 'disconnected' | 'failed';
|
|
3
|
+
type TransportState = 'connecting' | 'connected' | 'reconnecting' | 'renegotiating' | 'disconnected' | 'failed';
|
|
4
4
|
|
|
5
5
|
type SessionPhaseName = 'idle' | 'queued' | 'provisioning' | 'connecting' | 'live' | 'error' | 'ended';
|
|
6
6
|
|
|
@@ -36,6 +36,15 @@ interface TransportSessionOptions {
|
|
|
36
36
|
authProvider?: string;
|
|
37
37
|
|
|
38
38
|
sessionId?: string;
|
|
39
|
+
|
|
40
|
+
mediaLiveness?: MediaLivenessOptions;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
interface MediaLivenessOptions {
|
|
44
|
+
|
|
45
|
+
pollMs?: number;
|
|
46
|
+
|
|
47
|
+
stallTimeoutMs?: number;
|
|
39
48
|
}
|
|
40
49
|
|
|
41
50
|
type ChannelName = 'scene_graph' | 'ui_components' | 'events' | 'agent_status' | 'control';
|
|
@@ -139,6 +148,17 @@ interface Store {
|
|
|
139
148
|
emit(name: string, data: unknown): void;
|
|
140
149
|
}
|
|
141
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
|
+
|
|
142
162
|
interface SessionDocument {
|
|
143
163
|
|
|
144
164
|
set(patch: Record<string, unknown>): void;
|
|
@@ -146,6 +166,8 @@ interface SessionDocument {
|
|
|
146
166
|
get(path?: string, defaultValue?: unknown): unknown;
|
|
147
167
|
|
|
148
168
|
on(event: 'change', handler: (snapshot: Record<string, unknown>) => void): () => void;
|
|
169
|
+
|
|
170
|
+
text(field: string): SessionText;
|
|
149
171
|
}
|
|
150
172
|
|
|
151
173
|
interface SessionStream {
|
|
@@ -161,6 +183,18 @@ interface SessionStream {
|
|
|
161
183
|
on(event: 'track', handler: (track: MediaStreamTrack | null) => void): () => void;
|
|
162
184
|
}
|
|
163
185
|
|
|
186
|
+
interface RequestOptions {
|
|
187
|
+
|
|
188
|
+
timeout?: number;
|
|
189
|
+
|
|
190
|
+
signal?: AbortSignal;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
interface RequestStreamOptions {
|
|
194
|
+
|
|
195
|
+
signal?: AbortSignal;
|
|
196
|
+
}
|
|
197
|
+
|
|
164
198
|
interface Session {
|
|
165
199
|
|
|
166
200
|
readonly id: string;
|
|
@@ -171,6 +205,10 @@ interface Session {
|
|
|
171
205
|
|
|
172
206
|
doc(key: string): SessionDocument;
|
|
173
207
|
|
|
208
|
+
request(payload: unknown, options?: RequestOptions): Promise<unknown>;
|
|
209
|
+
|
|
210
|
+
requestStream(payload: unknown, options?: RequestStreamOptions): AsyncIterable<string>;
|
|
211
|
+
|
|
174
212
|
onPhase(handler: (phase: SessionPhase) => void): () => void;
|
|
175
213
|
|
|
176
214
|
disconnect(): void;
|
|
@@ -242,6 +280,13 @@ interface TransportConnection {
|
|
|
242
280
|
sessionId: string;
|
|
243
281
|
jwt?: string;
|
|
244
282
|
}
|
|
283
|
+
|
|
284
|
+
declare function encodeDocSyncFrame(docKey: string, payload: Uint8Array): Uint8Array;
|
|
285
|
+
|
|
286
|
+
declare function decodeDocSyncFrame(frame: Uint8Array): {
|
|
287
|
+
docKey: string;
|
|
288
|
+
payload: Uint8Array;
|
|
289
|
+
} | null;
|
|
245
290
|
interface TransportEvents {
|
|
246
291
|
connected: () => void;
|
|
247
292
|
disconnected: () => void;
|
|
@@ -250,7 +295,7 @@ interface TransportEvents {
|
|
|
250
295
|
started: () => void;
|
|
251
296
|
audioTransportReady: () => void;
|
|
252
297
|
|
|
253
|
-
docSync: (payload: Uint8Array) => void;
|
|
298
|
+
docSync: (docKey: string, payload: Uint8Array) => void;
|
|
254
299
|
|
|
255
300
|
docSyncReady: () => void;
|
|
256
301
|
|
|
@@ -303,7 +348,21 @@ declare class TransportSession {
|
|
|
303
348
|
private _phase;
|
|
304
349
|
private _requestId;
|
|
305
350
|
private _liveReached;
|
|
351
|
+
|
|
352
|
+
private _mediaMonitorTimer;
|
|
353
|
+
|
|
354
|
+
private _lastInboundTotal;
|
|
355
|
+
|
|
356
|
+
private _mediaEverFlowed;
|
|
357
|
+
|
|
358
|
+
private _lastInboundAdvanceAt;
|
|
359
|
+
|
|
360
|
+
private _mediaDeathHandled;
|
|
361
|
+
|
|
362
|
+
private _currentEpoch;
|
|
306
363
|
get state(): TransportState;
|
|
364
|
+
|
|
365
|
+
get currentIncarnation(): number;
|
|
307
366
|
get phase(): SessionPhase;
|
|
308
367
|
get sessionId(): string | null;
|
|
309
368
|
get tracks(): Map<string, MediaStreamTrack>;
|
|
@@ -315,16 +374,26 @@ declare class TransportSession {
|
|
|
315
374
|
constructor(options?: TransportSessionOptions);
|
|
316
375
|
setConnection(options: Pick<TransportSessionOptions, 'url' | 'fallbackUrls' | 'sessionId'>): void;
|
|
317
376
|
setConnectionResolver(resolveConnection: (() => Promise<TransportConnection>) | null): void;
|
|
377
|
+
|
|
378
|
+
applyControlDocState(state: Record<string, unknown> | null | undefined): void;
|
|
379
|
+
|
|
380
|
+
setIncarnation(epoch: number): void;
|
|
381
|
+
|
|
382
|
+
isStaleIncarnation(epoch: number): boolean;
|
|
383
|
+
|
|
384
|
+
isStaleClosedMarker(marker: Record<string, unknown> | null | undefined): boolean;
|
|
318
385
|
connect(startOptions?: SessionStartOptions): Promise<void>;
|
|
319
386
|
disconnect(): void;
|
|
320
387
|
on<E extends keyof TransportEvents>(event: E, handler: TransportEvents[E]): () => void;
|
|
321
388
|
sendInput(data: Record<string, unknown>, sequence?: number): void;
|
|
322
389
|
|
|
323
|
-
sendDocSync(payload: Uint8Array): void;
|
|
390
|
+
sendDocSync(docKey: string, payload: Uint8Array): void;
|
|
324
391
|
|
|
325
|
-
onDocSync(handler: (payload: Uint8Array) => void): () => void;
|
|
392
|
+
onDocSync(docKey: string, handler: (payload: Uint8Array) => void): () => void;
|
|
326
393
|
|
|
327
394
|
onDocSyncReady(handler: () => void): () => void;
|
|
395
|
+
|
|
396
|
+
private _emitDocSyncFrame;
|
|
328
397
|
addTrack(track: MediaStreamTrack): Promise<void>;
|
|
329
398
|
removeTrack(): void;
|
|
330
399
|
requestDiagnostics(): void;
|
|
@@ -341,6 +410,14 @@ declare class TransportSession {
|
|
|
341
410
|
private _failoverRecvToTcp;
|
|
342
411
|
private _onCreateSendTransport;
|
|
343
412
|
private _onConsume;
|
|
413
|
+
private _mediaPollMs;
|
|
414
|
+
private _mediaStallTimeoutMs;
|
|
415
|
+
|
|
416
|
+
private _startMediaMonitor;
|
|
417
|
+
private _stopMediaMonitor;
|
|
418
|
+
private _sampleMediaLiveness;
|
|
419
|
+
|
|
420
|
+
private _renegotiate;
|
|
344
421
|
private _attemptReconnect;
|
|
345
422
|
private _connectUrls;
|
|
346
423
|
private _connectOnce;
|
|
@@ -358,4 +435,4 @@ declare class TransportSession {
|
|
|
358
435
|
private _emitError;
|
|
359
436
|
}
|
|
360
437
|
|
|
361
|
-
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
|
|
438
|
+
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,6 +1,6 @@
|
|
|
1
1
|
|
|
2
2
|
|
|
3
|
-
type TransportState = 'connecting' | 'connected' | 'reconnecting' | 'disconnected' | 'failed';
|
|
3
|
+
type TransportState = 'connecting' | 'connected' | 'reconnecting' | 'renegotiating' | 'disconnected' | 'failed';
|
|
4
4
|
|
|
5
5
|
type SessionPhaseName = 'idle' | 'queued' | 'provisioning' | 'connecting' | 'live' | 'error' | 'ended';
|
|
6
6
|
|
|
@@ -36,6 +36,15 @@ interface TransportSessionOptions {
|
|
|
36
36
|
authProvider?: string;
|
|
37
37
|
|
|
38
38
|
sessionId?: string;
|
|
39
|
+
|
|
40
|
+
mediaLiveness?: MediaLivenessOptions;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
interface MediaLivenessOptions {
|
|
44
|
+
|
|
45
|
+
pollMs?: number;
|
|
46
|
+
|
|
47
|
+
stallTimeoutMs?: number;
|
|
39
48
|
}
|
|
40
49
|
|
|
41
50
|
type ChannelName = 'scene_graph' | 'ui_components' | 'events' | 'agent_status' | 'control';
|
|
@@ -139,6 +148,17 @@ interface Store {
|
|
|
139
148
|
emit(name: string, data: unknown): void;
|
|
140
149
|
}
|
|
141
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
|
+
|
|
142
162
|
interface SessionDocument {
|
|
143
163
|
|
|
144
164
|
set(patch: Record<string, unknown>): void;
|
|
@@ -146,6 +166,8 @@ interface SessionDocument {
|
|
|
146
166
|
get(path?: string, defaultValue?: unknown): unknown;
|
|
147
167
|
|
|
148
168
|
on(event: 'change', handler: (snapshot: Record<string, unknown>) => void): () => void;
|
|
169
|
+
|
|
170
|
+
text(field: string): SessionText;
|
|
149
171
|
}
|
|
150
172
|
|
|
151
173
|
interface SessionStream {
|
|
@@ -161,6 +183,18 @@ interface SessionStream {
|
|
|
161
183
|
on(event: 'track', handler: (track: MediaStreamTrack | null) => void): () => void;
|
|
162
184
|
}
|
|
163
185
|
|
|
186
|
+
interface RequestOptions {
|
|
187
|
+
|
|
188
|
+
timeout?: number;
|
|
189
|
+
|
|
190
|
+
signal?: AbortSignal;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
interface RequestStreamOptions {
|
|
194
|
+
|
|
195
|
+
signal?: AbortSignal;
|
|
196
|
+
}
|
|
197
|
+
|
|
164
198
|
interface Session {
|
|
165
199
|
|
|
166
200
|
readonly id: string;
|
|
@@ -171,6 +205,10 @@ interface Session {
|
|
|
171
205
|
|
|
172
206
|
doc(key: string): SessionDocument;
|
|
173
207
|
|
|
208
|
+
request(payload: unknown, options?: RequestOptions): Promise<unknown>;
|
|
209
|
+
|
|
210
|
+
requestStream(payload: unknown, options?: RequestStreamOptions): AsyncIterable<string>;
|
|
211
|
+
|
|
174
212
|
onPhase(handler: (phase: SessionPhase) => void): () => void;
|
|
175
213
|
|
|
176
214
|
disconnect(): void;
|
|
@@ -242,6 +280,13 @@ interface TransportConnection {
|
|
|
242
280
|
sessionId: string;
|
|
243
281
|
jwt?: string;
|
|
244
282
|
}
|
|
283
|
+
|
|
284
|
+
declare function encodeDocSyncFrame(docKey: string, payload: Uint8Array): Uint8Array;
|
|
285
|
+
|
|
286
|
+
declare function decodeDocSyncFrame(frame: Uint8Array): {
|
|
287
|
+
docKey: string;
|
|
288
|
+
payload: Uint8Array;
|
|
289
|
+
} | null;
|
|
245
290
|
interface TransportEvents {
|
|
246
291
|
connected: () => void;
|
|
247
292
|
disconnected: () => void;
|
|
@@ -250,7 +295,7 @@ interface TransportEvents {
|
|
|
250
295
|
started: () => void;
|
|
251
296
|
audioTransportReady: () => void;
|
|
252
297
|
|
|
253
|
-
docSync: (payload: Uint8Array) => void;
|
|
298
|
+
docSync: (docKey: string, payload: Uint8Array) => void;
|
|
254
299
|
|
|
255
300
|
docSyncReady: () => void;
|
|
256
301
|
|
|
@@ -303,7 +348,21 @@ declare class TransportSession {
|
|
|
303
348
|
private _phase;
|
|
304
349
|
private _requestId;
|
|
305
350
|
private _liveReached;
|
|
351
|
+
|
|
352
|
+
private _mediaMonitorTimer;
|
|
353
|
+
|
|
354
|
+
private _lastInboundTotal;
|
|
355
|
+
|
|
356
|
+
private _mediaEverFlowed;
|
|
357
|
+
|
|
358
|
+
private _lastInboundAdvanceAt;
|
|
359
|
+
|
|
360
|
+
private _mediaDeathHandled;
|
|
361
|
+
|
|
362
|
+
private _currentEpoch;
|
|
306
363
|
get state(): TransportState;
|
|
364
|
+
|
|
365
|
+
get currentIncarnation(): number;
|
|
307
366
|
get phase(): SessionPhase;
|
|
308
367
|
get sessionId(): string | null;
|
|
309
368
|
get tracks(): Map<string, MediaStreamTrack>;
|
|
@@ -315,16 +374,26 @@ declare class TransportSession {
|
|
|
315
374
|
constructor(options?: TransportSessionOptions);
|
|
316
375
|
setConnection(options: Pick<TransportSessionOptions, 'url' | 'fallbackUrls' | 'sessionId'>): void;
|
|
317
376
|
setConnectionResolver(resolveConnection: (() => Promise<TransportConnection>) | null): void;
|
|
377
|
+
|
|
378
|
+
applyControlDocState(state: Record<string, unknown> | null | undefined): void;
|
|
379
|
+
|
|
380
|
+
setIncarnation(epoch: number): void;
|
|
381
|
+
|
|
382
|
+
isStaleIncarnation(epoch: number): boolean;
|
|
383
|
+
|
|
384
|
+
isStaleClosedMarker(marker: Record<string, unknown> | null | undefined): boolean;
|
|
318
385
|
connect(startOptions?: SessionStartOptions): Promise<void>;
|
|
319
386
|
disconnect(): void;
|
|
320
387
|
on<E extends keyof TransportEvents>(event: E, handler: TransportEvents[E]): () => void;
|
|
321
388
|
sendInput(data: Record<string, unknown>, sequence?: number): void;
|
|
322
389
|
|
|
323
|
-
sendDocSync(payload: Uint8Array): void;
|
|
390
|
+
sendDocSync(docKey: string, payload: Uint8Array): void;
|
|
324
391
|
|
|
325
|
-
onDocSync(handler: (payload: Uint8Array) => void): () => void;
|
|
392
|
+
onDocSync(docKey: string, handler: (payload: Uint8Array) => void): () => void;
|
|
326
393
|
|
|
327
394
|
onDocSyncReady(handler: () => void): () => void;
|
|
395
|
+
|
|
396
|
+
private _emitDocSyncFrame;
|
|
328
397
|
addTrack(track: MediaStreamTrack): Promise<void>;
|
|
329
398
|
removeTrack(): void;
|
|
330
399
|
requestDiagnostics(): void;
|
|
@@ -341,6 +410,14 @@ declare class TransportSession {
|
|
|
341
410
|
private _failoverRecvToTcp;
|
|
342
411
|
private _onCreateSendTransport;
|
|
343
412
|
private _onConsume;
|
|
413
|
+
private _mediaPollMs;
|
|
414
|
+
private _mediaStallTimeoutMs;
|
|
415
|
+
|
|
416
|
+
private _startMediaMonitor;
|
|
417
|
+
private _stopMediaMonitor;
|
|
418
|
+
private _sampleMediaLiveness;
|
|
419
|
+
|
|
420
|
+
private _renegotiate;
|
|
344
421
|
private _attemptReconnect;
|
|
345
422
|
private _connectUrls;
|
|
346
423
|
private _connectOnce;
|
|
@@ -358,4 +435,4 @@ declare class TransportSession {
|
|
|
358
435
|
private _emitError;
|
|
359
436
|
}
|
|
360
437
|
|
|
361
|
-
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
|
|
438
|
+
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 };
|
package/dist/internal.d.mts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { c as ChannelMessage, d as ChannelMultiplexer, e as ChannelName,
|
|
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-B7GoThNN.mjs';
|
package/dist/internal.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { c as ChannelMessage, d as ChannelMultiplexer, e as ChannelName,
|
|
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-B7GoThNN.js';
|