@dobuki/hello-worker 1.0.25 → 1.0.26

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.
@@ -1,7 +1,7 @@
1
1
  import { EnterRoom } from "./signal-room";
2
2
  import { SigType, SigPayload } from "./webrtc-peer-collector";
3
3
  type UserListener = (user: string, action: "join" | "leave", users: string[]) => void;
4
- export declare function enterWorld({ appId, logLine, enterRoomFunction, peerlessUserExpiration, workerUrl, onRoomReady, onRoomClose, }: {
4
+ export declare function enterWorld({ appId, logLine, enterRoomFunction, peerlessUserExpiration, workerUrl, onRoomReady, onRoomClose, dataChannelOptions, }: {
5
5
  appId: string;
6
6
  logLine?: (direction: string, obj?: any) => void;
7
7
  enterRoomFunction?: EnterRoom<SigType, SigPayload>;
@@ -16,6 +16,7 @@ export declare function enterWorld({ appId, logLine, enterRoomFunction, peerless
16
16
  room: string;
17
17
  ev: Pick<CloseEvent, "reason" | "code" | "wasClean">;
18
18
  }): void;
19
+ dataChannelOptions?: RTCDataChannelInit;
19
20
  }): {
20
21
  userId: string;
21
22
  send: (data: any, userId?: string) => void;
@@ -1 +1 @@
1
- {"version":3,"file":"enter-world.d.ts","sourceRoot":"","sources":["../src/browser/enter-world.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAa,MAAM,eAAe,CAAC;AACrD,OAAO,EAAE,OAAO,EAAE,UAAU,EAA0B,MAAM,yBAAyB,CAAC;AAEtF,KAAK,YAAY,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAC,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;AAEpF,wBAAgB,UAAU,CAAC,EACzB,KAAK,EAAE,OAAuB,EAAE,iBAA6B,EAAE,sBAAsB,EAAE,SAAS,EAChG,WAAW,EACX,WAAW,GACZ,EAAE;IACD,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,GAAG,KAAK,IAAI,CAAC;IACjD,iBAAiB,CAAC,EAAE,SAAS,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;IACnD,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,SAAS,CAAC,EAAE,GAAG,CAAC;IAChB,WAAW,CAAC,CAAC,IAAI,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IACzD,WAAW,CAAC,CAAC,IAAI,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,IAAI,CAAC,UAAU,EAAE,QAAQ,GAAC,MAAM,GAAC,UAAU,CAAC,CAAA;KAAE,GAAG,IAAI,CAAC;CAC5G;;iBA2DqB,GAAG,WAAW,MAAM;;;;;;;;;;;mCAWF,CAAC,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,IAAI;sCAJ9B,CAAC,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,IAAI;gCAevC,YAAY;mCAJT,YAAY;;EAgCnD"}
1
+ {"version":3,"file":"enter-world.d.ts","sourceRoot":"","sources":["../src/browser/enter-world.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAa,MAAM,eAAe,CAAC;AACrD,OAAO,EAAE,OAAO,EAAE,UAAU,EAA0B,MAAM,yBAAyB,CAAC;AAEtF,KAAK,YAAY,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAC,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;AAEpF,wBAAgB,UAAU,CAAC,EACzB,KAAK,EAAE,OAAuB,EAAE,iBAA6B,EAAE,sBAAsB,EAAE,SAAS,EAChG,WAAW,EACX,WAAW,EACX,kBAAkB,GACnB,EAAE;IACD,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,GAAG,KAAK,IAAI,CAAC;IACjD,iBAAiB,CAAC,EAAE,SAAS,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;IACnD,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,SAAS,CAAC,EAAE,GAAG,CAAC;IAChB,WAAW,CAAC,CAAC,IAAI,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IACzD,WAAW,CAAC,CAAC,IAAI,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,IAAI,CAAC,UAAU,EAAE,QAAQ,GAAC,MAAM,GAAC,UAAU,CAAC,CAAA;KAAE,GAAG,IAAI,CAAC;IAC3G,kBAAkB,CAAC,EAAE,kBAAkB,CAAC;CACzC;;iBA2DqB,GAAG,WAAW,MAAM;;;;;;;;;;;mCAWF,CAAC,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,IAAI;sCAJ9B,CAAC,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,IAAI;gCAevC,YAAY;mCAJT,YAAY;;EAgCnD"}
@@ -1,4 +1,4 @@
1
- function L(A){let{userId:W,appId:E,room:N,host:O,autoRejoin:b=!0,logLine:f}=A,V=!1,C=0,X,S,H=!0,Y=new Map,q=`wss://${O}/room/${E}/${N}?userId=${encodeURIComponent(W)}`;function J(){if(V)return;X=new WebSocket(q),X.onopen=()=>{if(H)A.onOpen?.(),H=!1;C=0},X.onmessage=(Q)=>{try{let c=JSON.parse(Q.data);if(f?.("\uD83D\uDDA5️ ➡️ \uD83D\uDC64",c),c.type==="peer-joined"||c.type==="peer-left")h(c.users);else if(c.peerId&&c.userId)A.onMessage(c.type,c.payload,{userId:c.userId,peerId:c.peerId,receive:(T,G)=>_(T,c.peerId,G)})}catch{f?.("⚠️ ERROR",{error:"invalid-json"})}},X.onclose=(Q)=>{let T=[1001,1006,1011,1012,1013].includes(Q.code);if(b&&!V&&T){let G=Math.min(Math.pow(2,C)*1000,30000),B=Math.random()*1000,Z=G+B;f?.("\uD83D\uDD04 RECONNECTING",{attempt:C+1,delayMs:Math.round(Z)}),C++,S=setTimeout(J,Z)}else A.onClose?.({code:Q.code,reason:Q.reason,wasClean:Q.wasClean})},X.onerror=()=>A.onError?.()}function _(Q,c,T){if(V||X.readyState!==WebSocket.OPEN)return!1;let G={type:Q,to:c,payload:T};return X.send(JSON.stringify(G)),f?.("\uD83D\uDC64 ➡️ \uD83D\uDDA5️",G),!0}function h(Q){let c=[],T=[],G=new Set;Q.forEach(({userId:B,peerId:Z})=>{if(B===W)return;if(!Y.has(Z)){let D={userId:B,peerId:Z,receive:(z,F)=>_(z,Z,F)};Y.set(Z,D),c.push(D)}G.add(Z)});for(let[B,Z]of Y.entries())if(!G.has(B))Y.delete(B),T.push({peerId:B,userId:Z.userId});if(c.length)A.onPeerJoined(c);if(T.length)A.onPeerLeft(T)}return J(),{exitRoom:()=>{V=!0,clearTimeout(S),X.close()}}}function R({userId:A,appId:W,room:E,host:N,autoRejoin:O=!0,onOpen:b,onClose:f,onError:V,onPeerJoined:C,onPeerLeft:X,onMessage:S,logLine:H,workerUrl:Y}){if(!Y)return console.warn("Warning: enterRoom called without workerUrl; this may cause issues in some environments. You should pass workerUrl explicitly. Use:","https://cdn.jsdelivr.net/npm/@dobuki/hello-worker/dist/signal-room.worker.min.js"),L({userId:A,appId:W,room:E,host:N,autoRejoin:O,onOpen:b,onClose:f,onError:V,onPeerJoined:C,onPeerLeft:X,onMessage:S});let q=new Worker(Y,{type:"module"}),J=!1;function _({userId:Q,peerId:c}){return{userId:Q,peerId:c,receive:(T,G)=>{if(J)return!1;return q.postMessage({cmd:"send",toPeerId:c,type:T,payload:G}),!0}}}let h=(Q)=>{let c=Q.data;if(c.kind==="open")b?.();else if(c.kind==="close")q.terminate(),f?.(c.ev);else if(c.kind==="error")V?.();else if(c.kind==="peer-joined")C(c.users.map((T)=>_({userId:T.userId,peerId:T.peerId})));else if(c.kind==="peer-left")X(c.users);else if(c.kind==="message")S(c.type,c.payload,_({userId:c.fromUserId,peerId:c.fromPeerId}));else if(c.kind==="log")H?.(c.direction,c.obj)};return q.addEventListener("message",h),q.postMessage({cmd:"enter",userId:A,appId:W,room:E,host:N,autoRejoin:O}),{exitRoom:()=>{J=!0,q.removeEventListener("message",h),q.postMessage({cmd:"exit"})}}}var U=R;function g({appId:A,receivePeerConnection:W,peerlessUserExpiration:E,rtcConfig:N={iceServers:[{urls:"stun:stun.l.google.com:19302"}]},enterRoomFunction:O=U,logLine:b=console.debug,onLeaveUser:f,workerUrl:V,onRoomReady:C,onRoomClose:X}){let S=`user-${crypto.randomUUID()}`,H=new Map;function Y(c){let T=H.get(c.userId),G=!1;if(!T){let B={userId:c.userId,pc:new RTCPeerConnection(N),pendingRemoteIce:[],peers:new Map};B.peers.set(c.peerId,c),H.set(c.userId,B),B.pc.onicecandidate=(Z)=>{if(!Z.candidate)return;for(let D of B.peers.values())if(D.receive("ice",Z.candidate.toJSON()))break},B.pc.onconnectionstatechange=()=>{b("\uD83D\uDCAC",{event:"pc-state",userId:B.userId,state:B.pc.connectionState})},T=B,H.set(T.userId,T),G=!0}else if(T)clearTimeout(T.expirationTimeout),T.expirationTimeout=0,T.peers.set(c.peerId,c);return[T,G]}function q(c){f?.(c);let T=H.get(c);if(!T)return;try{T.pc.close()}catch{}H.delete(c)}async function J(c){if(!c.pc.remoteDescription)return;let T=c.pendingRemoteIce;c.pendingRemoteIce=[];for(let G of T)try{await c.pc.addIceCandidate(G)}catch(B){b("⚠️ ERROR",{error:"add-ice-failed",userId:c.userId,detail:String(B)})}}let _=new Map;function h({room:c,host:T}){let G=`${T}/room/${c}`,B=_.get(G);if(B)B.exitRoom(),_.delete(G)}function Q({room:c,host:T}){return new Promise((G,B)=>{async function Z(z){let[F]=Y(z),K=F.pc,$=await K.createOffer();await K.setLocalDescription($),z.receive("offer",K.localDescription?.toJSON())}let{exitRoom:D}=O({userId:S,appId:A,room:c,host:T,logLine:b,workerUrl:V,autoRejoin:!0,onOpen(){C?.({room:c,host:T}),G()},onError(){console.error("onError"),B()},onClose(z){X?.({room:c,host:T,ev:z})},onPeerJoined(z){z.forEach((F)=>{let[K,$]=Y(F);if(!$)return;let M=K.pc;W({pc:M,userId:F.userId,initiator:!0}),Z(F)})},onPeerLeft(z){z.forEach(({userId:F,peerId:K})=>{let $=H.get(F);if(!$)return;if($.peers.delete(K),!$.peers.size)$.expirationTimeout=setTimeout(()=>q(F),E??0)})},async onMessage(z,F,K){let[$]=Y(K),M=$.pc;if(z==="offer"){W({pc:M,userId:K.userId,initiator:!1}),await M.setRemoteDescription(F);let x=await M.createAnswer();await M.setLocalDescription(x),K.receive("answer",M.localDescription?.toJSON()),await J($);return}if(z==="answer"){await M.setRemoteDescription(F),await J($);return}if(z==="ice"){let x=F;if(!M.remoteDescription){$.pendingRemoteIce.push(x);return}try{await M.addIceCandidate(x)}catch(j){b("⚠️ ERROR",{error:"add-ice-failed",userId:$.userId,detail:String(j)})}return}}});_.set(`${T}/room/${c}`,{exitRoom:D,room:c,host:T})})}return{userId:S,enterRoom:Q,exitRoom:h,leaveUser:q,end(){_.forEach(({exitRoom:c})=>c()),_.clear(),H.forEach(({userId:c})=>q(c)),H.clear()}}}function d({appId:A,logLine:W=console.debug,enterRoomFunction:E=R,peerlessUserExpiration:N,workerUrl:O,onRoomReady:b,onRoomClose:f}){let V=[],C={iceServers:[{urls:"stun:stun.l.google.com:19302"}]},X=new Set;function S(D,z){z.onopen=()=>{W("\uD83D\uDCAC",{event:"dc-open",userId:D}),V.push(D),Y.forEach((F)=>F(D,"join",V))},z.onmessage=({data:F})=>{X.forEach((K)=>K(F,D)),W("\uD83D\uDCAC",{event:"dc-message",userId:D,data:F})},z.onclose=()=>{W("\uD83D\uDCAC",{event:"dc-close",userId:D}),V.splice(V.indexOf(D),1),Y.forEach((F)=>F(D,"leave",V))},z.onerror=()=>W("⚠️ ERROR",{error:"dc-error",userId:D})}let H=new Map,Y=new Set,{userId:q,enterRoom:J,exitRoom:_,leaveUser:h,end:Q}=g({appId:A,rtcConfig:C,enterRoomFunction:E,logLine:W,workerUrl:O,peerlessUserExpiration:N,onRoomReady:b,onRoomClose:f,onLeaveUser(D){let z=H.get(D);try{z?.close()}catch{}H.delete(D)},receivePeerConnection({pc:D,userId:z,initiator:F}){if(F){let K=D.createDataChannel("data");S(z,K),H.set(z,K)}else D.ondatachannel=(K)=>{let $=K.channel;S(z,$),H.set(z,$),D.ondatachannel=null}}});function c(D,z){H.forEach((F,K)=>{if(z&&K!==z)return;if(F.readyState==="open")F.send(D)})}function T(D){X.delete(D)}function G(D){return X.add(D),()=>{T(D)}}function B(D){Y.delete(D)}function Z(D){return Y.add(D),()=>{B(D)}}return{userId:q,send:c,enterRoom:J,exitRoom:_,leaveUser:h,getUsers:()=>V,addMessageListener:G,removeMessageListener:T,addUserListener:Z,removeUserListener:B,end(){H.forEach((D)=>{try{D.close()}catch{}}),H.clear(),Q(),Y.clear(),V.length=0}}}export{d as enterWorld};
1
+ function L($){let{userId:A,appId:M,room:O,host:h,autoRejoin:b=!0,logLine:f}=$,S=!1,X=0,Z,_,Y=!0,H=new Map,Q=`wss://${h}/room/${M}/${O}?userId=${encodeURIComponent(A)}`;function J(){if(S)return;Z=new WebSocket(Q),Z.onopen=()=>{if(Y)$.onOpen?.(),Y=!1;X=0},Z.onmessage=(K)=>{try{let c=JSON.parse(K.data);if(f?.("\uD83D\uDDA5️ ➡️ \uD83D\uDC64",c),c.type==="peer-joined"||c.type==="peer-left")E(c.users);else if(c.peerId&&c.userId)$.onMessage(c.type,c.payload,{userId:c.userId,peerId:c.peerId,receive:(D,C)=>W(D,c.peerId,C)})}catch{f?.("⚠️ ERROR",{error:"invalid-json"})}},Z.onclose=(K)=>{let D=[1001,1006,1011,1012,1013].includes(K.code);if(b&&!S&&D){let C=Math.min(Math.pow(2,X)*1000,30000),B=Math.random()*1000,V=C+B;f?.("\uD83D\uDD04 RECONNECTING",{attempt:X+1,delayMs:Math.round(V)}),X++,_=setTimeout(J,V)}else $.onClose?.({code:K.code,reason:K.reason,wasClean:K.wasClean})},Z.onerror=()=>$.onError?.()}function W(K,c,D){if(S||Z.readyState!==WebSocket.OPEN)return!1;let C={type:K,to:c,payload:D};return Z.send(JSON.stringify(C)),f?.("\uD83D\uDC64 ➡️ \uD83D\uDDA5️",C),!0}function E(K){let c=[],D=[],C=new Set;K.forEach(({userId:B,peerId:V})=>{if(B===A)return;if(!H.has(V)){let N={userId:B,peerId:V,receive:(T,z)=>W(T,V,z)};H.set(V,N),c.push(N)}C.add(V)});for(let[B,V]of H.entries())if(!C.has(B))H.delete(B),D.push({peerId:B,userId:V.userId});if(c.length)$.onPeerJoined(c);if(D.length)$.onPeerLeft(D)}return J(),{exitRoom:()=>{S=!0,clearTimeout(_),Z.close()}}}function x({userId:$,appId:A,room:M,host:O,autoRejoin:h=!0,onOpen:b,onClose:f,onError:S,onPeerJoined:X,onPeerLeft:Z,onMessage:_,logLine:Y,workerUrl:H}){if(!H)return console.warn("Warning: enterRoom called without workerUrl; this may cause issues in some environments. You should pass workerUrl explicitly. Use:","https://cdn.jsdelivr.net/npm/@dobuki/hello-worker/dist/signal-room.worker.min.js"),L({userId:$,appId:A,room:M,host:O,autoRejoin:h,onOpen:b,onClose:f,onError:S,onPeerJoined:X,onPeerLeft:Z,onMessage:_});let Q=new Worker(H,{type:"module"}),J=!1;function W({userId:K,peerId:c}){return{userId:K,peerId:c,receive:(D,C)=>{if(J)return!1;return Q.postMessage({cmd:"send",toPeerId:c,type:D,payload:C}),!0}}}let E=(K)=>{let c=K.data;if(c.kind==="open")b?.();else if(c.kind==="close")Q.terminate(),f?.(c.ev);else if(c.kind==="error")S?.();else if(c.kind==="peer-joined")X(c.users.map((D)=>W({userId:D.userId,peerId:D.peerId})));else if(c.kind==="peer-left")Z(c.users);else if(c.kind==="message")_(c.type,c.payload,W({userId:c.fromUserId,peerId:c.fromPeerId}));else if(c.kind==="log")Y?.(c.direction,c.obj)};return Q.addEventListener("message",E),Q.postMessage({cmd:"enter",userId:$,appId:A,room:M,host:O,autoRejoin:h}),{exitRoom:()=>{J=!0,Q.removeEventListener("message",E),Q.postMessage({cmd:"exit"})}}}var j=x;function n({appId:$,receivePeerConnection:A,peerlessUserExpiration:M,rtcConfig:O={iceServers:[{urls:"stun:stun.l.google.com:19302"}]},enterRoomFunction:h=j,logLine:b=console.debug,onLeaveUser:f,workerUrl:S,onRoomReady:X,onRoomClose:Z}){let _=`user-${crypto.randomUUID()}`,Y=new Map;function H(c){let D=Y.get(c.userId),C=!1;if(!D){let B={userId:c.userId,pc:new RTCPeerConnection(O),pendingRemoteIce:[],peers:new Map};B.peers.set(c.peerId,c),Y.set(c.userId,B),B.pc.onicecandidate=(V)=>{if(!V.candidate)return;for(let N of B.peers.values())if(N.receive("ice",V.candidate.toJSON()))break},B.pc.onconnectionstatechange=()=>{b("\uD83D\uDCAC",{event:"pc-state",userId:B.userId,state:B.pc.connectionState})},D=B,Y.set(D.userId,D),C=!0}else if(D)clearTimeout(D.expirationTimeout),D.expirationTimeout=0,D.peers.set(c.peerId,c);return[D,C]}function Q(c){f?.(c);let D=Y.get(c);if(!D)return;try{D.pc.close()}catch{}Y.delete(c)}async function J(c){if(!c.pc.remoteDescription)return;let D=c.pendingRemoteIce;c.pendingRemoteIce=[];for(let C of D)try{await c.pc.addIceCandidate(C)}catch(B){b("⚠️ ERROR",{error:"add-ice-failed",userId:c.userId,detail:String(B)})}}let W=new Map;function E({room:c,host:D}){let C=`${D}/room/${c}`,B=W.get(C);if(B)B.exitRoom(),W.delete(C)}function K({room:c,host:D}){return new Promise((C,B)=>{async function V(T){let[z]=H(T),F=z.pc,G=await F.createOffer();await F.setLocalDescription(G),T.receive("offer",F.localDescription?.toJSON())}let{exitRoom:N}=h({userId:_,appId:$,room:c,host:D,logLine:b,workerUrl:S,autoRejoin:!0,onOpen(){X?.({room:c,host:D}),C()},onError(){console.error("onError"),B()},onClose(T){Z?.({room:c,host:D,ev:T})},onPeerJoined(T){T.forEach((z)=>{let[F,G]=H(z);if(!G)return;let q=F.pc;A({pc:q,userId:z.userId,initiator:!0}),V(z)})},onPeerLeft(T){T.forEach(({userId:z,peerId:F})=>{let G=Y.get(z);if(!G)return;if(G.peers.delete(F),!G.peers.size)G.expirationTimeout=setTimeout(()=>Q(z),M??0)})},async onMessage(T,z,F){let[G]=H(F),q=G.pc;if(T==="offer"){A({pc:q,userId:F.userId,initiator:!1}),await q.setRemoteDescription(z);let R=await q.createAnswer();await q.setLocalDescription(R),F.receive("answer",q.localDescription?.toJSON()),await J(G);return}if(T==="answer"){await q.setRemoteDescription(z),await J(G);return}if(T==="ice"){let R=z;if(!q.remoteDescription){G.pendingRemoteIce.push(R);return}try{await q.addIceCandidate(R)}catch(g){b("⚠️ ERROR",{error:"add-ice-failed",userId:G.userId,detail:String(g)})}return}}});W.set(`${D}/room/${c}`,{exitRoom:N,room:c,host:D})})}return{userId:_,enterRoom:K,exitRoom:E,leaveUser:Q,end(){W.forEach(({exitRoom:c})=>c()),W.clear(),Y.forEach(({userId:c})=>Q(c)),Y.clear()}}}function a({appId:$,logLine:A=console.debug,enterRoomFunction:M=x,peerlessUserExpiration:O,workerUrl:h,onRoomReady:b,onRoomClose:f,dataChannelOptions:S}){let X=[],Z={iceServers:[{urls:"stun:stun.l.google.com:19302"}]},_=new Set;function Y(T,z){z.onopen=()=>{A("\uD83D\uDCAC",{event:"dc-open",userId:T}),X.push(T),Q.forEach((F)=>F(T,"join",X))},z.onmessage=({data:F})=>{_.forEach((G)=>G(F,T)),A("\uD83D\uDCAC",{event:"dc-message",userId:T,data:F})},z.onclose=()=>{A("\uD83D\uDCAC",{event:"dc-close",userId:T}),X.splice(X.indexOf(T),1),Q.forEach((F)=>F(T,"leave",X))},z.onerror=()=>A("⚠️ ERROR",{error:"dc-error",userId:T})}let H=new Map,Q=new Set,{userId:J,enterRoom:W,exitRoom:E,leaveUser:K,end:c}=n({appId:$,rtcConfig:Z,enterRoomFunction:M,logLine:A,workerUrl:h,peerlessUserExpiration:O,onRoomReady:b,onRoomClose:f,onLeaveUser(T){let z=H.get(T);try{z?.close()}catch{}H.delete(T)},receivePeerConnection({pc:T,userId:z,initiator:F}){if(F){let G=T.createDataChannel("data",S);Y(z,G),H.set(z,G)}else T.ondatachannel=(G)=>{let q=G.channel;Y(z,q),H.set(z,q),T.ondatachannel=null}}});function D(T,z){H.forEach((F,G)=>{if(z&&G!==z)return;if(F.readyState==="open")F.send(T)})}function C(T){_.delete(T)}function B(T){return _.add(T),()=>{C(T)}}function V(T){Q.delete(T)}function N(T){return Q.add(T),()=>{V(T)}}return{userId:J,send:D,enterRoom:W,exitRoom:E,leaveUser:K,getUsers:()=>X,addMessageListener:B,removeMessageListener:C,addUserListener:N,removeUserListener:V,end(){H.forEach((T)=>{try{T.close()}catch{}}),H.clear(),c(),Q.clear(),X.length=0}}}export{a as enterWorld};
2
2
 
3
- //# debugId=60A3F77FC735907664756E2164756E21
3
+ //# debugId=8A40AA56DDA61A8564756E2164756E21
4
4
  //# sourceMappingURL=enter-world.js.map
@@ -5,9 +5,9 @@
5
5
  "export interface IPeer<T extends string = string, P = any> {\n userId: string;\n peerId: string;\n receive(type: T, payload: P): boolean;\n}\n\n/**\n * enterRoom connects to the signaling room via WebSocket.\n */\nexport function enterRoom<T extends string, P = any>(params: {\n userId: string; appId: string; room: string; host: string;\n onOpen?: () => void;\n onClose?: (ev: Pick<CloseEvent, \"code\" | \"reason\" | \"wasClean\">) => void;\n onError?: () => void;\n logLine?: (direction: string, obj?: any) => void;\n onPeerJoined(users: IPeer<T, P>[]): void;\n onPeerLeft(users: { userId: string, peerId: string }[]): void;\n onMessage(type: T, payload: P, from: IPeer<T, P>): void;\n autoRejoin?: boolean;\n}): { exitRoom: () => void } {\n const { userId, appId, room, host, autoRejoin = true, logLine } = params;\n \n let exited = false;\n let retryCount = 0;\n let ws: WebSocket;\n let timeoutId: ReturnType<typeof setTimeout>;\n let initialConnection = true;\n\n const peers = new Map<string, IPeer<T, P>>();\n const wsUrl = `wss://${host}/room/${appId}/${room}?userId=${encodeURIComponent(userId)}`;\n\n function connect() {\n if (exited) return;\n\n ws = new WebSocket(wsUrl);\n\n ws.onopen = () => {\n if (initialConnection) {\n params.onOpen?.();\n initialConnection = false;\n }\n retryCount = 0; // Reset backoff on successful connection\n };\n\n ws.onmessage = (e: MessageEvent) => {\n // ... (keep your existing JSON parsing and updatePeers logic here)\n try {\n const msg = JSON.parse(e.data);\n logLine?.(\"🖥️ ➡️ 👤\", msg);\n if (msg.type === \"peer-joined\" || msg.type === \"peer-left\") {\n updatePeers(msg.users);\n } else if (msg.peerId && msg.userId) {\n params.onMessage(msg.type, msg.payload, {\n userId: msg.userId,\n peerId: msg.peerId,\n receive: (type: T, payload: P) => send(type, msg.peerId, payload),\n });\n }\n } catch { logLine?.(\"⚠️ ERROR\", { error: \"invalid-json\" }); }\n };\n\n ws.onclose = (ev: CloseEvent) => {\n\n // 1. Check if we should even try to reconnect\n const recoverableCodes = [1001, 1006, 1011, 1012, 1013];\n const isRecoverable = recoverableCodes.includes(ev.code);\n\n if (autoRejoin && !exited && isRecoverable) {\n // 2. Exponential Backoff: 1s, 2s, 4s, 8s... capped at 30s\n const backoff = Math.min(Math.pow(2, retryCount) * 1000, 30000);\n // 3. Add Jitter: +/- 1000ms randomness\n const jitter = Math.random() * 1000;\n const delay = backoff + jitter;\n\n logLine?.(\"🔄 RECONNECTING\", { attempt: retryCount + 1, delayMs: Math.round(delay) });\n \n retryCount++;\n timeoutId = setTimeout(connect, delay);\n } else {\n params.onClose?.({ code: ev.code, reason: ev.reason, wasClean: ev.wasClean });\n }\n };\n\n ws.onerror = () => params.onError?.();\n }\n\n // Helper for sending (uses the current ws instance)\n function send(type: T, toPeerId: string, payload: P) {\n if (exited || ws.readyState !== WebSocket.OPEN) return false;\n const obj = { type, to: toPeerId, payload };\n ws.send(JSON.stringify(obj));\n logLine?.(\"👤 ➡️ 🖥️\", obj);\n return true;\n }\n\n // Helper for peer tracking (logic from your original code)\n function updatePeers(updatedUsers: { peerId: string; userId: string }[]) {\n const joined: IPeer<T, P>[] = [];\n const left: { userId: string; peerId: string }[] = [];\n const updatedPeerSet = new Set<string>();\n\n updatedUsers.forEach(({ userId: pUserId, peerId }) => {\n if (pUserId === userId) return;\n if (!peers.has(peerId)) {\n const newPeer = { userId: pUserId, peerId, receive: (t: T, p: P) => send(t, peerId, p) };\n peers.set(peerId, newPeer);\n joined.push(newPeer);\n }\n updatedPeerSet.add(peerId);\n });\n\n for (const [peerId, peer] of peers.entries()) {\n if (!updatedPeerSet.has(peerId)) {\n peers.delete(peerId);\n left.push({ peerId, userId: peer.userId });\n }\n }\n // Notify peer joined first then peer left. (avoid disconnect in case the peer leaving / joining is on the same user).\n if (joined.length) params.onPeerJoined(joined);\n if (left.length) params.onPeerLeft(left);\n }\n\n // Start initial connection\n connect();\n\n return {\n exitRoom: () => {\n exited = true;\n clearTimeout(timeoutId);\n ws.close();\n },\n };\n}\n",
6
6
  "import type { IPeer } from \"./impl/signal-room.js\";\nimport { enterRoom as baseEnterRoom } from \"./impl/signal-room.js\";\nimport { RoomEvent, WorkerCommand } from \"./signal-room.worker.js\";\n\nexport function enterRoom<T extends string, P = any>({\n userId,\n appId,\n room,\n host,\n autoRejoin = true,\n onOpen,\n onClose,\n onError,\n onPeerJoined,\n onPeerLeft,\n onMessage,\n logLine,\n workerUrl,\n}: {\n userId: string;\n appId: string;\n room: string;\n host: string;\n autoRejoin?: boolean;\n onOpen?: () => void;\n onClose?: (ev: Pick<CloseEvent, \"code\"|\"reason\"|\"wasClean\">) => void;\n onError?: () => void;\n onPeerJoined: (users: IPeer<T, P>[]) => void;\n onPeerLeft: (users: {userId: string, peerId: string}[]) => void;\n onMessage: (type: T, payload: P, from: IPeer<T, P>) => void;\n logLine?: (direction: string, obj?: any) => void;\n\n // Pass the URL to your worker file (bundler will handle it)\n workerUrl?: URL;\n}): { exitRoom: () => void } {\n if (!workerUrl) {\n const CDN_WORKER_URL = `https://cdn.jsdelivr.net/npm/@dobuki/hello-worker/dist/signal-room.worker.min.js`;\n\n console.warn(\"Warning: enterRoom called without workerUrl; this may cause issues in some environments. You should pass workerUrl explicitly. Use:\", CDN_WORKER_URL);\n return baseEnterRoom<T, P>({\n userId,\n appId,\n room,\n host,\n autoRejoin,\n onOpen,\n onClose,\n onError,\n onPeerJoined,\n onPeerLeft,\n onMessage,\n });\n }\n const worker = new Worker(workerUrl, { type: \"module\" });\n let exited = false;\n\n function makeUser({ userId, peerId }: { userId: string; peerId: string }): IPeer<T, P> {\n return {\n userId,\n peerId,\n receive: (type: T, payload: P) => {\n if (exited) return false;\n worker.postMessage({ cmd: \"send\", toPeerId: peerId, type, payload } as WorkerCommand);\n return true;\n },\n };\n }\n\n const onWorkerMessage = (e: MessageEvent<RoomEvent<T, P>>) => {\n const ev = e.data;\n\n if (ev.kind === \"open\") onOpen?.();\n else if (ev.kind === \"close\") {\n worker.terminate();\n onClose?.(ev.ev);\n }\n else if (ev.kind === \"error\") onError?.();\n else if (ev.kind === \"peer-joined\") onPeerJoined(ev.users.map(ev => makeUser({ userId: ev.userId, peerId: ev.peerId })));\n else if (ev.kind === \"peer-left\") onPeerLeft(ev.users);\n else if (ev.kind === \"message\") onMessage(ev.type, ev.payload, makeUser({ userId: ev.fromUserId, peerId: ev.fromPeerId }));\n else if (ev.kind === \"log\") logLine?.(ev.direction, ev.obj);\n };\n\n worker.addEventListener(\"message\", onWorkerMessage);\n\n worker.postMessage({ cmd: \"enter\", userId, appId, room, host, autoRejoin } as WorkerCommand);\n\n return {\n exitRoom: () => {\n exited = true;\n worker.removeEventListener(\"message\", onWorkerMessage);\n worker.postMessage({ cmd: \"exit\" } as WorkerCommand);\n },\n };\n}\n\nexport type EnterRoom<T extends string, P> = typeof enterRoom<T, P>;\n",
7
7
  "import { IPeer } from \"./impl/signal-room\";\nimport { EnterRoom, enterRoom } from \"./signal-room\";\n\nexport type SigType = \"offer\" | \"answer\" | \"ice\";\nexport type SigPayload = RTCSessionDescriptionInit | RTCIceCandidateInit;\n\ntype UserState = {\n userId: string;\n pc: RTCPeerConnection;\n\n // ICE that arrived before we had remoteDescription\n pendingRemoteIce: RTCIceCandidateInit[];\n\n // the signaling \"user\" handle so we can send messages\n peers: Map<string, IPeer<SigType, SigPayload>>;\n\n expirationTimeout?: number;\n};\n\nconst DEFAULT_ENTER_ROOM = enterRoom;\n\n\nexport function collectPeerConnections({\n appId,\n receivePeerConnection,\n peerlessUserExpiration,\n rtcConfig = { iceServers: [{ urls: \"stun:stun.l.google.com:19302\" }] },\n enterRoomFunction: enterRoom = DEFAULT_ENTER_ROOM,\n logLine = console.debug,\n onLeaveUser,\n workerUrl,\n onRoomReady,\n onRoomClose,\n}: {\n appId: string;\n rtcConfig?: RTCConfiguration;\n enterRoomFunction?: EnterRoom<SigType, SigPayload>;\n onLeaveUser?: (userId: string) => void;\n logLine?: (direction: string, obj?: any) => void;\n workerUrl?: URL;\n peerlessUserExpiration?: number;\n receivePeerConnection(connection: { pc: RTCPeerConnection, userId: string, initiator: boolean }): void;\n onRoomReady?(info: { host: string; room: string }): void;\n onRoomClose?(info: { host: string; room: string; ev: Pick<CloseEvent, \"reason\"|\"code\"|\"wasClean\"> }): void;\n}) {\n const userId = `user-${crypto.randomUUID()}`;\n const users: Map<string, UserState> = new Map();\n\n function getPeer(peer: IPeer<SigType, SigPayload>): [UserState, boolean] {\n let state = users.get(peer.userId);\n let isNewPeer = false;\n if (!state) {\n const newState: UserState = {\n userId: peer.userId,\n pc: new RTCPeerConnection(rtcConfig),\n pendingRemoteIce: [],\n peers: new Map(),\n };\n newState.peers.set(peer.peerId, peer);\n users.set(peer.userId, newState);\n\n // Send local ICE candidates to this peer\n newState.pc.onicecandidate = (ev) => {\n if (!ev.candidate) return;\n for(let user of newState.peers.values()) {\n const success = user.receive(\"ice\", ev.candidate.toJSON());\n if (success) break;\n }\n };\n \n newState.pc.onconnectionstatechange = () => {\n logLine(\"💬\", { event: \"pc-state\", userId: newState.userId, state: newState.pc.connectionState });\n };\n state = newState;\n\n // New user\n users.set(state.userId, state);\n isNewPeer = true;\n } else if (state) {\n clearTimeout(state.expirationTimeout);\n state.expirationTimeout = 0;\n state.peers.set(peer.peerId, peer);\n }\n return [state, isNewPeer];\n }\n\n function leaveUser(userId: string) {\n onLeaveUser?.(userId);\n const p = users.get(userId);\n if (!p) return;\n try { p.pc.close(); } catch {}\n users.delete(userId);\n }\n\n async function flushRemoteIce(state: UserState) {\n if (!state.pc.remoteDescription) return;\n\n const queued = state.pendingRemoteIce;\n state.pendingRemoteIce = [];\n\n for (const ice of queued) {\n try {\n await state.pc.addIceCandidate(ice);\n } catch (e) {\n logLine(\"⚠️ ERROR\", { error: \"add-ice-failed\", userId: state.userId, detail: String(e) });\n }\n }\n }\n\n const roomsEntered = new Map<string, { room: string; host: string; exitRoom: () => void }>();\n\n function exit({ room, host }: { room: string; host: string; }) {\n const key = `${host}/room/${room}`;\n const session = roomsEntered.get(key);\n if (session) {\n session.exitRoom();\n roomsEntered.delete(key);\n }\n }\n\n function enter({ room, host }: { room: string; host: string; }) {\n return new Promise<void>((resolve, reject) => {\n async function makeOffer(user: IPeer) {\n // Offer flow: createOffer -> setLocalDescription -> send localDescription\n const [state] = getPeer(user);\n const pc = state.pc;\n const offer = await pc.createOffer();\n await pc.setLocalDescription(offer);\n user.receive(\"offer\", pc.localDescription?.toJSON()!);\n }\n\n const { exitRoom, } = enterRoom({\n userId,\n appId,\n room,\n host,\n logLine,\n workerUrl,\n autoRejoin: true,\n\n onOpen() {\n onRoomReady?.({room, host});\n resolve();\n },\n onError() {\n console.error(\"onError\");\n reject();\n },\n onClose(ev) {\n onRoomClose?.({room, host, ev});\n },\n\n // Existing peers initiate to the newcomer (Option 1)\n onPeerJoined(joiningUsers: IPeer<SigType, SigPayload>[]) {\n joiningUsers.forEach(user => {\n const [state, isNewPeer] = getPeer(user);\n if (!isNewPeer) return;\n const pc = state.pc;\n receivePeerConnection({ pc, userId: user.userId, initiator: true });\n makeOffer(user);\n });\n },\n\n onPeerLeft(leavingUsers: { userId: string; peerId: string }[]) {\n leavingUsers.forEach(({ userId, peerId }) => {\n const state = users.get(userId);\n if (!state) return;\n state.peers.delete(peerId);\n if (!state.peers.size) {\n state.expirationTimeout = setTimeout(() => leaveUser(userId), peerlessUserExpiration ?? 0);\n }\n });\n },\n\n async onMessage(type: SigType, payload: any, from: IPeer) {\n const [state] = getPeer(from);\n const pc = state.pc;\n\n if (type === \"offer\") {\n receivePeerConnection({ pc, userId: from.userId, initiator: false });\n // Responder: set remote offer\n await pc.setRemoteDescription(payload as RTCSessionDescriptionInit);\n\n // Create and send answer\n const answer = await pc.createAnswer();\n await pc.setLocalDescription(answer);\n\n from.receive(\"answer\", pc.localDescription?.toJSON()!);\n\n // Now safe to apply any queued ICE from this peer\n await flushRemoteIce(state);\n return;\n }\n\n if (type === \"answer\") {\n // Initiator: set remote answer\n await pc.setRemoteDescription(payload as RTCSessionDescriptionInit);\n await flushRemoteIce(state);\n return;\n }\n\n if (type === \"ice\") {\n const ice = payload as RTCIceCandidateInit;\n\n // If we don't have remoteDescription yet, queue it\n if (!pc.remoteDescription) {\n state.pendingRemoteIce.push(ice);\n return;\n }\n\n try {\n await pc.addIceCandidate(ice);\n } catch (e) {\n logLine(\"⚠️ ERROR\", { error: \"add-ice-failed\", userId: state.userId, detail: String(e) });\n }\n return;\n }\n },\n });\n roomsEntered.set(`${host}/room/${room}`, { exitRoom, room, host });\n });\n }\n\n return {\n userId,\n enterRoom: enter,\n exitRoom: exit,\n leaveUser,\n end() {\n roomsEntered.forEach(({ exitRoom }) => exitRoom());\n roomsEntered.clear();\n users.forEach(({ userId }) => leaveUser(userId));\n users.clear();\n },\n };\n}\n\n\n\n",
8
- "import { EnterRoom, enterRoom } from \"./signal-room\";\nimport { SigType, SigPayload, collectPeerConnections } from \"./webrtc-peer-collector\";\n\ntype UserListener = (user: string, action: \"join\"|\"leave\", users: string[]) => void;\n\nexport function enterWorld({\n appId, logLine = console.debug, enterRoomFunction = enterRoom, peerlessUserExpiration, workerUrl,\n onRoomReady,\n onRoomClose,\n}: {\n appId: string;\n logLine?: (direction: string, obj?: any) => void;\n enterRoomFunction?: EnterRoom<SigType, SigPayload>;\n peerlessUserExpiration?: number;\n workerUrl?: URL;\n onRoomReady?(info: { host: string; room: string }): void;\n onRoomClose?(info: { host: string; room: string; ev: Pick<CloseEvent, \"reason\"|\"code\"|\"wasClean\"> }): void;\n}) {\n const userIds: string[] = [];\n const rtcConfig: RTCConfiguration = {\n iceServers: [{ urls: \"stun:stun.l.google.com:19302\" }],\n };\n\n const messagesListeners = new Set<(data: any, from: string) => void>();\n\n function wireDataChannel(userId: string, dc: RTCDataChannel) {\n dc.onopen = () => {\n logLine(\"💬\", { event: \"dc-open\", userId });\n userIds.push(userId);\n userListeners.forEach(listener => listener(userId, \"join\", userIds));\n };\n dc.onmessage = ({ data }) => {\n messagesListeners.forEach(listener => listener(data as any, userId));\n logLine(\"💬\", { event: \"dc-message\", userId, data });\n };\n dc.onclose = () => {\n logLine(\"💬\", { event: \"dc-close\", userId });\n userIds.splice(userIds.indexOf(userId), 1);\n userListeners.forEach(listener => listener(userId, \"leave\", userIds));\n };\n dc.onerror = () => logLine(\"⚠️ ERROR\", { error: \"dc-error\", userId });\n }\n\n const dataChannels = new Map<string, RTCDataChannel>();\n const userListeners = new Set<UserListener>();\n\n const { userId, enterRoom, exitRoom, leaveUser, end: endPeerCollection } = collectPeerConnections({\n appId,\n rtcConfig,\n enterRoomFunction,\n logLine,\n workerUrl,\n peerlessUserExpiration,\n onRoomReady,\n onRoomClose,\n onLeaveUser(userId: string) {\n const dc = dataChannels.get(userId);\n try { dc?.close(); } catch { }\n dataChannels.delete(userId);\n },\n receivePeerConnection({ pc, userId, initiator }) {\n if (initiator) {\n const dc = pc.createDataChannel(\"data\");\n wireDataChannel(userId, dc);\n dataChannels.set(userId, dc);\n } else {\n pc.ondatachannel = (ev) => {\n const dc = ev.channel;\n wireDataChannel(userId, dc);\n dataChannels.set(userId, dc);\n pc.ondatachannel = null;\n };\n }\n },\n });\n\n function send(data: any, userId?: string) {\n dataChannels.forEach((dataChannel, pUserId) => {\n if (userId && pUserId !== userId) return;\n if (dataChannel.readyState === \"open\") dataChannel.send(data);\n });\n }\n\n function removeMessageListener(listener: (data: any, from: string) => void) {\n messagesListeners.delete(listener);\n }\n\n function addMessageListener(listener: (data: any, from: string) => void) {\n messagesListeners.add(listener);\n return () => {\n removeMessageListener(listener);\n };\n }\n\n function removeUserListener(listener: UserListener) {\n userListeners.delete(listener);\n }\n\n function addUserListener(listener: UserListener) {\n userListeners.add(listener);\n return () => {\n removeUserListener(listener);\n };\n }\n\n return {\n userId,\n send,\n enterRoom,\n exitRoom,\n leaveUser,\n getUsers: () => userIds,\n addMessageListener,\n removeMessageListener,\n addUserListener,\n removeUserListener,\n end() {\n dataChannels.forEach((dataChannel) => {\n try { dataChannel.close(); } catch { }\n });\n dataChannels.clear();\n endPeerCollection();\n userListeners.clear();\n userIds.length = 0;\n },\n };\n}\n"
8
+ "import { EnterRoom, enterRoom } from \"./signal-room\";\nimport { SigType, SigPayload, collectPeerConnections } from \"./webrtc-peer-collector\";\n\ntype UserListener = (user: string, action: \"join\"|\"leave\", users: string[]) => void;\n\nexport function enterWorld({\n appId, logLine = console.debug, enterRoomFunction = enterRoom, peerlessUserExpiration, workerUrl,\n onRoomReady,\n onRoomClose,\n dataChannelOptions,\n}: {\n appId: string;\n logLine?: (direction: string, obj?: any) => void;\n enterRoomFunction?: EnterRoom<SigType, SigPayload>;\n peerlessUserExpiration?: number;\n workerUrl?: URL;\n onRoomReady?(info: { host: string; room: string }): void;\n onRoomClose?(info: { host: string; room: string; ev: Pick<CloseEvent, \"reason\"|\"code\"|\"wasClean\"> }): void;\n dataChannelOptions?: RTCDataChannelInit;\n}) {\n const userIds: string[] = [];\n const rtcConfig: RTCConfiguration = {\n iceServers: [{ urls: \"stun:stun.l.google.com:19302\" }],\n };\n\n const messagesListeners = new Set<(data: any, from: string) => void>();\n\n function wireDataChannel(userId: string, dc: RTCDataChannel) {\n dc.onopen = () => {\n logLine(\"💬\", { event: \"dc-open\", userId });\n userIds.push(userId);\n userListeners.forEach(listener => listener(userId, \"join\", userIds));\n };\n dc.onmessage = ({ data }) => {\n messagesListeners.forEach(listener => listener(data as any, userId));\n logLine(\"💬\", { event: \"dc-message\", userId, data });\n };\n dc.onclose = () => {\n logLine(\"💬\", { event: \"dc-close\", userId });\n userIds.splice(userIds.indexOf(userId), 1);\n userListeners.forEach(listener => listener(userId, \"leave\", userIds));\n };\n dc.onerror = () => logLine(\"⚠️ ERROR\", { error: \"dc-error\", userId });\n }\n\n const dataChannels = new Map<string, RTCDataChannel>();\n const userListeners = new Set<UserListener>();\n\n const { userId, enterRoom, exitRoom, leaveUser, end: endPeerCollection } = collectPeerConnections({\n appId,\n rtcConfig,\n enterRoomFunction,\n logLine,\n workerUrl,\n peerlessUserExpiration,\n onRoomReady,\n onRoomClose,\n onLeaveUser(userId: string) {\n const dc = dataChannels.get(userId);\n try { dc?.close(); } catch { }\n dataChannels.delete(userId);\n },\n receivePeerConnection({ pc, userId, initiator }) {\n if (initiator) {\n const dc = pc.createDataChannel(\"data\", dataChannelOptions);\n wireDataChannel(userId, dc);\n dataChannels.set(userId, dc);\n } else {\n pc.ondatachannel = (ev) => {\n const dc = ev.channel;\n wireDataChannel(userId, dc);\n dataChannels.set(userId, dc);\n pc.ondatachannel = null;\n };\n }\n },\n });\n\n function send(data: any, userId?: string) {\n dataChannels.forEach((dataChannel, pUserId) => {\n if (userId && pUserId !== userId) return;\n if (dataChannel.readyState === \"open\") dataChannel.send(data);\n });\n }\n\n function removeMessageListener(listener: (data: any, from: string) => void) {\n messagesListeners.delete(listener);\n }\n\n function addMessageListener(listener: (data: any, from: string) => void) {\n messagesListeners.add(listener);\n return () => {\n removeMessageListener(listener);\n };\n }\n\n function removeUserListener(listener: UserListener) {\n userListeners.delete(listener);\n }\n\n function addUserListener(listener: UserListener) {\n userListeners.add(listener);\n return () => {\n removeUserListener(listener);\n };\n }\n\n return {\n userId,\n send,\n enterRoom,\n exitRoom,\n leaveUser,\n getUsers: () => userIds,\n addMessageListener,\n removeMessageListener,\n addUserListener,\n removeUserListener,\n end() {\n dataChannels.forEach((dataChannel) => {\n try { dataChannel.close(); } catch { }\n });\n dataChannels.clear();\n endPeerCollection();\n userListeners.clear();\n userIds.length = 0;\n },\n };\n}\n"
9
9
  ],
10
- "mappings": "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",
11
- "debugId": "60A3F77FC735907664756E2164756E21",
10
+ "mappings": "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",
11
+ "debugId": "8A40AA56DDA61A8564756E2164756E21",
12
12
  "names": []
13
13
  }
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- function n(Y){let{userId:Z,appId:x,room:E,host:N,autoRejoin:q=!0,logLine:C}=Y,K=!1,_=0,Q,S,F=!0,V=new Map,$=`wss://${N}/room/${x}/${E}?userId=${encodeURIComponent(Z)}`;function J(){if(K)return;Q=new WebSocket($),Q.onopen=()=>{if(F)Y.onOpen?.(),F=!1;_=0},Q.onmessage=(H)=>{try{let c=JSON.parse(H.data);if(C?.("\uD83D\uDDA5️ ➡️ \uD83D\uDC64",c),c.type==="peer-joined"||c.type==="peer-left")O(c.users);else if(c.peerId&&c.userId)Y.onMessage(c.type,c.payload,{userId:c.userId,peerId:c.peerId,receive:(T,B)=>A(T,c.peerId,B)})}catch{C?.("⚠️ ERROR",{error:"invalid-json"})}},Q.onclose=(H)=>{let T=[1001,1006,1011,1012,1013].includes(H.code);if(q&&!K&&T){let B=Math.min(Math.pow(2,_)*1000,30000),b=Math.random()*1000,W=B+b;C?.("\uD83D\uDD04 RECONNECTING",{attempt:_+1,delayMs:Math.round(W)}),_++,S=setTimeout(J,W)}else Y.onClose?.({code:H.code,reason:H.reason,wasClean:H.wasClean})},Q.onerror=()=>Y.onError?.()}function A(H,c,T){if(K||Q.readyState!==WebSocket.OPEN)return!1;let B={type:H,to:c,payload:T};return Q.send(JSON.stringify(B)),C?.("\uD83D\uDC64 ➡️ \uD83D\uDDA5️",B),!0}function O(H){let c=[],T=[],B=new Set;H.forEach(({userId:b,peerId:W})=>{if(b===Z)return;if(!V.has(W)){let f={userId:b,peerId:W,receive:(D,z)=>A(D,W,z)};V.set(W,f),c.push(f)}B.add(W)});for(let[b,W]of V.entries())if(!B.has(b))V.delete(b),T.push({peerId:b,userId:W.userId});if(c.length)Y.onPeerJoined(c);if(T.length)Y.onPeerLeft(T)}return J(),{exitRoom:()=>{K=!0,clearTimeout(S),Q.close()}}}function R({userId:Y,appId:Z,room:x,host:E,autoRejoin:N=!0,onOpen:q,onClose:C,onError:K,onPeerJoined:_,onPeerLeft:Q,onMessage:S,logLine:F,workerUrl:V}){if(!V)return console.warn("Warning: enterRoom called without workerUrl; this may cause issues in some environments. You should pass workerUrl explicitly. Use:","https://cdn.jsdelivr.net/npm/@dobuki/hello-worker/dist/signal-room.worker.min.js"),n({userId:Y,appId:Z,room:x,host:E,autoRejoin:N,onOpen:q,onClose:C,onError:K,onPeerJoined:_,onPeerLeft:Q,onMessage:S});let $=new Worker(V,{type:"module"}),J=!1;function A({userId:H,peerId:c}){return{userId:H,peerId:c,receive:(T,B)=>{if(J)return!1;return $.postMessage({cmd:"send",toPeerId:c,type:T,payload:B}),!0}}}let O=(H)=>{let c=H.data;if(c.kind==="open")q?.();else if(c.kind==="close")$.terminate(),C?.(c.ev);else if(c.kind==="error")K?.();else if(c.kind==="peer-joined")_(c.users.map((T)=>A({userId:T.userId,peerId:T.peerId})));else if(c.kind==="peer-left")Q(c.users);else if(c.kind==="message")S(c.type,c.payload,A({userId:c.fromUserId,peerId:c.fromPeerId}));else if(c.kind==="log")F?.(c.direction,c.obj)};return $.addEventListener("message",O),$.postMessage({cmd:"enter",userId:Y,appId:Z,room:x,host:E,autoRejoin:N}),{exitRoom:()=>{J=!0,$.removeEventListener("message",O),$.postMessage({cmd:"exit"})}}}var j=R;function L({appId:Y,receivePeerConnection:Z,peerlessUserExpiration:x,rtcConfig:E={iceServers:[{urls:"stun:stun.l.google.com:19302"}]},enterRoomFunction:N=j,logLine:q=console.debug,onLeaveUser:C,workerUrl:K,onRoomReady:_,onRoomClose:Q}){let S=`user-${crypto.randomUUID()}`,F=new Map;function V(c){let T=F.get(c.userId),B=!1;if(!T){let b={userId:c.userId,pc:new RTCPeerConnection(E),pendingRemoteIce:[],peers:new Map};b.peers.set(c.peerId,c),F.set(c.userId,b),b.pc.onicecandidate=(W)=>{if(!W.candidate)return;for(let f of b.peers.values())if(f.receive("ice",W.candidate.toJSON()))break},b.pc.onconnectionstatechange=()=>{q("\uD83D\uDCAC",{event:"pc-state",userId:b.userId,state:b.pc.connectionState})},T=b,F.set(T.userId,T),B=!0}else if(T)clearTimeout(T.expirationTimeout),T.expirationTimeout=0,T.peers.set(c.peerId,c);return[T,B]}function $(c){C?.(c);let T=F.get(c);if(!T)return;try{T.pc.close()}catch{}F.delete(c)}async function J(c){if(!c.pc.remoteDescription)return;let T=c.pendingRemoteIce;c.pendingRemoteIce=[];for(let B of T)try{await c.pc.addIceCandidate(B)}catch(b){q("⚠️ ERROR",{error:"add-ice-failed",userId:c.userId,detail:String(b)})}}let A=new Map;function O({room:c,host:T}){let B=`${T}/room/${c}`,b=A.get(B);if(b)b.exitRoom(),A.delete(B)}function H({room:c,host:T}){return new Promise((B,b)=>{async function W(D){let[z]=V(D),G=z.pc,X=await G.createOffer();await G.setLocalDescription(X),D.receive("offer",G.localDescription?.toJSON())}let{exitRoom:f}=N({userId:S,appId:Y,room:c,host:T,logLine:q,workerUrl:K,autoRejoin:!0,onOpen(){_?.({room:c,host:T}),B()},onError(){console.error("onError"),b()},onClose(D){Q?.({room:c,host:T,ev:D})},onPeerJoined(D){D.forEach((z)=>{let[G,X]=V(z);if(!X)return;let M=G.pc;Z({pc:M,userId:z.userId,initiator:!0}),W(z)})},onPeerLeft(D){D.forEach(({userId:z,peerId:G})=>{let X=F.get(z);if(!X)return;if(X.peers.delete(G),!X.peers.size)X.expirationTimeout=setTimeout(()=>$(z),x??0)})},async onMessage(D,z,G){let[X]=V(G),M=X.pc;if(D==="offer"){Z({pc:M,userId:G.userId,initiator:!1}),await M.setRemoteDescription(z);let h=await M.createAnswer();await M.setLocalDescription(h),G.receive("answer",M.localDescription?.toJSON()),await J(X);return}if(D==="answer"){await M.setRemoteDescription(z),await J(X);return}if(D==="ice"){let h=z;if(!M.remoteDescription){X.pendingRemoteIce.push(h);return}try{await M.addIceCandidate(h)}catch(g){q("⚠️ ERROR",{error:"add-ice-failed",userId:X.userId,detail:String(g)})}return}}});A.set(`${T}/room/${c}`,{exitRoom:f,room:c,host:T})})}return{userId:S,enterRoom:H,exitRoom:O,leaveUser:$,end(){A.forEach(({exitRoom:c})=>c()),A.clear(),F.forEach(({userId:c})=>$(c)),F.clear()}}}function U({appId:Y,logLine:Z=console.debug,enterRoomFunction:x=R,peerlessUserExpiration:E,workerUrl:N,onRoomReady:q,onRoomClose:C}){let K=[],_={iceServers:[{urls:"stun:stun.l.google.com:19302"}]},Q=new Set;function S(f,D){D.onopen=()=>{Z("\uD83D\uDCAC",{event:"dc-open",userId:f}),K.push(f),V.forEach((z)=>z(f,"join",K))},D.onmessage=({data:z})=>{Q.forEach((G)=>G(z,f)),Z("\uD83D\uDCAC",{event:"dc-message",userId:f,data:z})},D.onclose=()=>{Z("\uD83D\uDCAC",{event:"dc-close",userId:f}),K.splice(K.indexOf(f),1),V.forEach((z)=>z(f,"leave",K))},D.onerror=()=>Z("⚠️ ERROR",{error:"dc-error",userId:f})}let F=new Map,V=new Set,{userId:$,enterRoom:J,exitRoom:A,leaveUser:O,end:H}=L({appId:Y,rtcConfig:_,enterRoomFunction:x,logLine:Z,workerUrl:N,peerlessUserExpiration:E,onRoomReady:q,onRoomClose:C,onLeaveUser(f){let D=F.get(f);try{D?.close()}catch{}F.delete(f)},receivePeerConnection({pc:f,userId:D,initiator:z}){if(z){let G=f.createDataChannel("data");S(D,G),F.set(D,G)}else f.ondatachannel=(G)=>{let X=G.channel;S(D,X),F.set(D,X),f.ondatachannel=null}}});function c(f,D){F.forEach((z,G)=>{if(D&&G!==D)return;if(z.readyState==="open")z.send(f)})}function T(f){Q.delete(f)}function B(f){return Q.add(f),()=>{T(f)}}function b(f){V.delete(f)}function W(f){return V.add(f),()=>{b(f)}}return{userId:$,send:c,enterRoom:J,exitRoom:A,leaveUser:O,getUsers:()=>K,addMessageListener:B,removeMessageListener:T,addUserListener:W,removeUserListener:b,end(){F.forEach((f)=>{try{f.close()}catch{}}),F.clear(),H(),V.clear(),K.length=0}}}export{U as enterWorld,n as enterRoom,L as collectPeerConnections};
1
+ function n(X){let{userId:Y,appId:M,room:O,host:h,autoRejoin:q=!0,logLine:_}=X,S=!1,Q=0,W,A,V=!0,F=new Map,H=`wss://${h}/room/${M}/${O}?userId=${encodeURIComponent(Y)}`;function J(){if(S)return;W=new WebSocket(H),W.onopen=()=>{if(V)X.onOpen?.(),V=!1;Q=0},W.onmessage=(G)=>{try{let c=JSON.parse(G.data);if(_?.("\uD83D\uDDA5️ ➡️ \uD83D\uDC64",c),c.type==="peer-joined"||c.type==="peer-left")x(c.users);else if(c.peerId&&c.userId)X.onMessage(c.type,c.payload,{userId:c.userId,peerId:c.peerId,receive:(D,b)=>Z(D,c.peerId,b)})}catch{_?.("⚠️ ERROR",{error:"invalid-json"})}},W.onclose=(G)=>{let D=[1001,1006,1011,1012,1013].includes(G.code);if(q&&!S&&D){let b=Math.min(Math.pow(2,Q)*1000,30000),C=Math.random()*1000,K=b+C;_?.("\uD83D\uDD04 RECONNECTING",{attempt:Q+1,delayMs:Math.round(K)}),Q++,A=setTimeout(J,K)}else X.onClose?.({code:G.code,reason:G.reason,wasClean:G.wasClean})},W.onerror=()=>X.onError?.()}function Z(G,c,D){if(S||W.readyState!==WebSocket.OPEN)return!1;let b={type:G,to:c,payload:D};return W.send(JSON.stringify(b)),_?.("\uD83D\uDC64 ➡️ \uD83D\uDDA5️",b),!0}function x(G){let c=[],D=[],b=new Set;G.forEach(({userId:C,peerId:K})=>{if(C===Y)return;if(!F.has(K)){let E={userId:C,peerId:K,receive:(T,f)=>Z(T,K,f)};F.set(K,E),c.push(E)}b.add(K)});for(let[C,K]of F.entries())if(!b.has(C))F.delete(C),D.push({peerId:C,userId:K.userId});if(c.length)X.onPeerJoined(c);if(D.length)X.onPeerLeft(D)}return J(),{exitRoom:()=>{S=!0,clearTimeout(A),W.close()}}}function R({userId:X,appId:Y,room:M,host:O,autoRejoin:h=!0,onOpen:q,onClose:_,onError:S,onPeerJoined:Q,onPeerLeft:W,onMessage:A,logLine:V,workerUrl:F}){if(!F)return console.warn("Warning: enterRoom called without workerUrl; this may cause issues in some environments. You should pass workerUrl explicitly. Use:","https://cdn.jsdelivr.net/npm/@dobuki/hello-worker/dist/signal-room.worker.min.js"),n({userId:X,appId:Y,room:M,host:O,autoRejoin:h,onOpen:q,onClose:_,onError:S,onPeerJoined:Q,onPeerLeft:W,onMessage:A});let H=new Worker(F,{type:"module"}),J=!1;function Z({userId:G,peerId:c}){return{userId:G,peerId:c,receive:(D,b)=>{if(J)return!1;return H.postMessage({cmd:"send",toPeerId:c,type:D,payload:b}),!0}}}let x=(G)=>{let c=G.data;if(c.kind==="open")q?.();else if(c.kind==="close")H.terminate(),_?.(c.ev);else if(c.kind==="error")S?.();else if(c.kind==="peer-joined")Q(c.users.map((D)=>Z({userId:D.userId,peerId:D.peerId})));else if(c.kind==="peer-left")W(c.users);else if(c.kind==="message")A(c.type,c.payload,Z({userId:c.fromUserId,peerId:c.fromPeerId}));else if(c.kind==="log")V?.(c.direction,c.obj)};return H.addEventListener("message",x),H.postMessage({cmd:"enter",userId:X,appId:Y,room:M,host:O,autoRejoin:h}),{exitRoom:()=>{J=!0,H.removeEventListener("message",x),H.postMessage({cmd:"exit"})}}}var j=R;function L({appId:X,receivePeerConnection:Y,peerlessUserExpiration:M,rtcConfig:O={iceServers:[{urls:"stun:stun.l.google.com:19302"}]},enterRoomFunction:h=j,logLine:q=console.debug,onLeaveUser:_,workerUrl:S,onRoomReady:Q,onRoomClose:W}){let A=`user-${crypto.randomUUID()}`,V=new Map;function F(c){let D=V.get(c.userId),b=!1;if(!D){let C={userId:c.userId,pc:new RTCPeerConnection(O),pendingRemoteIce:[],peers:new Map};C.peers.set(c.peerId,c),V.set(c.userId,C),C.pc.onicecandidate=(K)=>{if(!K.candidate)return;for(let E of C.peers.values())if(E.receive("ice",K.candidate.toJSON()))break},C.pc.onconnectionstatechange=()=>{q("\uD83D\uDCAC",{event:"pc-state",userId:C.userId,state:C.pc.connectionState})},D=C,V.set(D.userId,D),b=!0}else if(D)clearTimeout(D.expirationTimeout),D.expirationTimeout=0,D.peers.set(c.peerId,c);return[D,b]}function H(c){_?.(c);let D=V.get(c);if(!D)return;try{D.pc.close()}catch{}V.delete(c)}async function J(c){if(!c.pc.remoteDescription)return;let D=c.pendingRemoteIce;c.pendingRemoteIce=[];for(let b of D)try{await c.pc.addIceCandidate(b)}catch(C){q("⚠️ ERROR",{error:"add-ice-failed",userId:c.userId,detail:String(C)})}}let Z=new Map;function x({room:c,host:D}){let b=`${D}/room/${c}`,C=Z.get(b);if(C)C.exitRoom(),Z.delete(b)}function G({room:c,host:D}){return new Promise((b,C)=>{async function K(T){let[f]=F(T),z=f.pc,B=await z.createOffer();await z.setLocalDescription(B),T.receive("offer",z.localDescription?.toJSON())}let{exitRoom:E}=h({userId:A,appId:X,room:c,host:D,logLine:q,workerUrl:S,autoRejoin:!0,onOpen(){Q?.({room:c,host:D}),b()},onError(){console.error("onError"),C()},onClose(T){W?.({room:c,host:D,ev:T})},onPeerJoined(T){T.forEach((f)=>{let[z,B]=F(f);if(!B)return;let $=z.pc;Y({pc:$,userId:f.userId,initiator:!0}),K(f)})},onPeerLeft(T){T.forEach(({userId:f,peerId:z})=>{let B=V.get(f);if(!B)return;if(B.peers.delete(z),!B.peers.size)B.expirationTimeout=setTimeout(()=>H(f),M??0)})},async onMessage(T,f,z){let[B]=F(z),$=B.pc;if(T==="offer"){Y({pc:$,userId:z.userId,initiator:!1}),await $.setRemoteDescription(f);let N=await $.createAnswer();await $.setLocalDescription(N),z.receive("answer",$.localDescription?.toJSON()),await J(B);return}if(T==="answer"){await $.setRemoteDescription(f),await J(B);return}if(T==="ice"){let N=f;if(!$.remoteDescription){B.pendingRemoteIce.push(N);return}try{await $.addIceCandidate(N)}catch(g){q("⚠️ ERROR",{error:"add-ice-failed",userId:B.userId,detail:String(g)})}return}}});Z.set(`${D}/room/${c}`,{exitRoom:E,room:c,host:D})})}return{userId:A,enterRoom:G,exitRoom:x,leaveUser:H,end(){Z.forEach(({exitRoom:c})=>c()),Z.clear(),V.forEach(({userId:c})=>H(c)),V.clear()}}}function U({appId:X,logLine:Y=console.debug,enterRoomFunction:M=R,peerlessUserExpiration:O,workerUrl:h,onRoomReady:q,onRoomClose:_,dataChannelOptions:S}){let Q=[],W={iceServers:[{urls:"stun:stun.l.google.com:19302"}]},A=new Set;function V(T,f){f.onopen=()=>{Y("\uD83D\uDCAC",{event:"dc-open",userId:T}),Q.push(T),H.forEach((z)=>z(T,"join",Q))},f.onmessage=({data:z})=>{A.forEach((B)=>B(z,T)),Y("\uD83D\uDCAC",{event:"dc-message",userId:T,data:z})},f.onclose=()=>{Y("\uD83D\uDCAC",{event:"dc-close",userId:T}),Q.splice(Q.indexOf(T),1),H.forEach((z)=>z(T,"leave",Q))},f.onerror=()=>Y("⚠️ ERROR",{error:"dc-error",userId:T})}let F=new Map,H=new Set,{userId:J,enterRoom:Z,exitRoom:x,leaveUser:G,end:c}=L({appId:X,rtcConfig:W,enterRoomFunction:M,logLine:Y,workerUrl:h,peerlessUserExpiration:O,onRoomReady:q,onRoomClose:_,onLeaveUser(T){let f=F.get(T);try{f?.close()}catch{}F.delete(T)},receivePeerConnection({pc:T,userId:f,initiator:z}){if(z){let B=T.createDataChannel("data",S);V(f,B),F.set(f,B)}else T.ondatachannel=(B)=>{let $=B.channel;V(f,$),F.set(f,$),T.ondatachannel=null}}});function D(T,f){F.forEach((z,B)=>{if(f&&B!==f)return;if(z.readyState==="open")z.send(T)})}function b(T){A.delete(T)}function C(T){return A.add(T),()=>{b(T)}}function K(T){H.delete(T)}function E(T){return H.add(T),()=>{K(T)}}return{userId:J,send:D,enterRoom:Z,exitRoom:x,leaveUser:G,getUsers:()=>Q,addMessageListener:C,removeMessageListener:b,addUserListener:E,removeUserListener:K,end(){F.forEach((T)=>{try{T.close()}catch{}}),F.clear(),c(),H.clear(),Q.length=0}}}export{U as enterWorld,n as enterRoom,L as collectPeerConnections};
2
2
 
3
- //# debugId=A7A04F4BD55B793264756E2164756E21
3
+ //# debugId=5576A8B4E2AE921B64756E2164756E21
4
4
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -5,9 +5,9 @@
5
5
  "export interface IPeer<T extends string = string, P = any> {\n userId: string;\n peerId: string;\n receive(type: T, payload: P): boolean;\n}\n\n/**\n * enterRoom connects to the signaling room via WebSocket.\n */\nexport function enterRoom<T extends string, P = any>(params: {\n userId: string; appId: string; room: string; host: string;\n onOpen?: () => void;\n onClose?: (ev: Pick<CloseEvent, \"code\" | \"reason\" | \"wasClean\">) => void;\n onError?: () => void;\n logLine?: (direction: string, obj?: any) => void;\n onPeerJoined(users: IPeer<T, P>[]): void;\n onPeerLeft(users: { userId: string, peerId: string }[]): void;\n onMessage(type: T, payload: P, from: IPeer<T, P>): void;\n autoRejoin?: boolean;\n}): { exitRoom: () => void } {\n const { userId, appId, room, host, autoRejoin = true, logLine } = params;\n \n let exited = false;\n let retryCount = 0;\n let ws: WebSocket;\n let timeoutId: ReturnType<typeof setTimeout>;\n let initialConnection = true;\n\n const peers = new Map<string, IPeer<T, P>>();\n const wsUrl = `wss://${host}/room/${appId}/${room}?userId=${encodeURIComponent(userId)}`;\n\n function connect() {\n if (exited) return;\n\n ws = new WebSocket(wsUrl);\n\n ws.onopen = () => {\n if (initialConnection) {\n params.onOpen?.();\n initialConnection = false;\n }\n retryCount = 0; // Reset backoff on successful connection\n };\n\n ws.onmessage = (e: MessageEvent) => {\n // ... (keep your existing JSON parsing and updatePeers logic here)\n try {\n const msg = JSON.parse(e.data);\n logLine?.(\"🖥️ ➡️ 👤\", msg);\n if (msg.type === \"peer-joined\" || msg.type === \"peer-left\") {\n updatePeers(msg.users);\n } else if (msg.peerId && msg.userId) {\n params.onMessage(msg.type, msg.payload, {\n userId: msg.userId,\n peerId: msg.peerId,\n receive: (type: T, payload: P) => send(type, msg.peerId, payload),\n });\n }\n } catch { logLine?.(\"⚠️ ERROR\", { error: \"invalid-json\" }); }\n };\n\n ws.onclose = (ev: CloseEvent) => {\n\n // 1. Check if we should even try to reconnect\n const recoverableCodes = [1001, 1006, 1011, 1012, 1013];\n const isRecoverable = recoverableCodes.includes(ev.code);\n\n if (autoRejoin && !exited && isRecoverable) {\n // 2. Exponential Backoff: 1s, 2s, 4s, 8s... capped at 30s\n const backoff = Math.min(Math.pow(2, retryCount) * 1000, 30000);\n // 3. Add Jitter: +/- 1000ms randomness\n const jitter = Math.random() * 1000;\n const delay = backoff + jitter;\n\n logLine?.(\"🔄 RECONNECTING\", { attempt: retryCount + 1, delayMs: Math.round(delay) });\n \n retryCount++;\n timeoutId = setTimeout(connect, delay);\n } else {\n params.onClose?.({ code: ev.code, reason: ev.reason, wasClean: ev.wasClean });\n }\n };\n\n ws.onerror = () => params.onError?.();\n }\n\n // Helper for sending (uses the current ws instance)\n function send(type: T, toPeerId: string, payload: P) {\n if (exited || ws.readyState !== WebSocket.OPEN) return false;\n const obj = { type, to: toPeerId, payload };\n ws.send(JSON.stringify(obj));\n logLine?.(\"👤 ➡️ 🖥️\", obj);\n return true;\n }\n\n // Helper for peer tracking (logic from your original code)\n function updatePeers(updatedUsers: { peerId: string; userId: string }[]) {\n const joined: IPeer<T, P>[] = [];\n const left: { userId: string; peerId: string }[] = [];\n const updatedPeerSet = new Set<string>();\n\n updatedUsers.forEach(({ userId: pUserId, peerId }) => {\n if (pUserId === userId) return;\n if (!peers.has(peerId)) {\n const newPeer = { userId: pUserId, peerId, receive: (t: T, p: P) => send(t, peerId, p) };\n peers.set(peerId, newPeer);\n joined.push(newPeer);\n }\n updatedPeerSet.add(peerId);\n });\n\n for (const [peerId, peer] of peers.entries()) {\n if (!updatedPeerSet.has(peerId)) {\n peers.delete(peerId);\n left.push({ peerId, userId: peer.userId });\n }\n }\n // Notify peer joined first then peer left. (avoid disconnect in case the peer leaving / joining is on the same user).\n if (joined.length) params.onPeerJoined(joined);\n if (left.length) params.onPeerLeft(left);\n }\n\n // Start initial connection\n connect();\n\n return {\n exitRoom: () => {\n exited = true;\n clearTimeout(timeoutId);\n ws.close();\n },\n };\n}\n",
6
6
  "import type { IPeer } from \"./impl/signal-room.js\";\nimport { enterRoom as baseEnterRoom } from \"./impl/signal-room.js\";\nimport { RoomEvent, WorkerCommand } from \"./signal-room.worker.js\";\n\nexport function enterRoom<T extends string, P = any>({\n userId,\n appId,\n room,\n host,\n autoRejoin = true,\n onOpen,\n onClose,\n onError,\n onPeerJoined,\n onPeerLeft,\n onMessage,\n logLine,\n workerUrl,\n}: {\n userId: string;\n appId: string;\n room: string;\n host: string;\n autoRejoin?: boolean;\n onOpen?: () => void;\n onClose?: (ev: Pick<CloseEvent, \"code\"|\"reason\"|\"wasClean\">) => void;\n onError?: () => void;\n onPeerJoined: (users: IPeer<T, P>[]) => void;\n onPeerLeft: (users: {userId: string, peerId: string}[]) => void;\n onMessage: (type: T, payload: P, from: IPeer<T, P>) => void;\n logLine?: (direction: string, obj?: any) => void;\n\n // Pass the URL to your worker file (bundler will handle it)\n workerUrl?: URL;\n}): { exitRoom: () => void } {\n if (!workerUrl) {\n const CDN_WORKER_URL = `https://cdn.jsdelivr.net/npm/@dobuki/hello-worker/dist/signal-room.worker.min.js`;\n\n console.warn(\"Warning: enterRoom called without workerUrl; this may cause issues in some environments. You should pass workerUrl explicitly. Use:\", CDN_WORKER_URL);\n return baseEnterRoom<T, P>({\n userId,\n appId,\n room,\n host,\n autoRejoin,\n onOpen,\n onClose,\n onError,\n onPeerJoined,\n onPeerLeft,\n onMessage,\n });\n }\n const worker = new Worker(workerUrl, { type: \"module\" });\n let exited = false;\n\n function makeUser({ userId, peerId }: { userId: string; peerId: string }): IPeer<T, P> {\n return {\n userId,\n peerId,\n receive: (type: T, payload: P) => {\n if (exited) return false;\n worker.postMessage({ cmd: \"send\", toPeerId: peerId, type, payload } as WorkerCommand);\n return true;\n },\n };\n }\n\n const onWorkerMessage = (e: MessageEvent<RoomEvent<T, P>>) => {\n const ev = e.data;\n\n if (ev.kind === \"open\") onOpen?.();\n else if (ev.kind === \"close\") {\n worker.terminate();\n onClose?.(ev.ev);\n }\n else if (ev.kind === \"error\") onError?.();\n else if (ev.kind === \"peer-joined\") onPeerJoined(ev.users.map(ev => makeUser({ userId: ev.userId, peerId: ev.peerId })));\n else if (ev.kind === \"peer-left\") onPeerLeft(ev.users);\n else if (ev.kind === \"message\") onMessage(ev.type, ev.payload, makeUser({ userId: ev.fromUserId, peerId: ev.fromPeerId }));\n else if (ev.kind === \"log\") logLine?.(ev.direction, ev.obj);\n };\n\n worker.addEventListener(\"message\", onWorkerMessage);\n\n worker.postMessage({ cmd: \"enter\", userId, appId, room, host, autoRejoin } as WorkerCommand);\n\n return {\n exitRoom: () => {\n exited = true;\n worker.removeEventListener(\"message\", onWorkerMessage);\n worker.postMessage({ cmd: \"exit\" } as WorkerCommand);\n },\n };\n}\n\nexport type EnterRoom<T extends string, P> = typeof enterRoom<T, P>;\n",
7
7
  "import { IPeer } from \"./impl/signal-room\";\nimport { EnterRoom, enterRoom } from \"./signal-room\";\n\nexport type SigType = \"offer\" | \"answer\" | \"ice\";\nexport type SigPayload = RTCSessionDescriptionInit | RTCIceCandidateInit;\n\ntype UserState = {\n userId: string;\n pc: RTCPeerConnection;\n\n // ICE that arrived before we had remoteDescription\n pendingRemoteIce: RTCIceCandidateInit[];\n\n // the signaling \"user\" handle so we can send messages\n peers: Map<string, IPeer<SigType, SigPayload>>;\n\n expirationTimeout?: number;\n};\n\nconst DEFAULT_ENTER_ROOM = enterRoom;\n\n\nexport function collectPeerConnections({\n appId,\n receivePeerConnection,\n peerlessUserExpiration,\n rtcConfig = { iceServers: [{ urls: \"stun:stun.l.google.com:19302\" }] },\n enterRoomFunction: enterRoom = DEFAULT_ENTER_ROOM,\n logLine = console.debug,\n onLeaveUser,\n workerUrl,\n onRoomReady,\n onRoomClose,\n}: {\n appId: string;\n rtcConfig?: RTCConfiguration;\n enterRoomFunction?: EnterRoom<SigType, SigPayload>;\n onLeaveUser?: (userId: string) => void;\n logLine?: (direction: string, obj?: any) => void;\n workerUrl?: URL;\n peerlessUserExpiration?: number;\n receivePeerConnection(connection: { pc: RTCPeerConnection, userId: string, initiator: boolean }): void;\n onRoomReady?(info: { host: string; room: string }): void;\n onRoomClose?(info: { host: string; room: string; ev: Pick<CloseEvent, \"reason\"|\"code\"|\"wasClean\"> }): void;\n}) {\n const userId = `user-${crypto.randomUUID()}`;\n const users: Map<string, UserState> = new Map();\n\n function getPeer(peer: IPeer<SigType, SigPayload>): [UserState, boolean] {\n let state = users.get(peer.userId);\n let isNewPeer = false;\n if (!state) {\n const newState: UserState = {\n userId: peer.userId,\n pc: new RTCPeerConnection(rtcConfig),\n pendingRemoteIce: [],\n peers: new Map(),\n };\n newState.peers.set(peer.peerId, peer);\n users.set(peer.userId, newState);\n\n // Send local ICE candidates to this peer\n newState.pc.onicecandidate = (ev) => {\n if (!ev.candidate) return;\n for(let user of newState.peers.values()) {\n const success = user.receive(\"ice\", ev.candidate.toJSON());\n if (success) break;\n }\n };\n \n newState.pc.onconnectionstatechange = () => {\n logLine(\"💬\", { event: \"pc-state\", userId: newState.userId, state: newState.pc.connectionState });\n };\n state = newState;\n\n // New user\n users.set(state.userId, state);\n isNewPeer = true;\n } else if (state) {\n clearTimeout(state.expirationTimeout);\n state.expirationTimeout = 0;\n state.peers.set(peer.peerId, peer);\n }\n return [state, isNewPeer];\n }\n\n function leaveUser(userId: string) {\n onLeaveUser?.(userId);\n const p = users.get(userId);\n if (!p) return;\n try { p.pc.close(); } catch {}\n users.delete(userId);\n }\n\n async function flushRemoteIce(state: UserState) {\n if (!state.pc.remoteDescription) return;\n\n const queued = state.pendingRemoteIce;\n state.pendingRemoteIce = [];\n\n for (const ice of queued) {\n try {\n await state.pc.addIceCandidate(ice);\n } catch (e) {\n logLine(\"⚠️ ERROR\", { error: \"add-ice-failed\", userId: state.userId, detail: String(e) });\n }\n }\n }\n\n const roomsEntered = new Map<string, { room: string; host: string; exitRoom: () => void }>();\n\n function exit({ room, host }: { room: string; host: string; }) {\n const key = `${host}/room/${room}`;\n const session = roomsEntered.get(key);\n if (session) {\n session.exitRoom();\n roomsEntered.delete(key);\n }\n }\n\n function enter({ room, host }: { room: string; host: string; }) {\n return new Promise<void>((resolve, reject) => {\n async function makeOffer(user: IPeer) {\n // Offer flow: createOffer -> setLocalDescription -> send localDescription\n const [state] = getPeer(user);\n const pc = state.pc;\n const offer = await pc.createOffer();\n await pc.setLocalDescription(offer);\n user.receive(\"offer\", pc.localDescription?.toJSON()!);\n }\n\n const { exitRoom, } = enterRoom({\n userId,\n appId,\n room,\n host,\n logLine,\n workerUrl,\n autoRejoin: true,\n\n onOpen() {\n onRoomReady?.({room, host});\n resolve();\n },\n onError() {\n console.error(\"onError\");\n reject();\n },\n onClose(ev) {\n onRoomClose?.({room, host, ev});\n },\n\n // Existing peers initiate to the newcomer (Option 1)\n onPeerJoined(joiningUsers: IPeer<SigType, SigPayload>[]) {\n joiningUsers.forEach(user => {\n const [state, isNewPeer] = getPeer(user);\n if (!isNewPeer) return;\n const pc = state.pc;\n receivePeerConnection({ pc, userId: user.userId, initiator: true });\n makeOffer(user);\n });\n },\n\n onPeerLeft(leavingUsers: { userId: string; peerId: string }[]) {\n leavingUsers.forEach(({ userId, peerId }) => {\n const state = users.get(userId);\n if (!state) return;\n state.peers.delete(peerId);\n if (!state.peers.size) {\n state.expirationTimeout = setTimeout(() => leaveUser(userId), peerlessUserExpiration ?? 0);\n }\n });\n },\n\n async onMessage(type: SigType, payload: any, from: IPeer) {\n const [state] = getPeer(from);\n const pc = state.pc;\n\n if (type === \"offer\") {\n receivePeerConnection({ pc, userId: from.userId, initiator: false });\n // Responder: set remote offer\n await pc.setRemoteDescription(payload as RTCSessionDescriptionInit);\n\n // Create and send answer\n const answer = await pc.createAnswer();\n await pc.setLocalDescription(answer);\n\n from.receive(\"answer\", pc.localDescription?.toJSON()!);\n\n // Now safe to apply any queued ICE from this peer\n await flushRemoteIce(state);\n return;\n }\n\n if (type === \"answer\") {\n // Initiator: set remote answer\n await pc.setRemoteDescription(payload as RTCSessionDescriptionInit);\n await flushRemoteIce(state);\n return;\n }\n\n if (type === \"ice\") {\n const ice = payload as RTCIceCandidateInit;\n\n // If we don't have remoteDescription yet, queue it\n if (!pc.remoteDescription) {\n state.pendingRemoteIce.push(ice);\n return;\n }\n\n try {\n await pc.addIceCandidate(ice);\n } catch (e) {\n logLine(\"⚠️ ERROR\", { error: \"add-ice-failed\", userId: state.userId, detail: String(e) });\n }\n return;\n }\n },\n });\n roomsEntered.set(`${host}/room/${room}`, { exitRoom, room, host });\n });\n }\n\n return {\n userId,\n enterRoom: enter,\n exitRoom: exit,\n leaveUser,\n end() {\n roomsEntered.forEach(({ exitRoom }) => exitRoom());\n roomsEntered.clear();\n users.forEach(({ userId }) => leaveUser(userId));\n users.clear();\n },\n };\n}\n\n\n\n",
8
- "import { EnterRoom, enterRoom } from \"./signal-room\";\nimport { SigType, SigPayload, collectPeerConnections } from \"./webrtc-peer-collector\";\n\ntype UserListener = (user: string, action: \"join\"|\"leave\", users: string[]) => void;\n\nexport function enterWorld({\n appId, logLine = console.debug, enterRoomFunction = enterRoom, peerlessUserExpiration, workerUrl,\n onRoomReady,\n onRoomClose,\n}: {\n appId: string;\n logLine?: (direction: string, obj?: any) => void;\n enterRoomFunction?: EnterRoom<SigType, SigPayload>;\n peerlessUserExpiration?: number;\n workerUrl?: URL;\n onRoomReady?(info: { host: string; room: string }): void;\n onRoomClose?(info: { host: string; room: string; ev: Pick<CloseEvent, \"reason\"|\"code\"|\"wasClean\"> }): void;\n}) {\n const userIds: string[] = [];\n const rtcConfig: RTCConfiguration = {\n iceServers: [{ urls: \"stun:stun.l.google.com:19302\" }],\n };\n\n const messagesListeners = new Set<(data: any, from: string) => void>();\n\n function wireDataChannel(userId: string, dc: RTCDataChannel) {\n dc.onopen = () => {\n logLine(\"💬\", { event: \"dc-open\", userId });\n userIds.push(userId);\n userListeners.forEach(listener => listener(userId, \"join\", userIds));\n };\n dc.onmessage = ({ data }) => {\n messagesListeners.forEach(listener => listener(data as any, userId));\n logLine(\"💬\", { event: \"dc-message\", userId, data });\n };\n dc.onclose = () => {\n logLine(\"💬\", { event: \"dc-close\", userId });\n userIds.splice(userIds.indexOf(userId), 1);\n userListeners.forEach(listener => listener(userId, \"leave\", userIds));\n };\n dc.onerror = () => logLine(\"⚠️ ERROR\", { error: \"dc-error\", userId });\n }\n\n const dataChannels = new Map<string, RTCDataChannel>();\n const userListeners = new Set<UserListener>();\n\n const { userId, enterRoom, exitRoom, leaveUser, end: endPeerCollection } = collectPeerConnections({\n appId,\n rtcConfig,\n enterRoomFunction,\n logLine,\n workerUrl,\n peerlessUserExpiration,\n onRoomReady,\n onRoomClose,\n onLeaveUser(userId: string) {\n const dc = dataChannels.get(userId);\n try { dc?.close(); } catch { }\n dataChannels.delete(userId);\n },\n receivePeerConnection({ pc, userId, initiator }) {\n if (initiator) {\n const dc = pc.createDataChannel(\"data\");\n wireDataChannel(userId, dc);\n dataChannels.set(userId, dc);\n } else {\n pc.ondatachannel = (ev) => {\n const dc = ev.channel;\n wireDataChannel(userId, dc);\n dataChannels.set(userId, dc);\n pc.ondatachannel = null;\n };\n }\n },\n });\n\n function send(data: any, userId?: string) {\n dataChannels.forEach((dataChannel, pUserId) => {\n if (userId && pUserId !== userId) return;\n if (dataChannel.readyState === \"open\") dataChannel.send(data);\n });\n }\n\n function removeMessageListener(listener: (data: any, from: string) => void) {\n messagesListeners.delete(listener);\n }\n\n function addMessageListener(listener: (data: any, from: string) => void) {\n messagesListeners.add(listener);\n return () => {\n removeMessageListener(listener);\n };\n }\n\n function removeUserListener(listener: UserListener) {\n userListeners.delete(listener);\n }\n\n function addUserListener(listener: UserListener) {\n userListeners.add(listener);\n return () => {\n removeUserListener(listener);\n };\n }\n\n return {\n userId,\n send,\n enterRoom,\n exitRoom,\n leaveUser,\n getUsers: () => userIds,\n addMessageListener,\n removeMessageListener,\n addUserListener,\n removeUserListener,\n end() {\n dataChannels.forEach((dataChannel) => {\n try { dataChannel.close(); } catch { }\n });\n dataChannels.clear();\n endPeerCollection();\n userListeners.clear();\n userIds.length = 0;\n },\n };\n}\n"
8
+ "import { EnterRoom, enterRoom } from \"./signal-room\";\nimport { SigType, SigPayload, collectPeerConnections } from \"./webrtc-peer-collector\";\n\ntype UserListener = (user: string, action: \"join\"|\"leave\", users: string[]) => void;\n\nexport function enterWorld({\n appId, logLine = console.debug, enterRoomFunction = enterRoom, peerlessUserExpiration, workerUrl,\n onRoomReady,\n onRoomClose,\n dataChannelOptions,\n}: {\n appId: string;\n logLine?: (direction: string, obj?: any) => void;\n enterRoomFunction?: EnterRoom<SigType, SigPayload>;\n peerlessUserExpiration?: number;\n workerUrl?: URL;\n onRoomReady?(info: { host: string; room: string }): void;\n onRoomClose?(info: { host: string; room: string; ev: Pick<CloseEvent, \"reason\"|\"code\"|\"wasClean\"> }): void;\n dataChannelOptions?: RTCDataChannelInit;\n}) {\n const userIds: string[] = [];\n const rtcConfig: RTCConfiguration = {\n iceServers: [{ urls: \"stun:stun.l.google.com:19302\" }],\n };\n\n const messagesListeners = new Set<(data: any, from: string) => void>();\n\n function wireDataChannel(userId: string, dc: RTCDataChannel) {\n dc.onopen = () => {\n logLine(\"💬\", { event: \"dc-open\", userId });\n userIds.push(userId);\n userListeners.forEach(listener => listener(userId, \"join\", userIds));\n };\n dc.onmessage = ({ data }) => {\n messagesListeners.forEach(listener => listener(data as any, userId));\n logLine(\"💬\", { event: \"dc-message\", userId, data });\n };\n dc.onclose = () => {\n logLine(\"💬\", { event: \"dc-close\", userId });\n userIds.splice(userIds.indexOf(userId), 1);\n userListeners.forEach(listener => listener(userId, \"leave\", userIds));\n };\n dc.onerror = () => logLine(\"⚠️ ERROR\", { error: \"dc-error\", userId });\n }\n\n const dataChannels = new Map<string, RTCDataChannel>();\n const userListeners = new Set<UserListener>();\n\n const { userId, enterRoom, exitRoom, leaveUser, end: endPeerCollection } = collectPeerConnections({\n appId,\n rtcConfig,\n enterRoomFunction,\n logLine,\n workerUrl,\n peerlessUserExpiration,\n onRoomReady,\n onRoomClose,\n onLeaveUser(userId: string) {\n const dc = dataChannels.get(userId);\n try { dc?.close(); } catch { }\n dataChannels.delete(userId);\n },\n receivePeerConnection({ pc, userId, initiator }) {\n if (initiator) {\n const dc = pc.createDataChannel(\"data\", dataChannelOptions);\n wireDataChannel(userId, dc);\n dataChannels.set(userId, dc);\n } else {\n pc.ondatachannel = (ev) => {\n const dc = ev.channel;\n wireDataChannel(userId, dc);\n dataChannels.set(userId, dc);\n pc.ondatachannel = null;\n };\n }\n },\n });\n\n function send(data: any, userId?: string) {\n dataChannels.forEach((dataChannel, pUserId) => {\n if (userId && pUserId !== userId) return;\n if (dataChannel.readyState === \"open\") dataChannel.send(data);\n });\n }\n\n function removeMessageListener(listener: (data: any, from: string) => void) {\n messagesListeners.delete(listener);\n }\n\n function addMessageListener(listener: (data: any, from: string) => void) {\n messagesListeners.add(listener);\n return () => {\n removeMessageListener(listener);\n };\n }\n\n function removeUserListener(listener: UserListener) {\n userListeners.delete(listener);\n }\n\n function addUserListener(listener: UserListener) {\n userListeners.add(listener);\n return () => {\n removeUserListener(listener);\n };\n }\n\n return {\n userId,\n send,\n enterRoom,\n exitRoom,\n leaveUser,\n getUsers: () => userIds,\n addMessageListener,\n removeMessageListener,\n addUserListener,\n removeUserListener,\n end() {\n dataChannels.forEach((dataChannel) => {\n try { dataChannel.close(); } catch { }\n });\n dataChannels.clear();\n endPeerCollection();\n userListeners.clear();\n userIds.length = 0;\n },\n };\n}\n"
9
9
  ],
10
- "mappings": "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",
11
- "debugId": "A7A04F4BD55B793264756E2164756E21",
10
+ "mappings": "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",
11
+ "debugId": "5576A8B4E2AE921B64756E2164756E21",
12
12
  "names": []
13
13
  }
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/browser/sample/index.ts"],"names":[],"mappings":"AAuBA,wBAAgB,QAAQ,SAEvB;AAED,wBAAgB,WAAW,eAqC1B;AAED,wBAAgB,UAAU,eAoHzB"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/browser/sample/index.ts"],"names":[],"mappings":"AAuBA,wBAAgB,QAAQ,SAEvB;AAED,wBAAgB,WAAW,eAqC1B;AAED,wBAAgB,UAAU,eAuHzB"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dobuki/hello-worker",
3
- "version": "1.0.25",
3
+ "version": "1.0.26",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",