import { Action } from "redux" ; import { EventChannel , eventChannel } from "redux-saga" ; import { put } from "redux-saga/effects" ; import { Socket } from "socket.io-client" ; import { IncomingRegistry } from "@shoki/networking" ; import { GameServerToClient , LobbyServerToClient } from "@creature-chess/networking" ; import { gameConnectedEvent , lobbyConnectedEvent , LobbyConnectedEvent } from "../src/networking/events" ; import { call } from "redux-saga/effects" ; import { cancelled , race , take } from "typed-redux-saga" ; import { LobbyCommands } from "./state" ; const readPacketsToActions = function * ( registry ) { let channel = null ; try { channel = eventChannel ( emit => { registry . on ( "lobbyUpdate" , ( { players } ) => { emit ( LobbyCommands . updatePlayers ( { players } ) ) ; } ) ; registry . on ( "gameConnected" as any , ( packet ) => { emit ( gameConnectedEvent ( packet ) ) ; } ) ; return ( ) => { } ; } ) ; while ( true ) { const action = yield * take ( channel ) ; yield put ( action ) ; } } finally { if ( yield * cancelled ( ) ) { channel ?. close ( ) ; } } } ; export const lobbyNetworking = function * ( socket ) { const event = yield take < LobbyConnectedEvent > ( lobbyConnectedEvent . toString ( ) ) ; yield put ( LobbyCommands . connectToLobby ( event . payload ) ) ; const registry = LobbyServerToClient . incoming ( ( opcode , handler ) => socket . on ( opcode , handler as any ) , ( opcode , handler ) => socket . off ( opcode , handler as any ) ) ; const runForever = call ( readPacketsToActions , registry ) ; const connectedToGame = take ( gameConnectedEvent . toString ( ) ) ; const result = yield * race ( { runForever , connectedToGame } ) ; if ( result . connectedToGame ) { yield put ( result . connectedToGame as unknown as Action < any > ) ; } } ;