Skip to content

Refactor #441

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Aug 9, 2020
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
heavy refactor of channel/send
Signed-off-by: shmck <shawn.j.mckay@gmail.com>
  • Loading branch information
ShMcK committed Aug 8, 2020
commit 89c528924c410b3a684f8c09bab7310885d385a8
2 changes: 1 addition & 1 deletion src/actions/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@ export { default as onTutorialConfigContinue } from './onTutorialConfigContinue'
export { default as onValidateSetup } from './onValidateSetup'
export { default as onRunReset } from './onRunReset'
export { default as onErrorPage } from './onErrorPage'
export { runTest, onTestPass } from './onTest'
export { runTest } from './onTest'
export { onOpenLogs } from './onOpenLogs'
9 changes: 2 additions & 7 deletions src/actions/onStartup.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,12 @@
import * as vscode from 'vscode'
import * as T from 'typings'
import * as TT from 'typings/tutorial'
import * as E from 'typings/error'
import Context from '../services/context/context'
import { send } from '../commands'
import { WORKSPACE_ROOT, TUTORIAL_URL } from '../environment'
import fetch from 'node-fetch'
import logger from '../services/logger'

const onStartup = async (
context: Context,
workspaceState: vscode.Memento,
send: (action: T.Action) => Promise<void>,
): Promise<void> => {
const onStartup = async (context: Context): Promise<void> => {
try {
// check if a workspace is open, otherwise nothing works
const noActiveWorkspace = !WORKSPACE_ROOT.length
Expand Down
7 changes: 0 additions & 7 deletions src/actions/onTest.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,6 @@
import * as git from '../services/git'
import * as T from 'typings'
import * as vscode from 'vscode'
import { COMMANDS } from '../commands'
import Context from '../services/context/context'

export const onTestPass = (action: T.Action, context: Context): void => {
context.position.set({ ...action.payload.position, complete: true })
git.saveCommit('Save progress')
}

export const runTest = (action?: T.Action): void => {
vscode.commands.executeCommand(COMMANDS.RUN_TEST, action?.payload)
Expand Down
4 changes: 2 additions & 2 deletions src/actions/onTutorialConfigContinue.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ import * as T from 'typings'
import * as TT from 'typings/tutorial'
import Context from '../services/context/context'
import tutorialConfig from './utils/tutorialConfig'
import { COMMANDS } from '../commands'
import { COMMANDS, send } from '../commands'

const onTutorialConfigContinue = async (action: T.Action, context: Context, send: T.Send): Promise<void> => {
const onTutorialConfigContinue = async (action: T.Action, context: Context): Promise<void> => {
try {
const tutorialContinue: TT.Tutorial | null = context.tutorial.get()
if (!tutorialContinue) {
Expand Down
3 changes: 2 additions & 1 deletion src/actions/onTutorialConfigNew.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ import { onEvent } from '../services/telemetry'
import { version, compareVersions } from '../services/dependencies'
import Context from '../services/context/context'
import tutorialConfig from './utils/tutorialConfig'
import { send } from '../commands'

const onTutorialConfigNew = async (action: T.Action, context: Context, send: T.Send): Promise<void> => {
const onTutorialConfigNew = async (action: T.Action, context: Context): Promise<void> => {
try {
const data: TT.Tutorial = action.payload.tutorial

Expand Down
3 changes: 2 additions & 1 deletion src/actions/onValidateSetup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ import * as T from 'typings'
import * as E from 'typings/error'
import { version } from '../services/dependencies'
import { checkWorkspaceEmpty } from '../services/workspace'
import { send } from '../commands'

const onValidateSetup = async (send: T.Send): Promise<void> => {
const onValidateSetup = async (): Promise<void> => {
try {
// check workspace is selected
const isEmptyWorkspace = await checkWorkspaceEmpty()
Expand Down
45 changes: 7 additions & 38 deletions src/channel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,47 +9,36 @@ import * as hooks from './services/hooks'

interface Channel {
receive(action: T.Action): Promise<void>
send(action: T.Action): Promise<void>
}

interface ChannelProps {
postMessage: (action: T.Action) => Thenable<boolean>
workspaceState: vscode.Memento
}

class Channel implements Channel {
private postMessage: (action: T.Action) => Thenable<boolean>
private workspaceState: vscode.Memento
private context: Context
constructor({ postMessage, workspaceState }: ChannelProps) {
// workspaceState used for local storage
this.workspaceState = workspaceState
this.postMessage = postMessage
public context: Context
constructor(workspaceState: vscode.Memento) {
// workspaceState used for local storages
this.context = new Context(workspaceState)
}

// receive from webview
public receive = async (action: T.Action): Promise<void> => {
// action may be an object.type or plain string
const actionType: string = typeof action === 'string' ? action : action.type
// const onError = (error: T.ErrorMessage) => this.send({ type: 'ERROR', payload: { error } })

logger(`EXT RECEIVED: "${actionType}"`)

switch (actionType) {
case 'EDITOR_STARTUP':
actions.onStartup(this.context, this.workspaceState, this.send)
actions.onStartup(this.context)
return
// clear tutorial local storage
// configure test runner, language, git
case 'EDITOR_TUTORIAL_CONFIG':
actions.onTutorialConfigNew(action, this.context, this.send)
actions.onTutorialConfigNew(action, this.context)
return
case 'EDITOR_TUTORIAL_CONTINUE_CONFIG':
actions.onTutorialConfigContinue(action, this.context, this.send)
actions.onTutorialConfigContinue(action, this.context)
return
case 'EDITOR_VALIDATE_SETUP':
actions.onValidateSetup(this.send)
actions.onValidateSetup()
return
case 'EDITOR_REQUEST_WORKSPACE':
openWorkspace()
Expand Down Expand Up @@ -95,26 +84,6 @@ class Channel implements Channel {
return
}
}
// send to webview
public send = async (action: T.Action): Promise<void> => {
// load error page if error action is triggered
actions.onErrorPage(action)
// action may be an object.type or plain string
const actionType: string = typeof action === 'string' ? action : action.type

logger(`EXT TO CLIENT: "${actionType}"`)

switch (actionType) {
case 'TEST_PASS':
actions.onTestPass(action, this.context)
}

// send message
const sentToClient = await this.postMessage(action)
if (!sentToClient) {
throw new Error(`Message post failure: ${JSON.stringify(action)}`)
}
}
}

export default Channel
16 changes: 13 additions & 3 deletions src/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import createTestRunner from './services/testRunner'
import createWebView from './services/webview'
import * as hooks from './services/hooks'
import logger from './services/logger'
import * as actions from './actions'
import Channel from './channel'

export const COMMANDS = {
START: 'coderoad.start',
Expand All @@ -26,14 +28,20 @@ let sendToClient = (action: T.Action): void => {
// This makes it easier to pass the send
// function throughout the codebase
export const send = (action: T.Action): void => {
sendToClient(action)
// load error page if error action is triggered
actions.onErrorPage(action)

logger(`EXT TO CLIENT: "${typeof action === 'string' ? action : action.type}"`)

if (action) sendToClient(action)
}

export const createCommands = ({ extensionPath, workspaceState }: CreateCommandProps): { [key: string]: any } => {
// React panel webview
let webview: any
let currentPosition: T.Position
let testRunner: any
const channel = new Channel(workspaceState)

return {
// initialize
Expand All @@ -42,9 +50,9 @@ export const createCommands = ({ extensionPath, workspaceState }: CreateCommandP
webview.createOrShow()
} else {
// activate machine
webview = createWebView({
webview = await createWebView({
extensionPath,
workspaceState,
channel,
})
// make send to client function exportable
// as "send".
Expand All @@ -60,6 +68,7 @@ export const createCommands = ({ extensionPath, workspaceState }: CreateCommandP
onSuccess: (position: T.Position) => {
logger('test pass position', position)
// send test pass message back to client
channel.context.position.set({ ...position, complete: true })
send({ type: 'TEST_PASS', payload: { position: { ...position, complete: true } } })
},
onFail: (position: T.Position, failSummary: T.TestFail): void => {
Expand All @@ -83,6 +92,7 @@ export const createCommands = ({ extensionPath, workspaceState }: CreateCommandP
[COMMANDS.SET_CURRENT_POSITION]: (position: T.Position) => {
// set from last setup stepAction
currentPosition = position
channel.context.position.set(position)
},
[COMMANDS.RUN_TEST]: ({
subtasks,
Expand Down
1 change: 1 addition & 0 deletions src/services/hooks/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ export const onError = async (error: Error): Promise<void> => {
}

export const onStepComplete = async ({ levelId, stepId }: { levelId: string; stepId: string }): Promise<void> => {
git.saveCommit('Save progress')
logger(`ON STEP COMPLETE: ${JSON.stringify({ levelId, stepId })}`)
}

Expand Down
14 changes: 3 additions & 11 deletions src/services/webview/index.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
import * as T from 'typings'
import * as path from 'path'
import { Action } from 'typings'
import * as vscode from 'vscode'
import Channel from '../../channel'
import render from './render'

interface ReactWebViewProps {
extensionPath: string
workspaceState: vscode.Memento
channel: any
}

interface Output {
Expand All @@ -19,7 +17,7 @@ interface Output {

const state = { loaded: false }

const createReactWebView = ({ extensionPath, workspaceState }: ReactWebViewProps): Output => {
const createReactWebView = ({ extensionPath, channel }: ReactWebViewProps): Output => {
// TODO add disposables
const disposables: vscode.Disposable[] = []

Expand Down Expand Up @@ -53,15 +51,9 @@ const createReactWebView = ({ extensionPath, workspaceState }: ReactWebViewProps
disposables,
)

const channel = new Channel({
workspaceState,
postMessage: (action: Action): Thenable<boolean> => {
return panel.webview.postMessage(action)
},
})
// Handle messages from the webview
const receive = channel.receive
const send = channel.send
const send = (action: T.Action) => panel.webview.postMessage(action)

panel.webview.onDidReceiveMessage(receive, null, disposables)

Expand Down