From 347877687301ec43367105a7f8c49fe16129fc00 Mon Sep 17 00:00:00 2001 From: jbion Date: Sun, 5 May 2019 11:22:58 +0200 Subject: Convert redux sagas to TypeScript --- frontend/src/sagas/errors.js | 38 ------------------ frontend/src/sagas/errors.ts | 36 +++++++++++++++++ frontend/src/sagas/game.js | 81 --------------------------------------- frontend/src/sagas/game.ts | 81 +++++++++++++++++++++++++++++++++++++++ frontend/src/sagas/gameBrowser.js | 57 --------------------------- frontend/src/sagas/gameBrowser.ts | 55 ++++++++++++++++++++++++++ frontend/src/sagas/home.js | 30 --------------- frontend/src/sagas/home.ts | 28 ++++++++++++++ frontend/src/sagas/lobby.js | 46 ---------------------- frontend/src/sagas/lobby.ts | 44 +++++++++++++++++++++ 10 files changed, 244 insertions(+), 252 deletions(-) delete mode 100644 frontend/src/sagas/errors.js create mode 100644 frontend/src/sagas/errors.ts delete mode 100644 frontend/src/sagas/game.js create mode 100644 frontend/src/sagas/game.ts delete mode 100644 frontend/src/sagas/gameBrowser.js create mode 100644 frontend/src/sagas/gameBrowser.ts delete mode 100644 frontend/src/sagas/home.js create mode 100644 frontend/src/sagas/home.ts delete mode 100644 frontend/src/sagas/lobby.js create mode 100644 frontend/src/sagas/lobby.ts (limited to 'frontend/src/sagas') diff --git a/frontend/src/sagas/errors.js b/frontend/src/sagas/errors.js deleted file mode 100644 index 15287645..00000000 --- a/frontend/src/sagas/errors.js +++ /dev/null @@ -1,38 +0,0 @@ -// @flow -import { Toaster } from '@blueprintjs/core'; -import type { Channel, SagaIterator } from 'redux-saga'; -import { eventChannel } from 'redux-saga'; -import { apply, cancelled, take } from 'redux-saga/effects'; -import type { ApiError } from '../api/model'; -import type { SevenWondersSession } from '../api/sevenWondersApi'; - -const ErrorToaster = Toaster.create(); - -export function* errorHandlingSaga(session: SevenWondersSession): SagaIterator { - const errorChannel: Channel = yield eventChannel(session.watchErrors()); - try { - while (true) { - const error: ApiError = yield take(errorChannel); - yield* handleOneError(error); - } - } finally { - if (yield cancelled()) { - console.log('Error management saga cancelled'); - yield apply(errorChannel, errorChannel.close); - } - } -} - -function* handleOneError(err: ApiError): * { - console.error('Error received on web socket channel', err); - const msg = buildMsg(err); - yield apply(ErrorToaster, ErrorToaster.show, [{ intent: 'danger', icon: 'error', message: msg }]); -} - -function buildMsg(err: ApiError): string { - if (err.details.length > 0) { - return err.details.map(d => d.message).join('\n'); - } else { - return err.message; - } -} diff --git a/frontend/src/sagas/errors.ts b/frontend/src/sagas/errors.ts new file mode 100644 index 00000000..b27dfa95 --- /dev/null +++ b/frontend/src/sagas/errors.ts @@ -0,0 +1,36 @@ +import {Toaster} from '@blueprintjs/core'; +import {Channel, eventChannel} from 'redux-saga'; +import {apply, cancelled, take} from 'redux-saga/effects'; +import {ApiError} from '../api/model'; +import {SevenWondersSession} from '../api/sevenWondersApi'; + +const ErrorToaster = Toaster.create(); + +export function* errorHandlingSaga(session: SevenWondersSession): any { + const errorChannel: Channel = yield eventChannel(session.watchErrors()); + try { + while (true) { + const error: ApiError = yield take(errorChannel); + yield* handleOneError(error); + } + } finally { + if (yield cancelled()) { + console.log('Error management saga cancelled'); + yield apply(errorChannel, errorChannel.close); + } + } +} + +function* handleOneError(err: ApiError): any { + console.error('Error received on web socket channel', err); + const msg = buildMsg(err); + yield apply(ErrorToaster, ErrorToaster.show, [{ intent: 'danger', icon: 'error', message: msg }]); +} + +function buildMsg(err: ApiError): string { + if (err.details.length > 0) { + return err.details.map(d => d.message).join('\n'); + } else { + return err.message; + } +} diff --git a/frontend/src/sagas/game.js b/frontend/src/sagas/game.js deleted file mode 100644 index 661c277b..00000000 --- a/frontend/src/sagas/game.js +++ /dev/null @@ -1,81 +0,0 @@ -import { eventChannel } from 'redux-saga'; -import { apply, call, put, take } from 'redux-saga/effects'; -import type { ApiPlayerTurnInfo, ApiPreparedCard, ApiTable } from '../api/model'; -import { SevenWondersSession } from '../api/sevenWondersApi'; -import { actions, REQUEST_PREPARE_MOVE, REQUEST_SAY_READY } from '../redux/actions/game'; -import { ENTER_GAME } from '../redux/actions/lobby'; - -function* watchPlayerReady(session: SevenWondersSession, gameId: number) { - const channel = yield eventChannel(session.watchPlayerReady(gameId)); - try { - while (true) { - const username = yield take(channel); - yield put(actions.receivePlayerReady(username)); - } - } finally { - yield apply(channel, channel.close); - } -} - -function* watchTableUpdates(session: SevenWondersSession, gameId: number) { - const channel = yield eventChannel(session.watchTableUpdates(gameId)); - try { - while (true) { - const table: ApiTable = yield take(channel); - yield put(actions.receiveTableUpdate(table)); - } - } finally { - yield apply(channel, channel.close); - } -} - -function* watchPreparedCards(session: SevenWondersSession, gameId: number) { - const channel = yield eventChannel(session.watchPreparedCards(gameId)); - try { - while (true) { - const preparedCard: ApiPreparedCard = yield take(channel); - yield put(actions.receivePreparedCard(preparedCard)); - } - } finally { - yield apply(channel, channel.close); - } -} - -function* sayReady(session: SevenWondersSession) { - while (true) { - yield take(REQUEST_SAY_READY); - yield apply(session, session.sayReady); - } -} - -function* prepareMove(session: SevenWondersSession) { - while (true) { - let action = yield take(REQUEST_PREPARE_MOVE); - yield apply(session, session.prepareMove, [action.move]); - } -} - -function* watchTurnInfo(session: SevenWondersSession) { - const channel = yield eventChannel(session.watchTurnInfo()); - try { - while (true) { - const turnInfo: ApiPlayerTurnInfo = yield take(channel); - yield put(actions.receiveTurnInfo(turnInfo)); - } - } finally { - yield apply(channel, channel.close); - } -} - -export function* gameSaga(session: SevenWondersSession) { - const { gameId } = yield take(ENTER_GAME); - console.log('Entered game!', gameId); - yield [ - call(watchPlayerReady, session, gameId), - call(watchTableUpdates, session, gameId), - call(watchPreparedCards, session, gameId), - call(sayReady, session), - call(prepareMove, session), - call(watchTurnInfo, session) - ]; -} diff --git a/frontend/src/sagas/game.ts b/frontend/src/sagas/game.ts new file mode 100644 index 00000000..a60ab2d3 --- /dev/null +++ b/frontend/src/sagas/game.ts @@ -0,0 +1,81 @@ +import { eventChannel, SagaIterator } from 'redux-saga'; +import { apply, call, put, take } from 'redux-saga/effects'; +import { ApiPlayerTurnInfo, ApiPreparedCard, ApiTable } from '../api/model'; +import { SevenWondersSession } from '../api/sevenWondersApi'; +import { actions, REQUEST_PREPARE_MOVE, REQUEST_SAY_READY } from '../redux/actions/game'; +import { ENTER_GAME } from '../redux/actions/lobby'; + +function* watchPlayerReady(session: SevenWondersSession, gameId: number) { + const channel = yield eventChannel(session.watchPlayerReady(gameId)); + try { + while (true) { + const username = yield take(channel); + yield put(actions.receivePlayerReady(username)); + } + } finally { + yield apply(channel, channel.close); + } +} + +function* watchTableUpdates(session: SevenWondersSession, gameId: number) { + const channel = yield eventChannel(session.watchTableUpdates(gameId)); + try { + while (true) { + const table: ApiTable = yield take(channel); + yield put(actions.receiveTableUpdate(table)); + } + } finally { + yield apply(channel, channel.close); + } +} + +function* watchPreparedCards(session: SevenWondersSession, gameId: number) { + const channel = yield eventChannel(session.watchPreparedCards(gameId)); + try { + while (true) { + const preparedCard: ApiPreparedCard = yield take(channel); + yield put(actions.receivePreparedCard(preparedCard)); + } + } finally { + yield apply(channel, channel.close); + } +} + +function* sayReady(session: SevenWondersSession): SagaIterator { + while (true) { + yield take(REQUEST_SAY_READY); + yield apply(session, session.sayReady); + } +} + +function* prepareMove(session: SevenWondersSession): SagaIterator { + while (true) { + let action = yield take(REQUEST_PREPARE_MOVE); + yield apply(session, session.prepareMove, [action.move]); + } +} + +function* watchTurnInfo(session: SevenWondersSession) { + const channel = yield eventChannel(session.watchTurnInfo()); + try { + while (true) { + const turnInfo: ApiPlayerTurnInfo = yield take(channel); + yield put(actions.receiveTurnInfo(turnInfo)); + } + } finally { + yield apply(channel, channel.close); + } +} + +export function* gameSaga(session: SevenWondersSession): SagaIterator { + const { gameId } = yield take(ENTER_GAME); + console.log('Entered game!', gameId); + yield [ + call(watchPlayerReady, session, gameId), + call(watchTableUpdates, session, gameId), + call(watchPreparedCards, session, gameId), + call(sayReady, session), + call(prepareMove, session), + call(watchTurnInfo, session) + ]; +} diff --git a/frontend/src/sagas/gameBrowser.js b/frontend/src/sagas/gameBrowser.js deleted file mode 100644 index 6b545933..00000000 --- a/frontend/src/sagas/gameBrowser.js +++ /dev/null @@ -1,57 +0,0 @@ -// @flow -import { push } from 'react-router-redux'; -import type { SagaIterator } from 'redux-saga'; -import { eventChannel } from 'redux-saga'; -import { all, apply, call, put, take } from 'redux-saga/effects'; -import type { ApiLobby } from '../api/model'; -import type { SevenWondersSession } from '../api/sevenWondersApi'; -import { actions as gameActions, REQUEST_CREATE_GAME, REQUEST_JOIN_GAME } from '../redux/actions/lobby'; - -function* watchGames(session: SevenWondersSession): SagaIterator { - const gamesChannel = yield eventChannel(session.watchGames()); - try { - while (true) { - const gameList = yield take(gamesChannel); - yield put(gameActions.updateGames(gameList)); - } - } finally { - yield apply(gamesChannel, gamesChannel.close); - } -} - -function* watchLobbyJoined(session: SevenWondersSession): SagaIterator { - const joinedLobbyChannel = yield eventChannel(session.watchLobbyJoined()); - try { - const joinedLobby: ApiLobby = yield take(joinedLobbyChannel); - yield put(gameActions.updateGames([joinedLobby])); - yield put(gameActions.enterLobby(joinedLobby.id)); - yield put(push(`/lobby/${joinedLobby.id}`)); - } finally { - yield apply(joinedLobbyChannel, joinedLobbyChannel.close); - } -} - -function* createGame(session: SevenWondersSession): SagaIterator { - while (true) { - const { gameName } = yield take(REQUEST_CREATE_GAME); - // $FlowFixMe - yield apply(session, session.createGame, [gameName]); - } -} - -function* joinGame(session: SevenWondersSession): SagaIterator { - while (true) { - const { gameId } = yield take(REQUEST_JOIN_GAME); - // $FlowFixMe - yield apply(session, session.joinGame, [gameId]); - } -} - -export function* gameBrowserSaga(session: SevenWondersSession): SagaIterator { - yield all([ - call(watchGames, session), - call(watchLobbyJoined, session), - call(createGame, session), - call(joinGame, session), - ]); -} diff --git a/frontend/src/sagas/gameBrowser.ts b/frontend/src/sagas/gameBrowser.ts new file mode 100644 index 00000000..868ec471 --- /dev/null +++ b/frontend/src/sagas/gameBrowser.ts @@ -0,0 +1,55 @@ +import { push } from 'react-router-redux'; +import { eventChannel, SagaIterator } from 'redux-saga'; +import { all, apply, call, put, take } from 'redux-saga/effects'; +import { ApiLobby } from '../api/model'; +import { SevenWondersSession } from '../api/sevenWondersApi'; +import { actions as gameActions, REQUEST_CREATE_GAME, REQUEST_JOIN_GAME } from '../redux/actions/lobby'; + +function* watchGames(session: SevenWondersSession): any { + const gamesChannel = yield eventChannel(session.watchGames()); + try { + while (true) { + const gameList = yield take(gamesChannel); + yield put(gameActions.updateGames(gameList)); + } + } finally { + yield apply(gamesChannel, gamesChannel.close); + } +} + +function* watchLobbyJoined(session: SevenWondersSession): any { + const joinedLobbyChannel = yield eventChannel(session.watchLobbyJoined()); + try { + const joinedLobby: ApiLobby = yield take(joinedLobbyChannel); + yield put(gameActions.updateGames([joinedLobby])); + yield put(gameActions.enterLobby(joinedLobby.id)); + yield put(push(`/lobby/${joinedLobby.id}`)); + } finally { + yield apply(joinedLobbyChannel, joinedLobbyChannel.close); + } +} + +function* createGame(session: SevenWondersSession): SagaIterator { + while (true) { + const { gameName } = yield take(REQUEST_CREATE_GAME); + // $FlowFixMe + yield apply(session, session.createGame, [gameName]); + } +} + +function* joinGame(session: SevenWondersSession): SagaIterator { + while (true) { + const { gameId } = yield take(REQUEST_JOIN_GAME); + // $FlowFixMe + yield apply(session, session.joinGame, [gameId]); + } +} + +export function* gameBrowserSaga(session: SevenWondersSession): SagaIterator { + yield all([ + call(watchGames, session), + call(watchLobbyJoined, session), + call(createGame, session), + call(joinGame, session), + ]); +} diff --git a/frontend/src/sagas/home.js b/frontend/src/sagas/home.js deleted file mode 100644 index 237ca004..00000000 --- a/frontend/src/sagas/home.js +++ /dev/null @@ -1,30 +0,0 @@ -// @flow -import { push } from 'react-router-redux'; -import type { SagaIterator } from 'redux-saga'; -import { eventChannel } from 'redux-saga'; -import { all, apply, call, put, take } from 'redux-saga/effects'; -import type { ApiPlayer } from '../api/model'; -import type { SevenWondersSession } from '../api/sevenWondersApi'; -import { actions, REQUEST_CHOOSE_USERNAME } from '../redux/actions/user'; - -function* sendUsername(session: SevenWondersSession): SagaIterator { - while (true) { - const { username } = yield take(REQUEST_CHOOSE_USERNAME); - // $FlowFixMe - yield apply(session, session.chooseName, [username]); - } -} - -function* validateUsername(session: SevenWondersSession): SagaIterator { - const usernameChannel = yield eventChannel(session.watchNameChoice()); - while (true) { - const user: ApiPlayer = yield take(usernameChannel); - yield put(actions.setCurrentPlayer(user)); - yield apply(usernameChannel, usernameChannel.close); - yield put(push('/games')); - } -} - -export function* homeSaga(session: SevenWondersSession): SagaIterator { - yield all([call(sendUsername, session), call(validateUsername, session)]); -} diff --git a/frontend/src/sagas/home.ts b/frontend/src/sagas/home.ts new file mode 100644 index 00000000..585c536e --- /dev/null +++ b/frontend/src/sagas/home.ts @@ -0,0 +1,28 @@ +import { push } from 'react-router-redux'; +import { eventChannel, SagaIterator } from 'redux-saga'; +import { all, apply, call, put, take } from 'redux-saga/effects'; +import { ApiPlayer } from '../api/model'; +import { SevenWondersSession } from '../api/sevenWondersApi'; +import { actions, REQUEST_CHOOSE_USERNAME } from '../redux/actions/user'; + +function* sendUsername(session: SevenWondersSession): SagaIterator { + while (true) { + const { username } = yield take(REQUEST_CHOOSE_USERNAME); + // $FlowFixMe + yield apply(session, session.chooseName, [username]); + } +} + +function* validateUsername(session: SevenWondersSession): any { + const usernameChannel = yield eventChannel(session.watchNameChoice()); + while (true) { + const user: ApiPlayer = yield take(usernameChannel); + yield put(actions.setCurrentPlayer(user)); + yield apply(usernameChannel, usernameChannel.close); + yield put(push('/games')); + } +} + +export function* homeSaga(session: SevenWondersSession): SagaIterator { + yield all([call(sendUsername, session), call(validateUsername, session)]); +} diff --git a/frontend/src/sagas/lobby.js b/frontend/src/sagas/lobby.js deleted file mode 100644 index ce840947..00000000 --- a/frontend/src/sagas/lobby.js +++ /dev/null @@ -1,46 +0,0 @@ -// @flow -import { push } from 'react-router-redux'; -import type { Channel, SagaIterator } from 'redux-saga'; -import { eventChannel } from 'redux-saga'; -import { all, apply, call, put, take } from 'redux-saga/effects'; -import { SevenWondersSession } from '../api/sevenWondersApi'; -import { actions as gameActions, ENTER_LOBBY, REQUEST_START_GAME } from '../redux/actions/lobby'; - -function* watchLobbyUpdates(session: SevenWondersSession, lobbyId: number): SagaIterator { - const lobbyUpdatesChannel: Channel = yield eventChannel(session.watchLobbyUpdated(lobbyId)); - try { - while (true) { - const lobby = yield take(lobbyUpdatesChannel); - yield put(gameActions.updateGames([lobby])); - } - } finally { - yield apply(lobbyUpdatesChannel, lobbyUpdatesChannel.close); - } -} - -function* watchGameStart(session: SevenWondersSession, lobbyId: number): SagaIterator { - const gameStartedChannel = yield eventChannel(session.watchGameStarted(lobbyId)); - try { - yield take(gameStartedChannel); - yield put(gameActions.enterGame(lobbyId)); - yield put(push(`/game/${lobbyId}`)); - } finally { - yield apply(gameStartedChannel, gameStartedChannel.close); - } -} - -function* startGame(session: SevenWondersSession): SagaIterator { - while (true) { - yield take(REQUEST_START_GAME); - yield apply(session, session.startGame, []); - } -} - -export function* lobbySaga(session: SevenWondersSession): SagaIterator { - const { gameId } = yield take(ENTER_LOBBY); - yield all([ - call(watchLobbyUpdates, session, gameId), - call(watchGameStart, session, gameId), - call(startGame, session) - ]); -} diff --git a/frontend/src/sagas/lobby.ts b/frontend/src/sagas/lobby.ts new file mode 100644 index 00000000..09360b02 --- /dev/null +++ b/frontend/src/sagas/lobby.ts @@ -0,0 +1,44 @@ +import { push } from 'react-router-redux'; +import { Channel, eventChannel, SagaIterator } from 'redux-saga'; +import { all, apply, call, put, take } from 'redux-saga/effects'; +import { SevenWondersSession } from '../api/sevenWondersApi'; +import { actions as gameActions, ENTER_LOBBY, REQUEST_START_GAME } from '../redux/actions/lobby'; + +function* watchLobbyUpdates(session: SevenWondersSession, lobbyId: number): any { + const lobbyUpdatesChannel: Channel = yield eventChannel(session.watchLobbyUpdated(lobbyId)); + try { + while (true) { + const lobby = yield take(lobbyUpdatesChannel); + yield put(gameActions.updateGames([lobby])); + } + } finally { + yield apply(lobbyUpdatesChannel, lobbyUpdatesChannel.close); + } +} + +function* watchGameStart(session: SevenWondersSession, lobbyId: number): any { + const gameStartedChannel = yield eventChannel(session.watchGameStarted(lobbyId)); + try { + yield take(gameStartedChannel); + yield put(gameActions.enterGame(lobbyId)); + yield put(push(`/game/${lobbyId}`)); + } finally { + yield apply(gameStartedChannel, gameStartedChannel.close); + } +} + +function* startGame(session: SevenWondersSession): SagaIterator { + while (true) { + yield take(REQUEST_START_GAME); + yield apply(session, session.startGame); + } +} + +export function* lobbySaga(session: SevenWondersSession): SagaIterator { + const { gameId } = yield take(ENTER_LOBBY); + yield all([ + call(watchLobbyUpdates, session, gameId), + call(watchGameStart, session, gameId), + call(startGame, session) + ]); +} -- cgit