Split ClientAction and ServerAction, and differentiate between Commands (messages sent to/from the server) and Actions (data packets sent around the client's different parts).
parent
a83c9688bb
commit
44b2813922
@ -0,0 +1,64 @@ |
|||||||
|
import {BaseAction} from "./BaseAction"; |
||||||
|
import {AppAction} from "./AppAction"; |
||||||
|
import {CellColorAction, isCellColorAction} from "./CellAction"; |
||||||
|
import {isUserActiveColorAction, UserActiveColorAction} from "./UserAction"; |
||||||
|
|
||||||
|
export const CLIENT_HELLO = "CLIENT_HELLO" |
||||||
|
/** Sent when the client connects. */ |
||||||
|
export interface ClientHelloCommand extends BaseAction { |
||||||
|
readonly type: typeof CLIENT_HELLO |
||||||
|
/** The protocol version the client is running on */ |
||||||
|
readonly version: number |
||||||
|
} |
||||||
|
export function isClientHelloCommand(action: AppAction): action is ClientHelloCommand { |
||||||
|
return action.type === CLIENT_HELLO |
||||||
|
} |
||||||
|
|
||||||
|
export const CLIENT_REFRESH = "CLIENT_REFRESH" |
||||||
|
/** Sent when the user requests a refresh. */ |
||||||
|
export interface ClientRefreshCommand extends BaseAction { |
||||||
|
readonly type: typeof CLIENT_REFRESH |
||||||
|
} |
||||||
|
export function isClientRefreshCommand(action: AppAction): action is ClientRefreshCommand { |
||||||
|
return action.type === CLIENT_REFRESH |
||||||
|
} |
||||||
|
|
||||||
|
export const CLIENT_PENDING = "CLIENT_PENDING" |
||||||
|
/** Synthesized when a user action is ready to be sent to the server. */ |
||||||
|
export interface ClientPendingAction extends BaseAction { |
||||||
|
readonly type: typeof CLIENT_PENDING |
||||||
|
readonly pending: SendableAction |
||||||
|
} |
||||||
|
export function isClientPendingAction(action: AppAction): action is ClientPendingAction { |
||||||
|
return action.type === CLIENT_PENDING |
||||||
|
} |
||||||
|
|
||||||
|
export interface SentAction { |
||||||
|
readonly id: number |
||||||
|
readonly action: SendableAction |
||||||
|
} |
||||||
|
|
||||||
|
export const CLIENT_ACT = "CLIENT_ACT" |
||||||
|
/** Sent to the server when the user performs an action. */ |
||||||
|
export interface ClientActCommand extends BaseAction { |
||||||
|
readonly type: typeof CLIENT_ACT |
||||||
|
readonly actions: readonly SentAction[] |
||||||
|
} |
||||||
|
export function isClientActCommand(action: AppAction): action is ClientActCommand { |
||||||
|
return action.type === CLIENT_ACT |
||||||
|
} |
||||||
|
|
||||||
|
export type SendableAction = CellColorAction | UserActiveColorAction |
||||||
|
export function isSendableAction(action: AppAction): action is SendableAction { |
||||||
|
return isCellColorAction(action) || isUserActiveColorAction(action) |
||||||
|
} |
||||||
|
|
||||||
|
export type ClientCommand = ClientHelloCommand | ClientRefreshCommand | ClientActCommand |
||||||
|
export function isClientCommand(action: AppAction): action is ClientCommand { |
||||||
|
return isClientHelloCommand(action) || isClientRefreshCommand(action) || isClientActCommand(action) |
||||||
|
} |
||||||
|
|
||||||
|
export type ClientAction = ClientHelloCommand | ClientRefreshCommand | ClientPendingAction | ClientActCommand |
||||||
|
export function isClientAction(action: AppAction): action is ClientAction { |
||||||
|
return isClientCommand(action) || isClientPendingAction(action) |
||||||
|
} |
@ -0,0 +1,111 @@ |
|||||||
|
import {BaseAction} from "./BaseAction"; |
||||||
|
import {SyncedState} from "../state/SyncedState"; |
||||||
|
import {AppAction} from "./AppAction"; |
||||||
|
import {SendableAction} from "./ClientAction"; |
||||||
|
|
||||||
|
export const SERVER_HELLO = "SERVER_HELLO" |
||||||
|
/** Sent in response to the client's ClientHelloAction when the client has been accepted. */ |
||||||
|
export interface ServerHelloCommand extends BaseAction { |
||||||
|
readonly type: typeof SERVER_HELLO |
||||||
|
/** The protocol version the server is running on. */ |
||||||
|
readonly version: number |
||||||
|
/** The current state of the server as of when the client connected. */ |
||||||
|
readonly state: SyncedState |
||||||
|
} |
||||||
|
export function isServerHelloCommand(action: AppAction): action is ServerHelloCommand { |
||||||
|
return action.type === SERVER_HELLO |
||||||
|
} |
||||||
|
|
||||||
|
export const SERVER_GOODBYE = "SERVER_GOODBYE" |
||||||
|
/** Synthesized out of the close message when the server closes the connection. */ |
||||||
|
export interface ServerGoodbyeCommand extends BaseAction { |
||||||
|
readonly type: typeof SERVER_GOODBYE |
||||||
|
/** The error code sent with the close message by the server, or -1 if our side crashed.*/ |
||||||
|
readonly code: number |
||||||
|
/** The text of the server's goodbye message, or the exception if our side crashed. */ |
||||||
|
readonly reason: string|Error |
||||||
|
/** The current time when this close message was received. */ |
||||||
|
readonly currentTime: Date |
||||||
|
} |
||||||
|
export function isServerGoodbyeCommand(action: AppAction): action is ServerGoodbyeCommand { |
||||||
|
return action.type === SERVER_GOODBYE |
||||||
|
} |
||||||
|
|
||||||
|
export const SERVER_REFRESH = "SERVER_REFRESH" |
||||||
|
/** Sent in response to the client's ClientRefreshCommand. */ |
||||||
|
export interface ServerRefreshCommand extends BaseAction { |
||||||
|
readonly type: typeof SERVER_REFRESH |
||||||
|
/** The current state of the server as of when the client's refresh request was processed. */ |
||||||
|
readonly state: SyncedState |
||||||
|
} |
||||||
|
export function isServerRefreshCommand(action: AppAction): action is ServerRefreshCommand { |
||||||
|
return action.type === SERVER_REFRESH |
||||||
|
} |
||||||
|
|
||||||
|
export const SERVER_OK = "SERVER_OK" |
||||||
|
/** Sent in response to the client's ClientActCommand, if it succeeds and is applied to the server map. */ |
||||||
|
export interface ServerOKCommand extends BaseAction { |
||||||
|
readonly type: typeof SERVER_OK |
||||||
|
/** |
||||||
|
* The IDs of the successful actions. |
||||||
|
* These will always be sent in sequential order - the order in which the server received and applied them. |
||||||
|
* This allows the client to apply that set of actions to its server-state copy and then refresh its local copy. |
||||||
|
*/ |
||||||
|
readonly ids: readonly number[] |
||||||
|
} |
||||||
|
export function isServerOKCommand(action: AppAction): action is ServerOKCommand { |
||||||
|
return action.type === SERVER_OK |
||||||
|
} |
||||||
|
|
||||||
|
export const SERVER_FAILED = "SERVER_FAILED" |
||||||
|
/** Sent in response to the client's ClientActCommand, if it fails and has not been applied to the server map. */ |
||||||
|
export interface ServerFailedCommand extends BaseAction { |
||||||
|
readonly type: typeof SERVER_FAILED |
||||||
|
/** The IDs of the failed actions, all of which failed with the same error. */ |
||||||
|
readonly ids: readonly number[] |
||||||
|
/** The error the above actions failed with. */ |
||||||
|
readonly error: string |
||||||
|
} |
||||||
|
export function isServerFailedCommand(action: AppAction): action is ServerFailedCommand { |
||||||
|
return action.type === SERVER_FAILED |
||||||
|
} |
||||||
|
|
||||||
|
export enum SocketState { |
||||||
|
CONNECTING = "CONNECTING", |
||||||
|
OPEN = "OPEN", |
||||||
|
} |
||||||
|
export const SERVER_SOCKET_STARTUP = "SERVER_SOCKET_STARTUP" |
||||||
|
/** Synthesized when the websocket begins connecting, i.e., enters the Connecting or Open states.. */ |
||||||
|
export interface ServerSocketStartupAction extends BaseAction { |
||||||
|
readonly type: typeof SERVER_SOCKET_STARTUP |
||||||
|
readonly state: SocketState |
||||||
|
} |
||||||
|
export function isServerSocketStartupAction(action: AppAction): action is ServerSocketStartupAction { |
||||||
|
return action.type === SERVER_SOCKET_STARTUP |
||||||
|
} |
||||||
|
|
||||||
|
export const SERVER_ACT = "SERVER_ACT" |
||||||
|
/** Sent by the server when another client has performed an action. Never sent for the client's own actions. */ |
||||||
|
export interface ServerActCommand extends BaseAction { |
||||||
|
readonly type: typeof SERVER_ACT |
||||||
|
readonly actions: readonly SyncableAction[] |
||||||
|
} |
||||||
|
export function isServerActCommand(action: AppAction): action is ServerActCommand { |
||||||
|
return action.type === SERVER_ACT |
||||||
|
} |
||||||
|
|
||||||
|
export type SyncableAction = SendableAction |
||||||
|
|
||||||
|
export type ServerCommand = |
||||||
|
ServerHelloCommand | ServerGoodbyeCommand | ServerRefreshCommand | |
||||||
|
ServerOKCommand | ServerFailedCommand | ServerActCommand |
||||||
|
export function isServerCommand(action: AppAction): action is ServerCommand { |
||||||
|
return isServerHelloCommand(action) || isServerGoodbyeCommand(action) || isServerRefreshCommand(action) |
||||||
|
|| isServerOKCommand(action) || isServerFailedCommand(action) || isServerActCommand(action) |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
export type ServerAction = ServerCommand | ServerSocketStartupAction |
||||||
|
export function isServerAction(action: AppAction): action is ServerAction { |
||||||
|
return isServerCommand(action) || isServerSocketStartupAction(action) |
||||||
|
} |
Loading…
Reference in new issue