Add common top-level Action type

This makes for better type inference.
This commit is contained in:
David Lechner
2020-05-26 21:20:08 -05:00
committed by David Lechner
parent 6713afe198
commit 6e4b22f841
15 changed files with 90 additions and 25 deletions
+29
View File
@@ -118,6 +118,20 @@ export function didDisconnect(): BootloaderConnectionDidDisconnectAction {
return { type: BootloaderConnectionActionType.DidDisconnect };
}
/**
* Common type for all bootloader connection actions.
*/
export type BootloaderConnectionAction =
| BootloaderConnectionConnectAction
| BootloaderConnectionDidConnectAction
| BootloaderConnectionDidCancelAction
| BootloaderConnectionDidErrorAction
| BootloaderConnectionSendAction
| BootloaderConnectionDidSendAction
| BootloaderConnectionDidSendAction
| BootloaderConnectionDidReceiveAction
| BootloaderConnectionDidDisconnectAction;
/**
* Bootloader request actions for sending commands over the connection.
*/
@@ -414,6 +428,18 @@ export function errorResponse(command: Command): BootloaderErrorResponseAction {
return { type: BootloaderResponseActionType.Error, command };
}
/**
* Common type for all bootloader response actions.
*/
export type BootloaderResponseAction =
| BootloaderEraseResponseAction
| BootloaderProgramResponseAction
| BootloaderInitResponseAction
| BootloaderInfoResponseAction
| BootloaderChecksumResponseAction
| BootloaderStateResponseAction
| BootloaderErrorResponseAction;
/**
* High-level bootloader actions.
*/
@@ -464,6 +490,9 @@ export function progress(
return { type: BootloaderActionType.FlashProgress, complete, total };
}
/**
* Common type for all high-level bootloader actions.
*/
export type BootloaderAction =
| BootloaderFlashFirmwareAction
| BootloaderFlashProgressAction;
+5
View File
@@ -60,3 +60,8 @@ export interface EditorOpenAction extends Action<EditorActionType.Open> {
export function open(data: ArrayBuffer): EditorOpenAction {
return { type: EditorActionType.Open, data };
}
/**
* Common type for all editor actions.
*/
export type EditorAction = CurrentEditorAction | EditorOpenAction | EditorSaveAction;
+29
View File
@@ -0,0 +1,29 @@
import { Dispatch as ReduxDispatch } from 'redux';
import {
BootloaderAction,
BootloaderConnectionAction,
BootloaderDidRequestAction,
BootloaderRequestAction,
BootloaderResponseAction,
} from './bootloader';
import { EditorAction } from './editor';
import { NotificationAction } from './notification';
import { TerminalDataAction } from './terminal';
/**
* Common type for all actions.
*/
export type Action =
| BootloaderConnectionAction
| BootloaderRequestAction
| BootloaderDidRequestAction
| BootloaderResponseAction
| BootloaderAction
| EditorAction
| NotificationAction
| TerminalDataAction;
/**
* Dispatch function.
*/
export type Dispatch = ReduxDispatch<Action>;
+1 -1
View File
@@ -2,7 +2,7 @@
// Copyright (c) 2020 The Pybricks Authors
import { connect } from 'react-redux';
import { Dispatch } from 'redux';
import { Dispatch } from '../actions';
import { flashFirmware } from '../actions/bootloader';
import * as notification from '../actions/notification';
import { RootState } from '../reducers';
+1 -1
View File
@@ -2,7 +2,7 @@
// Copyright (c) 2020 The Pybricks Authors
import { connect } from 'react-redux';
import { Dispatch } from 'redux';
import { Dispatch } from '../actions';
import * as editor from '../actions/editor';
import * as notification from '../actions/notification';
import { RootState } from '../reducers';
+1 -1
View File
@@ -4,7 +4,7 @@
import React from 'react';
import Toast from 'react-bootstrap/Toast';
import { connect } from 'react-redux';
import { Dispatch } from 'redux';
import { Dispatch } from '../actions';
import * as notification from '../actions/notification';
interface DispatchProps {
+1 -1
View File
@@ -2,7 +2,7 @@
// Copyright (c) 2020 The Pybricks Authors
import { connect } from 'react-redux';
import { Dispatch } from 'redux';
import { Dispatch } from '../actions';
import * as editor from '../actions/editor';
import { RootState } from '../reducers';
import ActionButton, { ActionButtonProps } from './ActionButton';
+1 -1
View File
@@ -4,10 +4,10 @@
import React from 'react';
import { connect } from 'react-redux';
import ResizeObserver from 'react-resize-observer';
import { Dispatch } from 'redux';
import { Subscription } from 'rxjs';
import { Terminal as XTerm } from 'xterm';
import { FitAddon } from 'xterm-addon-fit';
import { Dispatch } from '../actions';
import { receiveData } from '../actions/terminal';
import { terminalOutput } from '../epics/terminal';
+3 -2
View File
@@ -2,6 +2,7 @@
// Copyright (c) 2020 The Pybricks Authors
import { Reducer, combineReducers } from 'redux';
import { Action } from '../actions';
import {
BootloaderConnectionActionType,
BootloaderRequestActionType,
@@ -30,7 +31,7 @@ export enum BootloaderConnectionState {
Disconnecting = 'bootloader.connection.disconnecting',
}
const connection: Reducer<BootloaderConnectionState> = (
const connection: Reducer<BootloaderConnectionState, Action> = (
state = BootloaderConnectionState.Disconnected,
action,
) => {
@@ -124,7 +125,7 @@ export enum FirmwareFlashState {
Error = 'bootloader.flash.error',
}
const flash: Reducer<FirmwareFlashState> = (
const flash: Reducer<FirmwareFlashState, Action> = (
state = FirmwareFlashState.EndDisconnect,
action,
) => {
+3 -5
View File
@@ -3,14 +3,12 @@
import { Ace } from 'ace-builds';
import { Reducer, combineReducers } from 'redux';
import { CurrentEditorAction, EditorActionType } from '../actions/editor';
import { Action } from '../actions';
import { EditorActionType } from '../actions/editor';
type CurrentEditSession = Ace.EditSession | null;
const current: Reducer<CurrentEditSession, CurrentEditorAction> = (
state = null,
action,
) => {
const current: Reducer<CurrentEditSession, Action> = (state = null, action) => {
switch (action.type) {
case EditorActionType.Current:
return action.editSession || null;
+1 -1
View File
@@ -1,8 +1,8 @@
// SPDX-License-Identifier: MIT
// Copyright (c) 2020 The Pybricks Authors
import { Action } from 'redux';
import { runSaga, stdChannel } from 'redux-saga';
import { Action } from '../actions';
import {
BootloaderRequestActionType,
checksumRequest,
+7 -4
View File
@@ -4,7 +4,6 @@
import cPlusHubZip from '@pybricks/firmware/build/cplushub.zip';
import moveHubZip from '@pybricks/firmware/build/movehub.zip';
import JSZip from 'jszip';
import { Action } from 'redux';
import { Channel, buffers } from 'redux-saga';
import {
Effect,
@@ -18,6 +17,7 @@ import {
take,
takeEvery,
} from 'redux-saga/effects';
import { Action } from '../actions';
import {
BootloaderActionType,
BootloaderChecksumResponseAction,
@@ -38,6 +38,7 @@ import {
BootloaderProgramResponseAction,
BootloaderRequestAction,
BootloaderRequestActionType,
BootloaderResponseAction,
BootloaderResponseActionType,
checksumRequest,
checksumResponse,
@@ -95,13 +96,15 @@ const firmwareZipMap = new Map<HubType, string>([
/**
* Converts a request action into bytecodes and creates a new action to send
* the bytecodes to to the device.
* @param action The request action that was observed.
*/
function* encodeRequest(): Generator {
// Using a while loop to serialize sending data to avoid "busy" errors.
const chan = (yield actionChannel(
(a: Action) => Object.values(BootloaderRequestActionType).includes(a.type),
(a: Action) =>
Object.values(BootloaderRequestActionType).includes(
a.type as BootloaderRequestActionType,
),
buffers.expanding(),
)) as Channel<BootloaderRequestAction>;
while (true) {
@@ -200,7 +203,7 @@ function* decodeResponse(action: BootloaderConnectionDidReceiveAction): Generato
/**
* Helper type for return value of wait() function.
*/
type WaitResponse<T extends Action<BootloaderResponseActionType>> = [
type WaitResponse<T extends BootloaderResponseAction> = [
T,
BootloaderErrorResponseAction,
boolean,
+5 -6
View File
@@ -1,10 +1,10 @@
// SPDX-License-Identifier: MIT
// Copyright (c) 2020 The Pybricks Authors
import { Action, Dispatch } from 'redux';
import { Action, Dispatch } from '../actions';
import {
BootloaderConnectionActionType,
BootloaderConnectionSendAction,
didCancel,
didConnect,
didDisconnect,
@@ -130,11 +130,10 @@ async function send(action: Action, dispatch: Dispatch): Promise<void> {
if (!char) {
throw Error('Not connected');
}
const sendAction = action as BootloaderConnectionSendAction;
if (sendAction.withResponse) {
await char.xWriteValueWithResponse(sendAction.data);
if (action.withResponse) {
await char.xWriteValueWithResponse(action.data);
} else {
await char.xWriteValueWithoutResponse(sendAction.data);
await char.xWriteValueWithoutResponse(action.data);
}
dispatch(didSend());
} catch (err) {
+1 -1
View File
@@ -2,7 +2,7 @@
// Copyright (c) 2020 The Pybricks Authors
import * as FileSaver from 'file-saver';
import { Action, Dispatch } from 'redux';
import { Action, Dispatch } from '../actions';
import { EditorActionType, EditorOpenAction } from '../actions/editor';
import { RootState } from '../reducers';
import { combineServices } from '.';
+2 -1
View File
@@ -1,7 +1,8 @@
// SPDX-License-Identifier: MIT
// Copyright (c) 2020 The Pybricks Authors
import { Action, Dispatch, Middleware } from 'redux';
import { Middleware } from 'redux';
import { Action, Dispatch } from '../actions';
import { RootState } from '../reducers';
import bootloader from './bootloader';
import editor from './editor';