From 3ba52e560d4c96095ab219be97922b620b82ba8c Mon Sep 17 00:00:00 2001 From: David Lechner Date: Sat, 23 Jan 2021 18:58:26 -0600 Subject: [PATCH] convert terminal sagas to typed-redux-saga/macro --- src/sagas/terminal.ts | 58 ++++++++++++++++++++----------------------- 1 file changed, 27 insertions(+), 31 deletions(-) diff --git a/src/sagas/terminal.ts b/src/sagas/terminal.ts index 7a828b93..621392d5 100644 --- a/src/sagas/terminal.ts +++ b/src/sagas/terminal.ts @@ -1,7 +1,6 @@ // SPDX-License-Identifier: MIT // Copyright (c) 2020-2021 The Pybricks Authors -import { Channel } from 'redux-saga'; import { actionChannel, delay, @@ -12,16 +11,11 @@ import { select, take, takeEvery, -} from 'redux-saga/effects'; +} from 'typed-redux-saga/macro'; import PushStream from 'zen-push'; import { Action } from '../actions'; import { AppActionType, AppDidStartAction } from '../actions/app'; -import { - BleUartActionType, - BleUartNotifyAction, - BleUartWriteAction, - write, -} from '../actions/ble-uart'; +import { BleUartActionType, BleUartNotifyAction, write } from '../actions/ble-uart'; import { HubRuntimeStatusType, checksum, updateStatus } from '../actions/hub'; import { TerminalActionType, @@ -32,13 +26,14 @@ import { import { SafeTxCharLength } from '../protocols/nrf-uart'; import { RootState } from '../reducers'; import { HubRuntimeState } from '../reducers/hub'; +import { defined } from '../utils'; const encoder = new TextEncoder(); const decoder = new TextDecoder(); const terminalDataSource = new PushStream(); function* startup(_action: AppDidStartAction): Generator { - yield put(setDataSource(terminalDataSource.observable)); + yield* put(setDataSource(terminalDataSource.observable)); } function* handleMatch( @@ -50,24 +45,24 @@ function* handleMatch( } if (match[1]) { - yield put(sendData(match[1])); + yield* put(sendData(match[1])); } - yield put(updateStatus(status)); + yield* put(updateStatus(status)); if (match[2]) { - yield put(sendData(match[2])); + yield* put(sendData(match[2])); } return true; } function* receiveUartData(action: BleUartNotifyAction): Generator { - const hubState = (yield select((s: RootState) => s.hub.runtime)) as HubRuntimeState; + const hubState = yield* select((s: RootState) => s.hub.runtime); if (hubState === HubRuntimeState.Loading && action.value.buffer.byteLength === 1) { const view = new DataView(action.value.buffer); - yield put(checksum(view.getUint8(0))); + yield* put(checksum(view.getUint8(0))); return; } @@ -97,40 +92,41 @@ function* receiveUartData(action: BleUartNotifyAction): Generator { return; } - yield put(sendData(value)); + yield* put(sendData(value)); } function* receiveTerminalData(): Generator { - const channel = (yield actionChannel( + const channel = yield* actionChannel( TerminalActionType.ReceivedData, - )) as Channel; + ); while (true) { // wait for input from terminal - const action = (yield take(channel)) as TerminalDataReceiveDataAction; + const action = yield* take(channel); let value = action.value; // Try to collect more data so that we aren't sending just one byte at time while (value.length < SafeTxCharLength) { - const [action, timeout] = (yield race([take(channel), delay(20)])) as [ - TerminalDataReceiveDataAction, - boolean, - ]; + const { action, timeout } = yield* race({ + action: take(channel), + timeout: delay(20), + }); if (timeout) { break; } + defined(action); value += action.value; } - const nextMessageId = (yield getContext('nextMessageId')) as () => number; + const nextMessageId = yield* getContext<() => number>('nextMessageId'); // stdin gets piped to BLE connection const data = encoder.encode(value); for (let i = 0; i < data.length; i += SafeTxCharLength) { - const { id } = (yield put( + const { id } = yield* put( write(nextMessageId(), data.slice(i, i + SafeTxCharLength)), - )) as BleUartWriteAction; + ); - yield take( + yield* take( (a: Action) => (a.type === BleUartActionType.DidWrite || a.type === BleUartActionType.DidFailToWrite) && @@ -138,7 +134,7 @@ function* receiveTerminalData(): Generator { ); // wait for echo so tht we don't overrun the hub with messages - yield race([take(BleUartActionType.Notify), delay(100)]); + yield* race([take(BleUartActionType.Notify), delay(100)]); } } } @@ -149,8 +145,8 @@ function sendTerminalData(action: TerminalDataReceiveDataAction): void { } export default function* (): Generator { - yield takeEvery(AppActionType.DidStart, startup); - yield takeEvery(BleUartActionType.Notify, receiveUartData); - yield fork(receiveTerminalData); - yield takeEvery(TerminalActionType.SendData, sendTerminalData); + yield* takeEvery(AppActionType.DidStart, startup); + yield* takeEvery(BleUartActionType.Notify, receiveUartData); + yield* fork(receiveTerminalData); + yield* takeEvery(TerminalActionType.SendData, sendTerminalData); }