var n=Object.defineProperty;var a=(r,t,e)=>t in r?n(r,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):r[t]=e;var i=(r,t,e)=>a(r,typeof t!="symbol"?t+"":t,e);class p{constructor(t,e=`${location.protocol==="https:"?"wss:":"ws:"}//${location.host}/room`){i(this,"socket");i(this,"listeners",new Map);i(this,"sequence",0);i(this,"retries",0);i(this,"timer",0);i(this,"stopped",!1);i(this,"expiresAt",1/0);i(this,"state","offline");i(this,"actorId","");this.revalidate=t,this.endpoint=e}on(t,e){const s=this.listeners.get(t)??new Set;return s.add(e),this.listeners.set(t,s),()=>s.delete(e)}emit(t,e){for(const s of this.listeners.get(t)??[])s(e)}status(t){this.state=t,this.emit("state",t)}connect(){if(this.socket&&(this.socket.readyState===WebSocket.OPEN||this.socket.readyState===WebSocket.CONNECTING))return;this.stopped=!1,clearTimeout(this.timer),this.status(this.retries?"reconnecting":"connecting");const t=new WebSocket(this.endpoint);this.socket=t,t.onmessage=e=>{if(this.socket!==t)return;let s;try{s=JSON.parse(String(e.data))}catch{return}s.type==="welcome"&&(this.actorId=s.actorId,this.expiresAt=s.expiresAt,this.sequence=0,this.retries=0,this.status("ready"),this.emit("welcome",s),this.emit("snapshot",s.snapshot)),s.type==="snapshot"&&this.emit("snapshot",s),s.type==="appearance"&&this.emit("appearance",{actorId:s.actorId,appearance:s.appearance}),s.type==="central"&&this.emit("central",s.available),s.type==="error"&&this.emit("error",s.message)},t.onclose=e=>{if(this.socket===t&&(this.socket=void 0,!this.stopped)){if(e.code===4003||e.code===4002||Date.now()>=this.expiresAt){this.status("expired");return}if([4001,4004,4008].includes(e.code)){this.status("offline"),this.emit("error",e.reason||"Room connection ended. Return Home to re-enter.");return}this.retry()}},t.onerror=()=>{this.emit("error","Room connection interrupted.")}}retry(){if(!this.stopped){if(this.retries>=5){this.status("offline");return}this.status("reconnecting"),this.timer=window.setTimeout(()=>{this.revalidate().then(()=>{this.stopped||this.connect()}).catch(t=>{if(this.stopped)return;const e=t==null?void 0:t.status;e===401||e===403||Date.now()>=this.expiresAt?this.status("expired"):this.retry()})},Math.min(500*2**this.retries++,5e3))}}send(t){var s;if(this.state!=="ready"||((s=this.socket)==null?void 0:s.readyState)!==WebSocket.OPEN||this.socket.bufferedAmount>16384)return 0;const e={...t,seq:++this.sequence};return this.socket.send(JSON.stringify(e)),e.seq}disconnect(){this.stopped=!0,clearTimeout(this.timer);const t=this.socket;this.socket=void 0,t==null||t.close(1e3,"Leaving world"),this.status("offline")}dispose(){this.disconnect(),this.listeners.clear()}}class c extends Error{constructor(t,e){super(t),this.status=e}}class u{constructor(t=""){this.base=t}async request(t,e){const s=await fetch(this.base+t,{method:e===void 0?"GET":"POST",credentials:"same-origin",headers:{"x-yoworlds":"1","x-pocketbeyond":"1",...e===void 0?{}:{"content-type":"application/json"}},...e===void 0?{}:{body:JSON.stringify(e)},signal:AbortSignal.timeout(8e3)}),o=await s.json();if(!s.ok)throw new c(o.error??"The request could not be completed.",s.status);return o}enterSession(){return this.request("/api/session")}readAppearance(){return this.request("/api/appearance")}refreshAppearance(){return this.readAppearance()}async getDestinations(){return(await this.enterSession()).destinations}requestTravel(t){return this.request("/api/travel",{worldId:t})}openStore(t){return this.request("/api/store",t?{selectedItem:t}:{})}openWardrobe(t){return this.openStore(t)}async openCharacterCreator(){const t=await this.openStore(),e=new URL(t.url);return e.searchParams.set("view","character"),{url:e.href}}}export{u as Pocketbeyond,c as RequestError,p as RoomConnection,u as YoWorlds};
