@dobuki/hello-worker 1.0.49 → 1.0.51
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/enter-world.d.ts.map +1 -1
- package/dist/enter-world.js +2 -2
- package/dist/enter-world.js.map +3 -3
- package/dist/index.js +2 -2
- package/dist/index.js.map +3 -3
- package/package.json +1 -1
|
@@ -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,EACL,OAAO,EACP,UAAU,EAEX,MAAM,yBAAyB,CAAC;AAEjC,KAAK,YAAY,GAAG,CAClB,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,GAAG,OAAO,EACxB,KAAK,EAAE,MAAM,EAAE,KACZ,IAAI,CAAC;AAEV,wBAAgB,UAAU,CAAC,CAAC,SAAS,MAAM,GAAG,UAAU,EAAE,EACxD,KAAK,EACL,OAAuB,EACvB,iBAA6B,EAC7B,sBAAsB,EACtB,SAAS,EACT,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;QACjB,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,EAAE,EAAE,IAAI,CAAC,UAAU,EAAE,QAAQ,GAAG,MAAM,GAAG,UAAU,CAAC,CAAC;KACtD,GAAG,IAAI,CAAC;IACT,kBAAkB,CAAC,EAAE,kBAAkB,CAAC;CACzC;;
|
|
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,EACL,OAAO,EACP,UAAU,EAEX,MAAM,yBAAyB,CAAC;AAEjC,KAAK,YAAY,GAAG,CAClB,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,GAAG,OAAO,EACxB,KAAK,EAAE,MAAM,EAAE,KACZ,IAAI,CAAC;AAEV,wBAAgB,UAAU,CAAC,CAAC,SAAS,MAAM,GAAG,UAAU,EAAE,EACxD,KAAK,EACL,OAAuB,EACvB,iBAA6B,EAC7B,sBAAsB,EACtB,SAAS,EACT,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;QACjB,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,EAAE,EAAE,IAAI,CAAC,UAAU,EAAE,QAAQ,GAAG,MAAM,GAAG,UAAU,CAAC,CAAC;KACtD,GAAG,IAAI,CAAC;IACT,kBAAkB,CAAC,EAAE,kBAAkB,CAAC;CACzC;;iBAkFqB,CAAC,WAAW,MAAM;;;;;;;;;;;mCAaA,CAAC,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,KAAK,IAAI;sCAJ5B,CAAC,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,KAAK,IAAI;gCAerC,YAAY;mCAJT,YAAY;;EAkCnD"}
|
package/dist/enter-world.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
function w(M){let{userId:B,appId:C,room:j,host:
|
|
1
|
+
function w(M){let{userId:B,appId:C,room:j,host:P,autoRejoin:h=!0,logLine:T}=M,L=!1,H=0,S,R,W=!0,E=new Map,F=`wss://${P}/room/${C}/${j}?userId=${encodeURIComponent(B)}`;function K($,q,Q){if(!S)return!1;if(L||S.readyState!==WebSocket.OPEN)return!1;let X={type:$,to:q,payload:Q};return S.send(JSON.stringify(X)),T?.("\uD83D\uDC64 ➡️ \uD83D\uDDA5️",X),!0}function O(){if(L)return;S=new WebSocket(F),S.onopen=()=>{if(W)M.onOpen?.(),W=!1;H=0},S.onmessage=($)=>{try{let q=JSON.parse($.data);(Array.isArray(q)?q:[q]).forEach((X)=>{if(T?.("\uD83D\uDDA5️ ➡️ \uD83D\uDC64",X),X.type==="peer-joined"||X.type==="peer-left")_(X.users);else if(X.type==="ice-server")M.onIceUrl?.(X.url);else if(X.userId)M.onMessage(X.type,X.payload,{userId:X.userId,receive:(b,D)=>K(b,X.userId,D)})})}catch{T?.("⚠️ ERROR",{error:"invalid-json"})}},S.onclose=($)=>{let Q=[1001,1006,1011,1012,1013].includes($.code);if(h&&!L&&Q){let X=Math.min(Math.pow(2,H)*1000,30000),b=Math.random()*1000,D=X+b;T?.("\uD83D\uDD04 RECONNECTING",{attempt:H+1,delayMs:Math.round(D)}),H++,R=setTimeout(O,D)}else M.onClose?.({code:$.code,reason:$.reason,wasClean:$.wasClean})},S.onerror=($)=>{console.error("WS Error",$),M.onError?.()}}function _($){let q=[],Q=[],X=new Set;$.forEach(({userId:b})=>{if(b===B)return;if(!E.has(B)){let D={userId:b,receive:(V,G)=>K(V,b,G)};E.set(B,D),q.push(D)}X.add(B)});for(let b of E.keys())if(!X.has(b))E.delete(b),Q.push({userId:b});if(q.length)M.onPeerJoined(q);if(Q.length)M.onPeerLeft(Q)}return O(),{exitRoom:()=>{L=!0,clearTimeout(R),S.close()}}}function c({userId:M,appId:B,room:C,host:j,autoRejoin:P=!0,onOpen:h,onClose:T,onError:L,onPeerJoined:H,onPeerLeft:S,onIceUrl:R,onMessage:W,logLine:E,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"),w({userId:M,appId:B,room:C,host:j,autoRejoin:P,onOpen:h,onClose:T,onError:L,onPeerJoined:H,onPeerLeft:S,onIceUrl:R,onMessage:W});let K=new Worker(F,{type:"module"}),O=!1;function _({userId:q}){return{userId:q,receive:(Q,X)=>{if(O)return!1;return K.postMessage({cmd:"send",toUserId:q,host:j,room:C,type:Q,payload:X}),!0}}}let $=(q)=>{let Q=q.data;if(Q.kind==="open")h?.();else if(Q.kind==="close")K.terminate(),T?.(Q.ev);else if(Q.kind==="error")L?.();else if(Q.kind==="peer-joined")H(Q.users.map((X)=>_({userId:X.userId})));else if(Q.kind==="peer-left")S(Q.users);else if(Q.kind==="ice-server")R?.(Q.url);else if(Q.kind==="message")W(Q.type,Q.payload,_({userId:Q.fromUserId}));else if(Q.kind==="log")E?.(Q.direction,Q.obj)};return K.addEventListener("message",$),K.postMessage({cmd:"enter",userId:M,appId:B,room:C,host:j,autoRejoin:P}),{exitRoom:()=>{O=!0,K.removeEventListener("message",$),K.postMessage({cmd:"exit"})}}}var g=c;function y({appId:M,receivePeerConnection:B,peerlessUserExpiration:C=5000,fallbackRtcConfig:j={iceServers:[{urls:"stun:stun.l.google.com:19302"}]},enterRoomFunction:P=g,logLine:h=console.debug,onLeaveUser:T,workerUrl:L,onRoomReady:H,onRoomClose:S}){let R=`user-${crypto.randomUUID()}`,W=new Map,E=void 0,F;async function K(){if(E)try{let D=await fetch(E);if(!D.ok)throw Error(`ICE endpoint failed: ${D.status}`);F=await D.json()}catch(D){console.warn("Using fallback rtcConfig:",D)}return j}async function O(D){return D.pc=new RTCPeerConnection(Date.now()-(F?.timestamp??0)<1e4?F:await K()),D.pc.onicecandidate=(V)=>{if(!V.candidate)return;D.peer.receive("ice",V.candidate.toJSON())},D.pc.onconnectionstatechange=()=>{h("\uD83D\uDCAC",{event:"pc-state",userId:D.userId,state:D.pc?.connectionState})},D.pc}async function _(D){let V=W.get(D.userId),G=!1;if(!V){let Y={userId:D.userId,pendingRemoteIce:[],peer:D};W.set(D.userId,Y),await O(Y),V=Y,W.set(V.userId,V),G=!0}else if(V)clearTimeout(V.expirationTimeout),V.expirationTimeout=0;if(!V.pc)await O(V);return V.peer=D,[V,G]}function $(D){T?.(D);let V=W.get(D);if(!V)return;try{V.pc?.close()}catch{}W.delete(D)}async function q(D){if(!D.pc?.remoteDescription)return;let V=D.pendingRemoteIce;D.pendingRemoteIce=[];for(let G of V)try{await D.pc.addIceCandidate(G)}catch(Y){h("⚠️ ERROR",{error:"add-ice-failed",userId:D.userId,detail:String(Y)})}}let Q=new Map;function X({room:D,host:V}){let G=`${V}/room/${D}`,Y=Q.get(G);if(Y)Y.exitRoom(),Q.delete(G)}function b({room:D,host:V}){return new Promise(async(G,Y)=>{async function x(Z){let[z]=await _(Z),A=z.pc,f=await A?.createOffer();await A?.setLocalDescription(f),Z.receive("offer",A?.localDescription?.toJSON())}let{exitRoom:N}=P({userId:R,appId:M,room:D,host:V,logLine:h,workerUrl:L,autoRejoin:!0,onOpen(){H?.({room:D,host:V}),G()},onError(){console.error("onError"),Y()},onClose(Z){S?.({room:D,host:V,ev:Z})},onPeerJoined(Z){Z.forEach(async(z)=>{let[A,f]=await _(z);if(!f)return;let J=A.pc;if(!J)return;async function k(){let n=W.get(z.userId);if(n){n.pc=void 0;let v=await O(n);B({pc:v,userId:z.userId,initiator:!0,restart:k}),await new Promise((U)=>setTimeout(U,3000)),x(z)}}B({pc:J,userId:z.userId,initiator:!0,restart:k}),x(z)})},onPeerLeft(Z){Z.forEach(({userId:z})=>{let A=W.get(z);if(!A)return;A.expirationTimeout=setTimeout(()=>$(z),C??0)})},onIceUrl(Z){E=Z},async onMessage(Z,z,A){let[f]=await _(A),J=f.pc;if(!J)return;if(Z==="offer"){B({pc:J,userId:A.userId,initiator:!1,restart(){f.pc=void 0}}),await J.setRemoteDescription(z);let k=await J.createAnswer();await J.setLocalDescription(k),A.receive("answer",J.localDescription?.toJSON()),await q(f);return}if(Z==="answer"){await J.setRemoteDescription(z),await q(f);return}if(Z==="ice"){let k=z;if(!J.remoteDescription){f.pendingRemoteIce.push(k);return}try{await J.addIceCandidate(k)}catch(n){h("⚠️ ERROR",{error:"add-ice-failed",userId:f.userId,detail:String(n)})}return}}});Q.set(`${V}/room/${D}`,{exitRoom:N,room:D,host:V})})}return{userId:R,enterRoom:b,exitRoom:X,leaveUser:$,end(){Q.forEach(({exitRoom:D})=>D()),Q.clear(),W.forEach(({userId:D})=>$(D)),W.clear()}}}function r({appId:M,logLine:B=console.debug,enterRoomFunction:C=c,peerlessUserExpiration:j,workerUrl:P,onRoomReady:h,onRoomClose:T,dataChannelOptions:L}){let H=[],S=new Set;function R(G,Y,x,N){if(x){let Z=G.createDataChannel("data",L);W(Y,Z,N),E.set(Y,Z)}else{let Z=function(z){let A=z.channel;W(Y,A,N),E.set(Y,A)};return G.addEventListener("datachannel",Z),()=>{G.removeEventListener("datachannel",Z)}}}function W(G,Y,x){Y.onopen=()=>{B("\uD83D\uDCAC",{event:"dc-open",userId:G}),H.push(G),F.forEach((Z)=>Z(G,"join",H))};let N=({data:Z})=>{S.forEach((z)=>z(Z,G)),B("\uD83D\uDCAC",{event:"dc-message",userId:G,data:Z})};Y.addEventListener("message",N),Y.addEventListener("close",()=>{B("\uD83D\uDCAC",{event:"dc-close",userId:G}),H.splice(H.indexOf(G),1),F.forEach((Z)=>Z(G,"leave",H)),Y.removeEventListener("message",N),x?.()}),Y.onerror=()=>B("⚠️ ERROR",{error:"dc-error",userId:G})}let E=new Map,F=new Set,{userId:K,enterRoom:O,exitRoom:_,leaveUser:$,end:q}=y({appId:M,enterRoomFunction:C,logLine:B,workerUrl:P,peerlessUserExpiration:j,onRoomReady:h,onRoomClose:T,onLeaveUser(G){let Y=E.get(G);try{Y?.close()}catch{}E.delete(G)},receivePeerConnection({pc:G,userId:Y,initiator:x,restart:N}){R(G,Y,x,N)}});function Q(G,Y){E.forEach((x,N)=>{if(Y&&N!==Y)return;if(x.readyState==="open")x.send(G)})}function X(G){S.delete(G)}function b(G){return S.add(G),()=>{X(G)}}function D(G){F.delete(G)}function V(G){return F.add(G),()=>{D(G)}}return{userId:K,send:Q,enterRoom:O,exitRoom:_,leaveUser:$,getUsers:()=>H,addMessageListener:b,removeMessageListener:X,addUserListener:V,removeUserListener:D,end(){E.forEach((G)=>{try{G.close()}catch{}}),E.clear(),q(),F.clear(),H.length=0}}}export{r as enterWorld};
|
|
2
2
|
|
|
3
|
-
//# debugId=
|
|
3
|
+
//# debugId=609FE715C165393064756E2164756E21
|
|
4
4
|
//# sourceMappingURL=enter-world.js.map
|
package/dist/enter-world.js.map
CHANGED
|
@@ -5,9 +5,9 @@
|
|
|
5
5
|
"export interface IPeer<T extends string = string, P = any> {\n userId: 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;\n appId: string;\n room: string;\n 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 }[]): void;\n onIceUrl?(url: string): void;\n onMessage(type: T, payload: P, from: IPeer<T, P>): void;\n autoRejoin?: boolean;\n}): { exitRoom: () => void } {\n type Message = {\n type: \"peer-joined\" | \"peer-left\" | \"ice-server\" | T;\n userId: string;\n users: { userId: string }[];\n payload: P;\n url: string;\n };\n\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(\n userId\n )}`;\n\n // Helper for sending (uses the current ws instance)\n function send(type: T, to: string, payload: P) {\n if (!ws) return false;\n if (exited || ws.readyState !== WebSocket.OPEN) return false;\n const obj = { type, to, payload };\n ws.send(JSON.stringify(obj));\n logLine?.(\"👤 ➡️ 🖥️\", obj);\n return true;\n }\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 try {\n const result = JSON.parse(e.data);\n const msgs: Message[] = Array.isArray(result) ? result : [result];\n msgs.forEach((msg) => {\n logLine?.(\"🖥️ ➡️ 👤\", msg);\n if (msg.type === \"peer-joined\" || msg.type === \"peer-left\") {\n updatePeers(msg.users);\n } else if (msg.type === \"ice-server\") {\n params.onIceUrl?.(msg.url);\n } else if (msg.userId) {\n params.onMessage(msg.type, msg.payload, {\n userId: msg.userId,\n receive: (type: T, payload: P) => send(type, msg.userId, payload),\n });\n }\n });\n } catch {\n logLine?.(\"⚠️ ERROR\", { error: \"invalid-json\" });\n }\n };\n\n ws.onclose = (ev: CloseEvent) => {\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\", {\n attempt: retryCount + 1,\n delayMs: Math.round(delay),\n });\n\n retryCount++;\n timeoutId = setTimeout(connect, delay);\n } else {\n params.onClose?.({\n code: ev.code,\n reason: ev.reason,\n wasClean: ev.wasClean,\n });\n }\n };\n\n ws.onerror = (ev) => {\n console.error(\"WS Error\", ev);\n params.onError?.();\n };\n }\n\n // Helper for peer tracking (logic from your original code)\n function updatePeers(updatedUsers: { userId: string }[]) {\n const joined: IPeer<T, P>[] = [];\n const left: { userId: string }[] = [];\n const updatedPeerSet = new Set<string>();\n\n updatedUsers.forEach(({ userId: pUserId }) => {\n if (pUserId === userId) return;\n if (!peers.has(userId)) {\n const newPeer = {\n userId: pUserId,\n receive: (t: T, p: P) => send(t, pUserId, p),\n };\n peers.set(userId, newPeer);\n joined.push(newPeer);\n }\n updatedPeerSet.add(userId);\n });\n\n for (const userId of peers.keys()) {\n if (!updatedPeerSet.has(userId)) {\n peers.delete(userId);\n left.push({ 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 onIceUrl,\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 }[]) => void;\n onIceUrl?(url: 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(\n \"Warning: enterRoom called without workerUrl; this may cause issues in some environments. You should pass workerUrl explicitly. Use:\",\n CDN_WORKER_URL\n );\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 onIceUrl,\n onMessage,\n });\n }\n const worker = new Worker(workerUrl, { type: \"module\" });\n let exited = false;\n\n function makeUser({ userId }: { userId: string }): IPeer<T, P> {\n return {\n userId,\n receive: (type: T, payload: P) => {\n if (exited) return false;\n worker.postMessage({\n cmd: \"send\",\n toUserId: userId,\n host,\n room,\n type,\n payload,\n } 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 } else if (ev.kind === \"error\") onError?.();\n else if (ev.kind === \"peer-joined\")\n onPeerJoined(ev.users.map((ev) => makeUser({ userId: ev.userId })));\n else if (ev.kind === \"peer-left\") onPeerLeft(ev.users);\n else if (ev.kind === \"ice-server\") onIceUrl?.(ev.url);\n else if (ev.kind === \"message\")\n onMessage(ev.type, ev.payload, makeUser({ userId: ev.fromUserId }));\n else if (ev.kind === \"log\") logLine?.(ev.direction, ev.obj);\n };\n\n worker.addEventListener(\"message\", onWorkerMessage);\n\n worker.postMessage({\n cmd: \"enter\",\n userId,\n appId,\n room,\n host,\n autoRejoin,\n } 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 peer: IPeer<SigType, SigPayload>;\n\n expirationTimeout?: number;\n};\n\nconst DEFAULT_ENTER_ROOM = enterRoom;\n\nexport function collectPeerConnections({\n appId,\n receivePeerConnection,\n peerlessUserExpiration = 5000,\n fallbackRtcConfig = {\n iceServers: [{ urls: \"stun:stun.l.google.com:19302\" }],\n },\n enterRoomFunction: enterRoom = DEFAULT_ENTER_ROOM,\n logLine = console.debug,\n onLeaveUser,\n workerUrl,\n onRoomReady,\n onRoomClose,\n}: {\n appId: string;\n fallbackRtcConfig?: 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: {\n pc: RTCPeerConnection;\n userId: string;\n initiator: boolean;\n restart?: () => void;\n }): void;\n onRoomReady?(info: { host: string; room: string }): void;\n onRoomClose?(info: {\n host: string;\n room: string;\n ev: Pick<CloseEvent, \"reason\" | \"code\" | \"wasClean\">;\n }): void;\n}) {\n const userId = `user-${crypto.randomUUID()}`;\n const users: Map<string, UserState> = new Map();\n let iceUrl: string | undefined = undefined;\n let rtcConfig: (RTCConfiguration & { timestamp: number }) | undefined;\n\n async function getRtcConfig(): Promise<RTCConfiguration> {\n if (iceUrl) {\n try {\n const r = await fetch(iceUrl);\n if (!r.ok) throw new Error(`ICE endpoint failed: ${r.status}`);\n rtcConfig = (await r.json()) as RTCConfiguration & {\n timestamp: number;\n };\n } catch (e) {\n console.warn(\"Using fallback rtcConfig:\", e);\n }\n }\n return fallbackRtcConfig;\n }\n\n async function setupPC(state: UserState) {\n state.pc = new RTCPeerConnection(\n Date.now() - (rtcConfig?.timestamp ?? 0) < 10000\n ? rtcConfig\n : await getRtcConfig()\n );\n // Send local ICE candidates to this peer\n state.pc.onicecandidate = (ev) => {\n if (!ev.candidate) return;\n state.peer.receive(\"ice\", ev.candidate.toJSON());\n };\n\n state.pc.onconnectionstatechange = () => {\n logLine(\"💬\", {\n event: \"pc-state\",\n userId: state.userId,\n state: state.pc?.connectionState,\n });\n };\n return state.pc;\n }\n\n async function getPeer(\n peer: IPeer<SigType, SigPayload>\n ): Promise<[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 pendingRemoteIce: [],\n peer,\n };\n users.set(peer.userId, newState);\n\n await setupPC(newState);\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 }\n if (!state.pc) {\n await setupPC(state);\n }\n state.peer = peer;\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 {\n p.pc?.close();\n } 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\", {\n error: \"add-ice-failed\",\n userId: state.userId,\n detail: String(e),\n });\n }\n }\n }\n\n const roomsEntered = new Map<\n string,\n { room: string; host: string; exitRoom: () => void }\n >();\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>(async (resolve, reject) => {\n async function makeOffer(user: IPeer) {\n // Offer flow: createOffer -> setLocalDescription -> send localDescription\n const [state] = await 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\n onPeerJoined(joiningUsers: IPeer<SigType, SigPayload>[]) {\n joiningUsers.forEach(async (user) => {\n const [state, isNewPeer] = await getPeer(user);\n if (!isNewPeer) return;\n const pc = state.pc;\n if (!pc) return;\n\n async function restart() {\n const state = users.get(user.userId);\n if (state) {\n state.pc = undefined;\n const pc = await setupPC(state);\n receivePeerConnection({\n pc,\n userId: user.userId,\n initiator: true,\n restart,\n });\n await new Promise((resolve) => setTimeout(resolve, 3000));\n makeOffer(user);\n }\n }\n\n receivePeerConnection({\n pc,\n userId: user.userId,\n initiator: true,\n restart,\n });\n makeOffer(user);\n });\n },\n\n onPeerLeft(leavingUsers: { userId: string }[]) {\n leavingUsers.forEach(({ userId }) => {\n const state = users.get(userId);\n if (!state) return;\n state.expirationTimeout = setTimeout(\n () => leaveUser(userId),\n peerlessUserExpiration ?? 0\n );\n });\n },\n\n onIceUrl(url) {\n iceUrl = url;\n },\n\n async onMessage(type: SigType, payload: any, from: IPeer) {\n const [state] = await getPeer(from);\n const pc = state.pc;\n if (!pc) return;\n\n if (type === \"offer\") {\n receivePeerConnection({\n pc,\n userId: from.userId,\n initiator: false,\n restart() {\n // reset PC\n state.pc = undefined;\n },\n });\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\", {\n error: \"add-ice-failed\",\n userId: state.userId,\n detail: String(e),\n });\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/*\nTurn Token ID\n<CF_TURN_TOKEN_ID>\n\nAPI Token\n<CF_RTC_API_TOKEN>\n\nCURL\ncurl \\\n\t-H \"Authorization: Bearer <CF_RTC_API_TOKEN>\" \\\n\t-H \"Content-Type: application/json\" -d '{\"ttl\": 86400}' \\\n\thttps://rtc.live.cloudflare.com/v1/turn/keys/<CF_TURN_TOKEN_ID>/credentials/generate-ice-servers\n\nJSON\n{\n\t\"iceServers\": [\n {\n \"urls\": [\n \"stun:stun.cloudflare.com:3478\",\n \"turn:turn.cloudflare.com:3478?transport=udp\",\n \"turn:turn.cloudflare.com:3478?transport=tcp\",\n \"turns:turn.cloudflare.com:5349?transport=tcp\"\n ],\n \"username\": \"xxxx\",\n \"credential\": \"yyyy\",\n }\n ]\n}\n\n*/\n",
|
|
8
|
-
"import { EnterRoom, enterRoom } from \"./signal-room\";\nimport {\n SigType,\n SigPayload,\n collectPeerConnections,\n} from \"./webrtc-peer-collector\";\n\ntype UserListener = (\n user: string,\n action: \"join\" | \"leave\",\n users: string[]\n) => void;\n\nexport function enterWorld<D extends string | Uint8Array>({\n appId,\n logLine = console.debug,\n enterRoomFunction = enterRoom,\n peerlessUserExpiration,\n 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: {\n host: string;\n room: string;\n ev: Pick<CloseEvent, \"reason\" | \"code\" | \"wasClean\">;\n }): void;\n dataChannelOptions?: RTCDataChannelInit;\n}) {\n const userIds: string[] = [];\n\n const messagesListeners = new Set<(data: any, from: string) => void>();\n\n function createDataChannel(\n pc: RTCPeerConnection,\n peerUserId: string,\n initiator: boolean,\n restart?: () => void\n ) {\n if (initiator) {\n const dc = pc.createDataChannel(\"data\", dataChannelOptions);\n wireDataChannel(peerUserId, dc, restart);\n dataChannels.set(peerUserId, dc);\n } else {\n function listener(ev: RTCDataChannelEvent) {\n const dc = ev.channel;\n wireDataChannel(peerUserId, dc, restart);\n dataChannels.set(peerUserId, dc);\n
|
|
8
|
+
"import { EnterRoom, enterRoom } from \"./signal-room\";\nimport {\n SigType,\n SigPayload,\n collectPeerConnections,\n} from \"./webrtc-peer-collector\";\n\ntype UserListener = (\n user: string,\n action: \"join\" | \"leave\",\n users: string[]\n) => void;\n\nexport function enterWorld<D extends string | Uint8Array>({\n appId,\n logLine = console.debug,\n enterRoomFunction = enterRoom,\n peerlessUserExpiration,\n 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: {\n host: string;\n room: string;\n ev: Pick<CloseEvent, \"reason\" | \"code\" | \"wasClean\">;\n }): void;\n dataChannelOptions?: RTCDataChannelInit;\n}) {\n const userIds: string[] = [];\n\n const messagesListeners = new Set<(data: any, from: string) => void>();\n\n function createDataChannel(\n pc: RTCPeerConnection,\n peerUserId: string,\n initiator: boolean,\n restart?: () => void\n ) {\n if (initiator) {\n const dc = pc.createDataChannel(\"data\", dataChannelOptions);\n wireDataChannel(peerUserId, dc, restart);\n dataChannels.set(peerUserId, dc);\n } else {\n function listener(ev: RTCDataChannelEvent) {\n const dc = ev.channel;\n wireDataChannel(peerUserId, dc, restart);\n dataChannels.set(peerUserId, dc);\n }\n pc.addEventListener(\"datachannel\", listener);\n return () => {\n pc.removeEventListener(\"datachannel\", listener);\n };\n }\n }\n\n function wireDataChannel(\n userId: string,\n dc: RTCDataChannel,\n restart?: () => void\n ) {\n dc.onopen = () => {\n logLine(\"💬\", { event: \"dc-open\", userId });\n userIds.push(userId);\n userListeners.forEach((listener) => listener(userId, \"join\", userIds));\n };\n const onmessage = ({ data }: MessageEvent) => {\n messagesListeners.forEach((listener) => listener(data as any, userId));\n logLine(\"💬\", { event: \"dc-message\", userId, data });\n };\n dc.addEventListener(\"message\", onmessage);\n dc.addEventListener(\"close\", () => {\n logLine(\"💬\", { event: \"dc-close\", userId });\n userIds.splice(userIds.indexOf(userId), 1);\n userListeners.forEach((listener) => listener(userId, \"leave\", userIds));\n dc.removeEventListener(\"message\", onmessage);\n restart?.();\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 {\n userId,\n enterRoom,\n exitRoom,\n leaveUser,\n end: endPeerCollection,\n } = collectPeerConnections({\n appId,\n enterRoomFunction,\n logLine,\n workerUrl,\n peerlessUserExpiration,\n onRoomReady,\n onRoomClose,\n onLeaveUser(userId: string) {\n const dc = dataChannels.get(userId);\n try {\n dc?.close();\n } catch {}\n dataChannels.delete(userId);\n },\n receivePeerConnection({ pc, userId, initiator, restart }) {\n createDataChannel(pc, userId, initiator, restart);\n },\n });\n\n function send(data: D, userId?: string) {\n dataChannels.forEach((dataChannel, pUserId) => {\n if (userId && pUserId !== userId) return;\n if (dataChannel.readyState === \"open\") {\n dataChannel.send(data as any);\n }\n });\n }\n\n function removeMessageListener(listener: (data: D, from: string) => void) {\n messagesListeners.delete(listener);\n }\n\n function addMessageListener(listener: (data: D, 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 {\n dataChannel.close();\n } catch {}\n });\n dataChannels.clear();\n endPeerCollection();\n userListeners.clear();\n userIds.length = 0;\n },\n };\n}\n"
|
|
9
9
|
],
|
|
10
|
-
"mappings": "AAQO,SAAS,CAAoC,CAAC,EAcxB,CAS3B,IAAQ,SAAQ,QAAO,OAAM,OAAM,aAAa,GAAM,WAAY,EAE9D,EAAS,GACT,EAAa,EACb,EACA,EACA,EAAoB,GAElB,EAAQ,IAAI,IACZ,EAAQ,SAAS,UAAa,KAAS,YAAe,mBAC1D,CACF,IAGA,SAAS,CAAI,CAAC,EAAS,EAAY,EAAY,CAC7C,GAAI,CAAC,EAAI,MAAO,GAChB,GAAI,GAAU,EAAG,aAAe,UAAU,KAAM,MAAO,GACvD,IAAM,EAAM,CAAE,OAAM,KAAI,SAAQ,EAGhC,OAFA,EAAG,KAAK,KAAK,UAAU,CAAG,CAAC,EAC3B,IAAU,gCAAY,CAAG,EAClB,GAGT,SAAS,CAAO,EAAG,CACjB,GAAI,EAAQ,OAEZ,EAAK,IAAI,UAAU,CAAK,EAExB,EAAG,OAAS,IAAM,CAChB,GAAI,EACF,EAAO,SAAS,EAChB,EAAoB,GAEtB,EAAa,GAGf,EAAG,UAAY,CAAC,IAAoB,CAClC,GAAI,CACF,IAAM,EAAS,KAAK,MAAM,EAAE,IAAI,GACR,MAAM,QAAQ,CAAM,EAAI,EAAS,CAAC,CAAM,GAC3D,QAAQ,CAAC,IAAQ,CAEpB,GADA,IAAU,gCAAY,CAAG,EACrB,EAAI,OAAS,eAAiB,EAAI,OAAS,YAC7C,EAAY,EAAI,KAAK,EAChB,QAAI,EAAI,OAAS,aACtB,EAAO,WAAW,EAAI,GAAG,EACpB,QAAI,EAAI,OACb,EAAO,UAAU,EAAI,KAAM,EAAI,QAAS,CACtC,OAAQ,EAAI,OACZ,QAAS,CAAC,EAAS,IAAe,EAAK,EAAM,EAAI,OAAQ,CAAO,CAClE,CAAC,EAEJ,EACD,KAAM,CACN,IAAU,WAAW,CAAE,MAAO,cAAe,CAAC,IAIlD,EAAG,QAAU,CAAC,IAAmB,CAG/B,IAAM,EADmB,CAAC,KAAM,KAAM,KAAM,KAAM,IAAI,EACf,SAAS,EAAG,IAAI,EAEvD,GAAI,GAAc,CAAC,GAAU,EAAe,CAE1C,IAAM,EAAU,KAAK,IAAI,KAAK,IAAI,EAAG,CAAU,EAAI,KAAM,KAAK,EAExD,EAAS,KAAK,OAAO,EAAI,KACzB,EAAQ,EAAU,EAExB,IAAU,4BAAkB,CAC1B,QAAS,EAAa,EACtB,QAAS,KAAK,MAAM,CAAK,CAC3B,CAAC,EAED,IACA,EAAY,WAAW,EAAS,CAAK,EAErC,OAAO,UAAU,CACf,KAAM,EAAG,KACT,OAAQ,EAAG,OACX,SAAU,EAAG,QACf,CAAC,GAIL,EAAG,QAAU,CAAC,IAAO,CACnB,QAAQ,MAAM,WAAY,CAAE,EAC5B,EAAO,UAAU,GAKrB,SAAS,CAAW,CAAC,EAAoC,CACvD,IAAM,EAAwB,CAAC,EACzB,EAA6B,CAAC,EAC9B,EAAiB,IAAI,IAE3B,EAAa,QAAQ,EAAG,OAAQ,KAAc,CAC5C,GAAI,IAAY,EAAQ,OACxB,GAAI,CAAC,EAAM,IAAI,CAAM,EAAG,CACtB,IAAM,EAAU,CACd,OAAQ,EACR,QAAS,CAAC,EAAM,IAAS,EAAK,EAAG,EAAS,CAAC,CAC7C,EACA,EAAM,IAAI,EAAQ,CAAO,EACzB,EAAO,KAAK,CAAO,EAErB,EAAe,IAAI,CAAM,EAC1B,EAED,QAAW,KAAU,EAAM,KAAK,EAC9B,GAAI,CAAC,EAAe,IAAI,CAAM,EAC5B,EAAM,OAAO,CAAM,EACnB,EAAK,KAAK,CAAE,QAAO,CAAC,EAIxB,GAAI,EAAO,OAAQ,EAAO,aAAa,CAAM,EAC7C,GAAI,EAAK,OAAQ,EAAO,WAAW,CAAI,EAMzC,OAFA,EAAQ,EAED,CACL,SAAU,IAAM,CACd,EAAS,GACT,aAAa,CAAS,EACtB,EAAG,MAAM,EAEb,EC9JK,SAAS,CAAoC,EAClD,SACA,QACA,OACA,OACA,aAAa,GACb,SACA,UACA,UACA,eACA,aACA,WACA,YACA,UACA,aAkB2B,CAC3B,GAAI,CAAC,EAOH,OAJA,QAAQ,KACN,sIAHqB,kFAKvB,EACO,EAAoB,CACzB,SACA,QACA,OACA,OACA,aACA,SACA,UACA,UACA,eACA,aACA,WACA,WACF,CAAC,EAEH,IAAM,EAAS,IAAI,OAAO,EAAW,CAAE,KAAM,QAAS,CAAC,EACnD,EAAS,GAEb,SAAS,CAAQ,EAAG,UAA2C,CAC7D,MAAO,CACL,SACA,QAAS,CAAC,EAAS,IAAe,CAChC,GAAI,EAAQ,MAAO,GASnB,OARA,EAAO,YAAY,CACjB,IAAK,OACL,SAAU,EACV,OACA,OACA,OACA,SACF,CAAkB,EACX,GAEX,EAGF,IAAM,EAAkB,CAAC,IAAqC,CAC5D,IAAM,EAAK,EAAE,KAEb,GAAI,EAAG,OAAS,OAAQ,IAAS,EAC5B,QAAI,EAAG,OAAS,QACnB,EAAO,UAAU,EACjB,IAAU,EAAG,EAAE,EACV,QAAI,EAAG,OAAS,QAAS,IAAU,EACrC,QAAI,EAAG,OAAS,cACnB,EAAa,EAAG,MAAM,IAAI,CAAC,IAAO,EAAS,CAAE,OAAQ,EAAG,MAAO,CAAC,CAAC,CAAC,EAC/D,QAAI,EAAG,OAAS,YAAa,EAAW,EAAG,KAAK,EAChD,QAAI,EAAG,OAAS,aAAc,IAAW,EAAG,GAAG,EAC/C,QAAI,EAAG,OAAS,UACnB,EAAU,EAAG,KAAM,EAAG,QAAS,EAAS,CAAE,OAAQ,EAAG,UAAW,CAAC,CAAC,EAC/D,QAAI,EAAG,OAAS,MAAO,IAAU,EAAG,UAAW,EAAG,GAAG,GAc5D,OAXA,EAAO,iBAAiB,UAAW,CAAe,EAElD,EAAO,YAAY,CACjB,IAAK,QACL,SACA,QACA,OACA,OACA,YACF,CAAkB,EAEX,CACL,SAAU,IAAM,CACd,EAAS,GACT,EAAO,oBAAoB,UAAW,CAAe,EACrD,EAAO,YAAY,CAAE,IAAK,MAAO,CAAkB,EAEvD,EC/FF,IAAM,EAAqB,EAEpB,SAAS,CAAsB,EACpC,QACA,wBACA,yBAAyB,KACzB,oBAAoB,CAClB,WAAY,CAAC,CAAE,KAAM,8BAA+B,CAAC,CACvD,EACA,kBAAmB,EAAY,EAC/B,UAAU,QAAQ,MAClB,cACA,YACA,cACA,eAqBC,CACD,IAAM,EAAS,QAAQ,OAAO,WAAW,IACnC,EAAgC,IAAI,IACtC,EAA6B,OAC7B,EAEJ,eAAe,CAAY,EAA8B,CACvD,GAAI,EACF,GAAI,CACF,IAAM,EAAI,MAAM,MAAM,CAAM,EAC5B,GAAI,CAAC,EAAE,GAAI,MAAU,MAAM,wBAAwB,EAAE,QAAQ,EAC7D,EAAa,MAAM,EAAE,KAAK,EAG1B,MAAO,EAAG,CACV,QAAQ,KAAK,4BAA6B,CAAC,EAG/C,OAAO,EAGT,eAAe,CAAO,CAAC,EAAkB,CAmBvC,OAlBA,EAAM,GAAK,IAAI,kBACb,KAAK,IAAI,GAAK,GAAW,WAAa,GAAK,IACvC,EACA,MAAM,EAAa,CACzB,EAEA,EAAM,GAAG,eAAiB,CAAC,IAAO,CAChC,GAAI,CAAC,EAAG,UAAW,OACnB,EAAM,KAAK,QAAQ,MAAO,EAAG,UAAU,OAAO,CAAC,GAGjD,EAAM,GAAG,wBAA0B,IAAM,CACvC,EAAQ,eAAK,CACX,MAAO,WACP,OAAQ,EAAM,OACd,MAAO,EAAM,IAAI,eACnB,CAAC,GAEI,EAAM,GAGf,eAAe,CAAO,CACpB,EAC+B,CAC/B,IAAI,EAAQ,EAAM,IAAI,EAAK,MAAM,EAC7B,EAAY,GAChB,GAAI,CAAC,EAAO,CACV,IAAM,EAAsB,CAC1B,OAAQ,EAAK,OACb,iBAAkB,CAAC,EACnB,MACF,EACA,EAAM,IAAI,EAAK,OAAQ,CAAQ,EAE/B,MAAM,EAAQ,CAAQ,EACtB,EAAQ,EAGR,EAAM,IAAI,EAAM,OAAQ,CAAK,EAC7B,EAAY,GACP,QAAI,EACT,aAAa,EAAM,iBAAiB,EACpC,EAAM,kBAAoB,EAE5B,GAAI,CAAC,EAAM,GACT,MAAM,EAAQ,CAAK,EAGrB,OADA,EAAM,KAAO,EACN,CAAC,EAAO,CAAS,EAG1B,SAAS,CAAS,CAAC,EAAgB,CACjC,IAAc,CAAM,EACpB,IAAM,EAAI,EAAM,IAAI,CAAM,EAC1B,GAAI,CAAC,EAAG,OACR,GAAI,CACF,EAAE,IAAI,MAAM,EACZ,KAAM,EACR,EAAM,OAAO,CAAM,EAGrB,eAAe,CAAc,CAAC,EAAkB,CAC9C,GAAI,CAAC,EAAM,IAAI,kBAAmB,OAElC,IAAM,EAAS,EAAM,iBACrB,EAAM,iBAAmB,CAAC,EAE1B,QAAW,KAAO,EAChB,GAAI,CACF,MAAM,EAAM,GAAG,gBAAgB,CAAG,EAClC,MAAO,EAAG,CACV,EAAQ,WAAW,CACjB,MAAO,iBACP,OAAQ,EAAM,OACd,OAAQ,OAAO,CAAC,CAClB,CAAC,GAKP,IAAM,EAAe,IAAI,IAKzB,SAAS,CAAI,EAAG,OAAM,QAAwC,CAC5D,IAAM,EAAM,GAAG,UAAa,IACtB,EAAU,EAAa,IAAI,CAAG,EACpC,GAAI,EACF,EAAQ,SAAS,EACjB,EAAa,OAAO,CAAG,EAI3B,SAAS,CAAK,EAAG,OAAM,QAAwC,CAC7D,OAAO,IAAI,QAAc,MAAO,EAAS,IAAW,CAClD,eAAe,CAAS,CAAC,EAAa,CAEpC,IAAO,GAAS,MAAM,EAAQ,CAAI,EAC5B,EAAK,EAAM,GACX,EAAQ,MAAM,GAAI,YAAY,EACpC,MAAM,GAAI,oBAAoB,CAAK,EACnC,EAAK,QAAQ,QAAS,GAAI,kBAAkB,OAAO,CAAE,EAGvD,IAAQ,YAAa,EAAU,CAC7B,SACA,QACA,OACA,OACA,UACA,YACA,WAAY,GAEZ,MAAM,EAAG,CACP,IAAc,CAAE,OAAM,MAAK,CAAC,EAC5B,EAAQ,GAEV,OAAO,EAAG,CACR,QAAQ,MAAM,SAAS,EACvB,EAAO,GAET,OAAO,CAAC,EAAI,CACV,IAAc,CAAE,OAAM,OAAM,IAAG,CAAC,GAIlC,YAAY,CAAC,EAA4C,CACvD,EAAa,QAAQ,MAAO,IAAS,CACnC,IAAO,EAAO,GAAa,MAAM,EAAQ,CAAI,EAC7C,GAAI,CAAC,EAAW,OAChB,IAAM,EAAK,EAAM,GACjB,GAAI,CAAC,EAAI,OAET,eAAe,CAAO,EAAG,CACvB,IAAM,EAAQ,EAAM,IAAI,EAAK,MAAM,EACnC,GAAI,EAAO,CACT,EAAM,GAAK,OACX,IAAM,EAAK,MAAM,EAAQ,CAAK,EAC9B,EAAsB,CACpB,KACA,OAAQ,EAAK,OACb,UAAW,GACX,SACF,CAAC,EACD,MAAM,IAAI,QAAQ,CAAC,IAAY,WAAW,EAAS,IAAI,CAAC,EACxD,EAAU,CAAI,GAIlB,EAAsB,CACpB,KACA,OAAQ,EAAK,OACb,UAAW,GACX,SACF,CAAC,EACD,EAAU,CAAI,EACf,GAGH,UAAU,CAAC,EAAoC,CAC7C,EAAa,QAAQ,EAAG,YAAa,CACnC,IAAM,EAAQ,EAAM,IAAI,CAAM,EAC9B,GAAI,CAAC,EAAO,OACZ,EAAM,kBAAoB,WACxB,IAAM,EAAU,CAAM,EACtB,GAA0B,CAC5B,EACD,GAGH,QAAQ,CAAC,EAAK,CACZ,EAAS,QAGL,UAAS,CAAC,EAAe,EAAc,EAAa,CACxD,IAAO,GAAS,MAAM,EAAQ,CAAI,EAC5B,EAAK,EAAM,GACjB,GAAI,CAAC,EAAI,OAET,GAAI,IAAS,QAAS,CACpB,EAAsB,CACpB,KACA,OAAQ,EAAK,OACb,UAAW,GACX,OAAO,EAAG,CAER,EAAM,GAAK,OAEf,CAAC,EAED,MAAM,EAAG,qBAAqB,CAAoC,EAGlE,IAAM,EAAS,MAAM,EAAG,aAAa,EACrC,MAAM,EAAG,oBAAoB,CAAM,EAEnC,EAAK,QAAQ,SAAU,EAAG,kBAAkB,OAAO,CAAE,EAGrD,MAAM,EAAe,CAAK,EAC1B,OAGF,GAAI,IAAS,SAAU,CAErB,MAAM,EAAG,qBAAqB,CAAoC,EAClE,MAAM,EAAe,CAAK,EAC1B,OAGF,GAAI,IAAS,MAAO,CAClB,IAAM,EAAM,EAGZ,GAAI,CAAC,EAAG,kBAAmB,CACzB,EAAM,iBAAiB,KAAK,CAAG,EAC/B,OAGF,GAAI,CACF,MAAM,EAAG,gBAAgB,CAAG,EAC5B,MAAO,EAAG,CACV,EAAQ,WAAW,CACjB,MAAO,iBACP,OAAQ,EAAM,OACd,OAAQ,OAAO,CAAC,CAClB,CAAC,EAEH,QAGN,CAAC,EACD,EAAa,IAAI,GAAG,UAAa,IAAQ,CAAE,WAAU,OAAM,MAAK,CAAC,EAClE,EAGH,MAAO,CACL,SACA,UAAW,EACX,SAAU,EACV,YACA,GAAG,EAAG,CACJ,EAAa,QAAQ,EAAG,cAAe,EAAS,CAAC,EACjD,EAAa,MAAM,EACnB,EAAM,QAAQ,EAAG,YAAa,EAAU,CAAM,CAAC,EAC/C,EAAM,MAAM,EAEhB,ECvTK,SAAS,CAAyC,EACvD,QACA,UAAU,QAAQ,MAClB,oBAAoB,EACpB,yBACA,YACA,cACA,cACA,sBAcC,CACD,IAAM,EAAoB,CAAC,EAErB,EAAoB,IAAI,IAE9B,SAAS,CAAiB,CACxB,EACA,EACA,EACA,EACA,CACA,GAAI,EAAW,CACb,IAAM,EAAK,EAAG,kBAAkB,OAAQ,CAAkB,EAC1D,EAAgB,EAAY,EAAI,CAAO,EACvC,EAAa,IAAI,EAAY,CAAE,EAC1B,KACL,IAAS,EAAT,QAAiB,CAAC,EAAyB,CACzC,IAAM,EAAK,EAAG,QACd,EAAgB,EAAY,EAAI,CAAO,EACvC,EAAa,IAAI,EAAY,CAAE,
|
|
11
|
-
"debugId": "
|
|
10
|
+
"mappings": "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",
|
|
11
|
+
"debugId": "609FE715C165393064756E2164756E21",
|
|
12
12
|
"names": []
|
|
13
13
|
}
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
function w(H){let{userId:q,appId:_,room:
|
|
1
|
+
function w(H){let{userId:q,appId:_,room:j,host:n,autoRejoin:h=!0,logLine:T}=H,x=!1,E=0,z,N,B=!0,S=new Map,F=`wss://${n}/room/${_}/${j}?userId=${encodeURIComponent(q)}`;function K(Z,$,Q){if(!z)return!1;if(x||z.readyState!==WebSocket.OPEN)return!1;let W={type:Z,to:$,payload:Q};return z.send(JSON.stringify(W)),T?.("\uD83D\uDC64 ➡️ \uD83D\uDDA5️",W),!0}function L(){if(x)return;z=new WebSocket(F),z.onopen=()=>{if(B)H.onOpen?.(),B=!1;E=0},z.onmessage=(Z)=>{try{let $=JSON.parse(Z.data);(Array.isArray($)?$:[$]).forEach((W)=>{if(T?.("\uD83D\uDDA5️ ➡️ \uD83D\uDC64",W),W.type==="peer-joined"||W.type==="peer-left")R(W.users);else if(W.type==="ice-server")H.onIceUrl?.(W.url);else if(W.userId)H.onMessage(W.type,W.payload,{userId:W.userId,receive:(M,D)=>K(M,W.userId,D)})})}catch{T?.("⚠️ ERROR",{error:"invalid-json"})}},z.onclose=(Z)=>{let Q=[1001,1006,1011,1012,1013].includes(Z.code);if(h&&!x&&Q){let W=Math.min(Math.pow(2,E)*1000,30000),M=Math.random()*1000,D=W+M;T?.("\uD83D\uDD04 RECONNECTING",{attempt:E+1,delayMs:Math.round(D)}),E++,N=setTimeout(L,D)}else H.onClose?.({code:Z.code,reason:Z.reason,wasClean:Z.wasClean})},z.onerror=(Z)=>{console.error("WS Error",Z),H.onError?.()}}function R(Z){let $=[],Q=[],W=new Set;Z.forEach(({userId:M})=>{if(M===q)return;if(!S.has(q)){let D={userId:M,receive:(V,G)=>K(V,M,G)};S.set(q,D),$.push(D)}W.add(q)});for(let M of S.keys())if(!W.has(M))S.delete(M),Q.push({userId:M});if($.length)H.onPeerJoined($);if(Q.length)H.onPeerLeft(Q)}return L(),{exitRoom:()=>{x=!0,clearTimeout(N),z.close()}}}function k({userId:H,appId:q,room:_,host:j,autoRejoin:n=!0,onOpen:h,onClose:T,onError:x,onPeerJoined:E,onPeerLeft:z,onIceUrl:N,onMessage:B,logLine:S,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"),w({userId:H,appId:q,room:_,host:j,autoRejoin:n,onOpen:h,onClose:T,onError:x,onPeerJoined:E,onPeerLeft:z,onIceUrl:N,onMessage:B});let K=new Worker(F,{type:"module"}),L=!1;function R({userId:$}){return{userId:$,receive:(Q,W)=>{if(L)return!1;return K.postMessage({cmd:"send",toUserId:$,host:j,room:_,type:Q,payload:W}),!0}}}let Z=($)=>{let Q=$.data;if(Q.kind==="open")h?.();else if(Q.kind==="close")K.terminate(),T?.(Q.ev);else if(Q.kind==="error")x?.();else if(Q.kind==="peer-joined")E(Q.users.map((W)=>R({userId:W.userId})));else if(Q.kind==="peer-left")z(Q.users);else if(Q.kind==="ice-server")N?.(Q.url);else if(Q.kind==="message")B(Q.type,Q.payload,R({userId:Q.fromUserId}));else if(Q.kind==="log")S?.(Q.direction,Q.obj)};return K.addEventListener("message",Z),K.postMessage({cmd:"enter",userId:H,appId:q,room:_,host:j,autoRejoin:n}),{exitRoom:()=>{L=!0,K.removeEventListener("message",Z),K.postMessage({cmd:"exit"})}}}var g=k;function y({appId:H,receivePeerConnection:q,peerlessUserExpiration:_=5000,fallbackRtcConfig:j={iceServers:[{urls:"stun:stun.l.google.com:19302"}]},enterRoomFunction:n=g,logLine:h=console.debug,onLeaveUser:T,workerUrl:x,onRoomReady:E,onRoomClose:z}){let N=`user-${crypto.randomUUID()}`,B=new Map,S=void 0,F;async function K(){if(S)try{let D=await fetch(S);if(!D.ok)throw Error(`ICE endpoint failed: ${D.status}`);F=await D.json()}catch(D){console.warn("Using fallback rtcConfig:",D)}return j}async function L(D){return D.pc=new RTCPeerConnection(Date.now()-(F?.timestamp??0)<1e4?F:await K()),D.pc.onicecandidate=(V)=>{if(!V.candidate)return;D.peer.receive("ice",V.candidate.toJSON())},D.pc.onconnectionstatechange=()=>{h("\uD83D\uDCAC",{event:"pc-state",userId:D.userId,state:D.pc?.connectionState})},D.pc}async function R(D){let V=B.get(D.userId),G=!1;if(!V){let X={userId:D.userId,pendingRemoteIce:[],peer:D};B.set(D.userId,X),await L(X),V=X,B.set(V.userId,V),G=!0}else if(V)clearTimeout(V.expirationTimeout),V.expirationTimeout=0;if(!V.pc)await L(V);return V.peer=D,[V,G]}function Z(D){T?.(D);let V=B.get(D);if(!V)return;try{V.pc?.close()}catch{}B.delete(D)}async function $(D){if(!D.pc?.remoteDescription)return;let V=D.pendingRemoteIce;D.pendingRemoteIce=[];for(let G of V)try{await D.pc.addIceCandidate(G)}catch(X){h("⚠️ ERROR",{error:"add-ice-failed",userId:D.userId,detail:String(X)})}}let Q=new Map;function W({room:D,host:V}){let G=`${V}/room/${D}`,X=Q.get(G);if(X)X.exitRoom(),Q.delete(G)}function M({room:D,host:V}){return new Promise(async(G,X)=>{async function f(Y){let[b]=await R(Y),A=b.pc,C=await A?.createOffer();await A?.setLocalDescription(C),Y.receive("offer",A?.localDescription?.toJSON())}let{exitRoom:O}=n({userId:N,appId:H,room:D,host:V,logLine:h,workerUrl:x,autoRejoin:!0,onOpen(){E?.({room:D,host:V}),G()},onError(){console.error("onError"),X()},onClose(Y){z?.({room:D,host:V,ev:Y})},onPeerJoined(Y){Y.forEach(async(b)=>{let[A,C]=await R(b);if(!C)return;let J=A.pc;if(!J)return;async function c(){let P=B.get(b.userId);if(P){P.pc=void 0;let v=await L(P);q({pc:v,userId:b.userId,initiator:!0,restart:c}),await new Promise((U)=>setTimeout(U,3000)),f(b)}}q({pc:J,userId:b.userId,initiator:!0,restart:c}),f(b)})},onPeerLeft(Y){Y.forEach(({userId:b})=>{let A=B.get(b);if(!A)return;A.expirationTimeout=setTimeout(()=>Z(b),_??0)})},onIceUrl(Y){S=Y},async onMessage(Y,b,A){let[C]=await R(A),J=C.pc;if(!J)return;if(Y==="offer"){q({pc:J,userId:A.userId,initiator:!1,restart(){C.pc=void 0}}),await J.setRemoteDescription(b);let c=await J.createAnswer();await J.setLocalDescription(c),A.receive("answer",J.localDescription?.toJSON()),await $(C);return}if(Y==="answer"){await J.setRemoteDescription(b),await $(C);return}if(Y==="ice"){let c=b;if(!J.remoteDescription){C.pendingRemoteIce.push(c);return}try{await J.addIceCandidate(c)}catch(P){h("⚠️ ERROR",{error:"add-ice-failed",userId:C.userId,detail:String(P)})}return}}});Q.set(`${V}/room/${D}`,{exitRoom:O,room:D,host:V})})}return{userId:N,enterRoom:M,exitRoom:W,leaveUser:Z,end(){Q.forEach(({exitRoom:D})=>D()),Q.clear(),B.forEach(({userId:D})=>Z(D)),B.clear()}}}function i({appId:H,logLine:q=console.debug,enterRoomFunction:_=k,peerlessUserExpiration:j,workerUrl:n,onRoomReady:h,onRoomClose:T,dataChannelOptions:x}){let E=[],z=new Set;function N(G,X,f,O){if(f){let Y=G.createDataChannel("data",x);B(X,Y,O),S.set(X,Y)}else{let Y=function(b){let A=b.channel;B(X,A,O),S.set(X,A)};return G.addEventListener("datachannel",Y),()=>{G.removeEventListener("datachannel",Y)}}}function B(G,X,f){X.onopen=()=>{q("\uD83D\uDCAC",{event:"dc-open",userId:G}),E.push(G),F.forEach((Y)=>Y(G,"join",E))};let O=({data:Y})=>{z.forEach((b)=>b(Y,G)),q("\uD83D\uDCAC",{event:"dc-message",userId:G,data:Y})};X.addEventListener("message",O),X.addEventListener("close",()=>{q("\uD83D\uDCAC",{event:"dc-close",userId:G}),E.splice(E.indexOf(G),1),F.forEach((Y)=>Y(G,"leave",E)),X.removeEventListener("message",O),f?.()}),X.onerror=()=>q("⚠️ ERROR",{error:"dc-error",userId:G})}let S=new Map,F=new Set,{userId:K,enterRoom:L,exitRoom:R,leaveUser:Z,end:$}=y({appId:H,enterRoomFunction:_,logLine:q,workerUrl:n,peerlessUserExpiration:j,onRoomReady:h,onRoomClose:T,onLeaveUser(G){let X=S.get(G);try{X?.close()}catch{}S.delete(G)},receivePeerConnection({pc:G,userId:X,initiator:f,restart:O}){N(G,X,f,O)}});function Q(G,X){S.forEach((f,O)=>{if(X&&O!==X)return;if(f.readyState==="open")f.send(G)})}function W(G){z.delete(G)}function M(G){return z.add(G),()=>{W(G)}}function D(G){F.delete(G)}function V(G){return F.add(G),()=>{D(G)}}return{userId:K,send:Q,enterRoom:L,exitRoom:R,leaveUser:Z,getUsers:()=>E,addMessageListener:M,removeMessageListener:W,addUserListener:V,removeUserListener:D,end(){S.forEach((G)=>{try{G.close()}catch{}}),S.clear(),$(),F.clear(),E.length=0}}}export{i as enterWorld,w as enterRoom,y as collectPeerConnections};
|
|
2
2
|
|
|
3
|
-
//# debugId=
|
|
3
|
+
//# debugId=0CDE40A88CD9235564756E2164756E21
|
|
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 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;\n appId: string;\n room: string;\n 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 }[]): void;\n onIceUrl?(url: string): void;\n onMessage(type: T, payload: P, from: IPeer<T, P>): void;\n autoRejoin?: boolean;\n}): { exitRoom: () => void } {\n type Message = {\n type: \"peer-joined\" | \"peer-left\" | \"ice-server\" | T;\n userId: string;\n users: { userId: string }[];\n payload: P;\n url: string;\n };\n\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(\n userId\n )}`;\n\n // Helper for sending (uses the current ws instance)\n function send(type: T, to: string, payload: P) {\n if (!ws) return false;\n if (exited || ws.readyState !== WebSocket.OPEN) return false;\n const obj = { type, to, payload };\n ws.send(JSON.stringify(obj));\n logLine?.(\"👤 ➡️ 🖥️\", obj);\n return true;\n }\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 try {\n const result = JSON.parse(e.data);\n const msgs: Message[] = Array.isArray(result) ? result : [result];\n msgs.forEach((msg) => {\n logLine?.(\"🖥️ ➡️ 👤\", msg);\n if (msg.type === \"peer-joined\" || msg.type === \"peer-left\") {\n updatePeers(msg.users);\n } else if (msg.type === \"ice-server\") {\n params.onIceUrl?.(msg.url);\n } else if (msg.userId) {\n params.onMessage(msg.type, msg.payload, {\n userId: msg.userId,\n receive: (type: T, payload: P) => send(type, msg.userId, payload),\n });\n }\n });\n } catch {\n logLine?.(\"⚠️ ERROR\", { error: \"invalid-json\" });\n }\n };\n\n ws.onclose = (ev: CloseEvent) => {\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\", {\n attempt: retryCount + 1,\n delayMs: Math.round(delay),\n });\n\n retryCount++;\n timeoutId = setTimeout(connect, delay);\n } else {\n params.onClose?.({\n code: ev.code,\n reason: ev.reason,\n wasClean: ev.wasClean,\n });\n }\n };\n\n ws.onerror = (ev) => {\n console.error(\"WS Error\", ev);\n params.onError?.();\n };\n }\n\n // Helper for peer tracking (logic from your original code)\n function updatePeers(updatedUsers: { userId: string }[]) {\n const joined: IPeer<T, P>[] = [];\n const left: { userId: string }[] = [];\n const updatedPeerSet = new Set<string>();\n\n updatedUsers.forEach(({ userId: pUserId }) => {\n if (pUserId === userId) return;\n if (!peers.has(userId)) {\n const newPeer = {\n userId: pUserId,\n receive: (t: T, p: P) => send(t, pUserId, p),\n };\n peers.set(userId, newPeer);\n joined.push(newPeer);\n }\n updatedPeerSet.add(userId);\n });\n\n for (const userId of peers.keys()) {\n if (!updatedPeerSet.has(userId)) {\n peers.delete(userId);\n left.push({ 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 onIceUrl,\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 }[]) => void;\n onIceUrl?(url: 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(\n \"Warning: enterRoom called without workerUrl; this may cause issues in some environments. You should pass workerUrl explicitly. Use:\",\n CDN_WORKER_URL\n );\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 onIceUrl,\n onMessage,\n });\n }\n const worker = new Worker(workerUrl, { type: \"module\" });\n let exited = false;\n\n function makeUser({ userId }: { userId: string }): IPeer<T, P> {\n return {\n userId,\n receive: (type: T, payload: P) => {\n if (exited) return false;\n worker.postMessage({\n cmd: \"send\",\n toUserId: userId,\n host,\n room,\n type,\n payload,\n } 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 } else if (ev.kind === \"error\") onError?.();\n else if (ev.kind === \"peer-joined\")\n onPeerJoined(ev.users.map((ev) => makeUser({ userId: ev.userId })));\n else if (ev.kind === \"peer-left\") onPeerLeft(ev.users);\n else if (ev.kind === \"ice-server\") onIceUrl?.(ev.url);\n else if (ev.kind === \"message\")\n onMessage(ev.type, ev.payload, makeUser({ userId: ev.fromUserId }));\n else if (ev.kind === \"log\") logLine?.(ev.direction, ev.obj);\n };\n\n worker.addEventListener(\"message\", onWorkerMessage);\n\n worker.postMessage({\n cmd: \"enter\",\n userId,\n appId,\n room,\n host,\n autoRejoin,\n } 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 peer: IPeer<SigType, SigPayload>;\n\n expirationTimeout?: number;\n};\n\nconst DEFAULT_ENTER_ROOM = enterRoom;\n\nexport function collectPeerConnections({\n appId,\n receivePeerConnection,\n peerlessUserExpiration = 5000,\n fallbackRtcConfig = {\n iceServers: [{ urls: \"stun:stun.l.google.com:19302\" }],\n },\n enterRoomFunction: enterRoom = DEFAULT_ENTER_ROOM,\n logLine = console.debug,\n onLeaveUser,\n workerUrl,\n onRoomReady,\n onRoomClose,\n}: {\n appId: string;\n fallbackRtcConfig?: 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: {\n pc: RTCPeerConnection;\n userId: string;\n initiator: boolean;\n restart?: () => void;\n }): void;\n onRoomReady?(info: { host: string; room: string }): void;\n onRoomClose?(info: {\n host: string;\n room: string;\n ev: Pick<CloseEvent, \"reason\" | \"code\" | \"wasClean\">;\n }): void;\n}) {\n const userId = `user-${crypto.randomUUID()}`;\n const users: Map<string, UserState> = new Map();\n let iceUrl: string | undefined = undefined;\n let rtcConfig: (RTCConfiguration & { timestamp: number }) | undefined;\n\n async function getRtcConfig(): Promise<RTCConfiguration> {\n if (iceUrl) {\n try {\n const r = await fetch(iceUrl);\n if (!r.ok) throw new Error(`ICE endpoint failed: ${r.status}`);\n rtcConfig = (await r.json()) as RTCConfiguration & {\n timestamp: number;\n };\n } catch (e) {\n console.warn(\"Using fallback rtcConfig:\", e);\n }\n }\n return fallbackRtcConfig;\n }\n\n async function setupPC(state: UserState) {\n state.pc = new RTCPeerConnection(\n Date.now() - (rtcConfig?.timestamp ?? 0) < 10000\n ? rtcConfig\n : await getRtcConfig()\n );\n // Send local ICE candidates to this peer\n state.pc.onicecandidate = (ev) => {\n if (!ev.candidate) return;\n state.peer.receive(\"ice\", ev.candidate.toJSON());\n };\n\n state.pc.onconnectionstatechange = () => {\n logLine(\"💬\", {\n event: \"pc-state\",\n userId: state.userId,\n state: state.pc?.connectionState,\n });\n };\n return state.pc;\n }\n\n async function getPeer(\n peer: IPeer<SigType, SigPayload>\n ): Promise<[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 pendingRemoteIce: [],\n peer,\n };\n users.set(peer.userId, newState);\n\n await setupPC(newState);\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 }\n if (!state.pc) {\n await setupPC(state);\n }\n state.peer = peer;\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 {\n p.pc?.close();\n } 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\", {\n error: \"add-ice-failed\",\n userId: state.userId,\n detail: String(e),\n });\n }\n }\n }\n\n const roomsEntered = new Map<\n string,\n { room: string; host: string; exitRoom: () => void }\n >();\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>(async (resolve, reject) => {\n async function makeOffer(user: IPeer) {\n // Offer flow: createOffer -> setLocalDescription -> send localDescription\n const [state] = await 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\n onPeerJoined(joiningUsers: IPeer<SigType, SigPayload>[]) {\n joiningUsers.forEach(async (user) => {\n const [state, isNewPeer] = await getPeer(user);\n if (!isNewPeer) return;\n const pc = state.pc;\n if (!pc) return;\n\n async function restart() {\n const state = users.get(user.userId);\n if (state) {\n state.pc = undefined;\n const pc = await setupPC(state);\n receivePeerConnection({\n pc,\n userId: user.userId,\n initiator: true,\n restart,\n });\n await new Promise((resolve) => setTimeout(resolve, 3000));\n makeOffer(user);\n }\n }\n\n receivePeerConnection({\n pc,\n userId: user.userId,\n initiator: true,\n restart,\n });\n makeOffer(user);\n });\n },\n\n onPeerLeft(leavingUsers: { userId: string }[]) {\n leavingUsers.forEach(({ userId }) => {\n const state = users.get(userId);\n if (!state) return;\n state.expirationTimeout = setTimeout(\n () => leaveUser(userId),\n peerlessUserExpiration ?? 0\n );\n });\n },\n\n onIceUrl(url) {\n iceUrl = url;\n },\n\n async onMessage(type: SigType, payload: any, from: IPeer) {\n const [state] = await getPeer(from);\n const pc = state.pc;\n if (!pc) return;\n\n if (type === \"offer\") {\n receivePeerConnection({\n pc,\n userId: from.userId,\n initiator: false,\n restart() {\n // reset PC\n state.pc = undefined;\n },\n });\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\", {\n error: \"add-ice-failed\",\n userId: state.userId,\n detail: String(e),\n });\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/*\nTurn Token ID\n<CF_TURN_TOKEN_ID>\n\nAPI Token\n<CF_RTC_API_TOKEN>\n\nCURL\ncurl \\\n\t-H \"Authorization: Bearer <CF_RTC_API_TOKEN>\" \\\n\t-H \"Content-Type: application/json\" -d '{\"ttl\": 86400}' \\\n\thttps://rtc.live.cloudflare.com/v1/turn/keys/<CF_TURN_TOKEN_ID>/credentials/generate-ice-servers\n\nJSON\n{\n\t\"iceServers\": [\n {\n \"urls\": [\n \"stun:stun.cloudflare.com:3478\",\n \"turn:turn.cloudflare.com:3478?transport=udp\",\n \"turn:turn.cloudflare.com:3478?transport=tcp\",\n \"turns:turn.cloudflare.com:5349?transport=tcp\"\n ],\n \"username\": \"xxxx\",\n \"credential\": \"yyyy\",\n }\n ]\n}\n\n*/\n",
|
|
8
|
-
"import { EnterRoom, enterRoom } from \"./signal-room\";\nimport {\n SigType,\n SigPayload,\n collectPeerConnections,\n} from \"./webrtc-peer-collector\";\n\ntype UserListener = (\n user: string,\n action: \"join\" | \"leave\",\n users: string[]\n) => void;\n\nexport function enterWorld<D extends string | Uint8Array>({\n appId,\n logLine = console.debug,\n enterRoomFunction = enterRoom,\n peerlessUserExpiration,\n 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: {\n host: string;\n room: string;\n ev: Pick<CloseEvent, \"reason\" | \"code\" | \"wasClean\">;\n }): void;\n dataChannelOptions?: RTCDataChannelInit;\n}) {\n const userIds: string[] = [];\n\n const messagesListeners = new Set<(data: any, from: string) => void>();\n\n function createDataChannel(\n pc: RTCPeerConnection,\n peerUserId: string,\n initiator: boolean,\n restart?: () => void\n ) {\n if (initiator) {\n const dc = pc.createDataChannel(\"data\", dataChannelOptions);\n wireDataChannel(peerUserId, dc, restart);\n dataChannels.set(peerUserId, dc);\n } else {\n function listener(ev: RTCDataChannelEvent) {\n const dc = ev.channel;\n wireDataChannel(peerUserId, dc, restart);\n dataChannels.set(peerUserId, dc);\n
|
|
8
|
+
"import { EnterRoom, enterRoom } from \"./signal-room\";\nimport {\n SigType,\n SigPayload,\n collectPeerConnections,\n} from \"./webrtc-peer-collector\";\n\ntype UserListener = (\n user: string,\n action: \"join\" | \"leave\",\n users: string[]\n) => void;\n\nexport function enterWorld<D extends string | Uint8Array>({\n appId,\n logLine = console.debug,\n enterRoomFunction = enterRoom,\n peerlessUserExpiration,\n 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: {\n host: string;\n room: string;\n ev: Pick<CloseEvent, \"reason\" | \"code\" | \"wasClean\">;\n }): void;\n dataChannelOptions?: RTCDataChannelInit;\n}) {\n const userIds: string[] = [];\n\n const messagesListeners = new Set<(data: any, from: string) => void>();\n\n function createDataChannel(\n pc: RTCPeerConnection,\n peerUserId: string,\n initiator: boolean,\n restart?: () => void\n ) {\n if (initiator) {\n const dc = pc.createDataChannel(\"data\", dataChannelOptions);\n wireDataChannel(peerUserId, dc, restart);\n dataChannels.set(peerUserId, dc);\n } else {\n function listener(ev: RTCDataChannelEvent) {\n const dc = ev.channel;\n wireDataChannel(peerUserId, dc, restart);\n dataChannels.set(peerUserId, dc);\n }\n pc.addEventListener(\"datachannel\", listener);\n return () => {\n pc.removeEventListener(\"datachannel\", listener);\n };\n }\n }\n\n function wireDataChannel(\n userId: string,\n dc: RTCDataChannel,\n restart?: () => void\n ) {\n dc.onopen = () => {\n logLine(\"💬\", { event: \"dc-open\", userId });\n userIds.push(userId);\n userListeners.forEach((listener) => listener(userId, \"join\", userIds));\n };\n const onmessage = ({ data }: MessageEvent) => {\n messagesListeners.forEach((listener) => listener(data as any, userId));\n logLine(\"💬\", { event: \"dc-message\", userId, data });\n };\n dc.addEventListener(\"message\", onmessage);\n dc.addEventListener(\"close\", () => {\n logLine(\"💬\", { event: \"dc-close\", userId });\n userIds.splice(userIds.indexOf(userId), 1);\n userListeners.forEach((listener) => listener(userId, \"leave\", userIds));\n dc.removeEventListener(\"message\", onmessage);\n restart?.();\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 {\n userId,\n enterRoom,\n exitRoom,\n leaveUser,\n end: endPeerCollection,\n } = collectPeerConnections({\n appId,\n enterRoomFunction,\n logLine,\n workerUrl,\n peerlessUserExpiration,\n onRoomReady,\n onRoomClose,\n onLeaveUser(userId: string) {\n const dc = dataChannels.get(userId);\n try {\n dc?.close();\n } catch {}\n dataChannels.delete(userId);\n },\n receivePeerConnection({ pc, userId, initiator, restart }) {\n createDataChannel(pc, userId, initiator, restart);\n },\n });\n\n function send(data: D, userId?: string) {\n dataChannels.forEach((dataChannel, pUserId) => {\n if (userId && pUserId !== userId) return;\n if (dataChannel.readyState === \"open\") {\n dataChannel.send(data as any);\n }\n });\n }\n\n function removeMessageListener(listener: (data: D, from: string) => void) {\n messagesListeners.delete(listener);\n }\n\n function addMessageListener(listener: (data: D, 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 {\n dataChannel.close();\n } 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": "
|
|
10
|
+
"mappings": "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",
|
|
11
|
+
"debugId": "0CDE40A88CD9235564756E2164756E21",
|
|
12
12
|
"names": []
|
|
13
13
|
}
|