-
Notifications
You must be signed in to change notification settings - Fork 38
/
Copy pathcommands.ts
116 lines (108 loc) Β· 3.66 KB
/
commands.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
import * as T from 'typings'
import * as TT from 'typings/tutorial'
import * as vscode from 'vscode'
import createTestRunner from './services/testRunner'
import createWebView from './services/webview/create'
import * as hooks from './services/hooks'
import logger from './services/logger'
import Channel from './channel'
export const COMMANDS = {
START: 'coderoad.start',
CONFIG_TEST_RUNNER: 'coderoad.config_test_runner',
RUN_TEST: 'coderoad.run_test',
SET_CURRENT_POSITION: 'coderoad.set_current_position',
ENTER: 'coderoad.enter',
}
interface CreateCommandProps {
extensionPath: string
workspaceState: vscode.Memento
}
let sendToClient = (action: T.Action): void => {
// function is replaced when webview mounts
}
// This makes it easier to pass the send
// function throughout the codebase
export const send = (action: T.Action): void => {
// log send of event to client
logger(`${typeof action === 'string' ? action : action.type}`)
sendToClient(action)
}
export const createCommands = (commandProps: CreateCommandProps): { [key: string]: any } => {
const { extensionPath, workspaceState } = commandProps
// React panel webview
let webview: any
let currentPosition: T.Position
let testRunner: any
const channel = new Channel(workspaceState)
const start = async () => {
if (webview && webview.state.loaded) {
webview.createOrShow()
} else {
// activate machine
webview = await createWebView({
extensionPath,
channel,
})
// make send to client function exportable
// as "send".
sendToClient = webview.send
}
}
// run activation if triggered by "workspaceContains"
start()
return {
[COMMANDS.START]: start,
[COMMANDS.CONFIG_TEST_RUNNER]: async ({
data,
alreadyConfigured,
}: {
data: TT.Tutorial
alreadyConfigured: boolean
}) => {
if (!alreadyConfigured) {
const setupActions = data.config.setup
if (setupActions) {
await hooks.onInit(setupActions, data.id)
}
}
testRunner = createTestRunner(data, {
onSuccess: (position: T.Position) => {
logger(`Test pass position: ${JSON.stringify(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 => {
// send test fail message back to client with failure message
send({ type: 'TEST_FAIL', payload: { position, fail: failSummary } })
},
onError: (position: T.Position) => {
// TODO: send test error message back to client
const message = 'Error with test runner'
send({ type: 'TEST_ERROR', payload: { position, message } })
},
onRun: (position: T.Position) => {
// send test run message back to client
send({ type: 'START_TEST', payload: { position } })
},
onLoadSubtasks: ({ summary }) => {
send({ type: 'LOAD_SUBTASK_RESULTS', payload: { summary } })
},
})
},
[COMMANDS.SET_CURRENT_POSITION]: (position: T.Position) => {
// set from last setup stepAction
currentPosition = position
channel.context.position.set(position)
},
[COMMANDS.RUN_TEST]: ({
subtasks,
callbacks,
}: { subtasks?: boolean; callbacks?: { onSuccess: () => void } } = {}) => {
testRunner({ position: currentPosition, onSuccess: callbacks?.onSuccess, subtasks })
},
[COMMANDS.ENTER]: () => {
send({ type: 'KEY_PRESS_ENTER' })
},
}
}