2022-08-14 17:29:24 -05:00
|
|
|
import { joinRoom, Room, RoomConfig } from 'trystero'
|
2022-08-13 12:11:59 -05:00
|
|
|
|
2022-08-16 09:21:33 -05:00
|
|
|
import { sleep } from 'utils'
|
2022-08-15 21:38:56 -05:00
|
|
|
|
2022-08-13 12:11:59 -05:00
|
|
|
export class PeerRoom {
|
2022-08-14 21:49:14 -05:00
|
|
|
private room: Room
|
2022-08-13 12:11:59 -05:00
|
|
|
|
2022-08-14 17:29:24 -05:00
|
|
|
private roomConfig: RoomConfig
|
|
|
|
|
2022-08-14 21:49:14 -05:00
|
|
|
constructor(config: RoomConfig, roomId: string) {
|
2022-08-14 17:29:24 -05:00
|
|
|
this.roomConfig = config
|
|
|
|
this.room = joinRoom(this.roomConfig, roomId)
|
2022-08-13 12:11:59 -05:00
|
|
|
}
|
|
|
|
|
2022-08-14 21:26:50 -05:00
|
|
|
leaveRoom = () => {
|
2022-08-13 12:11:59 -05:00
|
|
|
if (this.room) {
|
|
|
|
this.room.leave()
|
|
|
|
}
|
|
|
|
}
|
2022-08-14 17:49:31 -05:00
|
|
|
|
2022-08-14 21:26:50 -05:00
|
|
|
makeAction = <T>(namespace: string) => {
|
|
|
|
return this.room.makeAction<T>(namespace)
|
2022-08-14 17:49:31 -05:00
|
|
|
}
|
2022-08-13 12:11:59 -05:00
|
|
|
}
|
2022-08-15 21:38:56 -05:00
|
|
|
|
|
|
|
// This abstraction is necessary because it takes some time for a PeerRoom to
|
|
|
|
// be torn down, and there is no way to detect when that happens. If a new
|
|
|
|
// PeerRoom is instantiated with the same config and roomId before the previous
|
|
|
|
// one is torn down, an error is thrown. The workaround is to continually
|
|
|
|
// trying to instantiate a PeerRoom until it succeeds.
|
|
|
|
export const getPeerRoom = async (config: RoomConfig, roomId: string) => {
|
|
|
|
const timeout = 1000
|
|
|
|
const epoch = Date.now()
|
|
|
|
|
|
|
|
do {
|
|
|
|
if (Date.now() - epoch > timeout) {
|
|
|
|
throw new Error('Could not create PeerRoom')
|
|
|
|
}
|
|
|
|
|
|
|
|
try {
|
|
|
|
return new PeerRoom(config, roomId)
|
|
|
|
} catch (e) {}
|
|
|
|
|
|
|
|
await sleep(100)
|
|
|
|
} while (true)
|
|
|
|
}
|