add websocket for log
diff --git a/package.json b/package.json
index 6216b90..3b81071 100644
--- a/package.json
+++ b/package.json
@@ -29,6 +29,7 @@
"pinia": "^2.0.21",
"pinia-plugin-persistedstate": "^2.1.1",
"qs": "^6.11.0",
+ "socket.io-client": "^4.5.2",
"vue": "^3.2.37",
"vue-i18n": "^9.2.2",
"vue-router": "^4.1.5"
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index eb649dd..1724d07 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -27,6 +27,7 @@
prettier: ^2.7.1
qs: ^6.11.0
sass: ^1.54.5
+ socket.io-client: ^4.5.2
typescript: '*'
vite: ^3.0.7
vite-plugin-compression: ^0.5.1
@@ -45,6 +46,7 @@
pinia: 2.0.21_typescript@4.8.2+vue@3.2.37
pinia-plugin-persistedstate: 2.1.1_pinia@2.0.21
qs: registry.npmmirror.com/qs/6.11.0
+ socket.io-client: registry.npmmirror.com/socket.io-client/4.5.2
vue: 3.2.37
vue-i18n: 9.2.2_vue@3.2.37
vue-router: 4.1.5_vue@3.2.37
@@ -1204,12 +1206,6 @@
ms: 2.0.0
dev: true
- /debug/3.2.7:
- resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==}
- dependencies:
- ms: registry.npmmirror.com/ms/2.1.2
- dev: true
-
/debug/4.3.4:
resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==}
engines: {node: '>=6.0'}
@@ -1395,7 +1391,7 @@
/eslint-import-resolver-node/0.3.6:
resolution: {integrity: sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw==}
dependencies:
- debug: 3.2.7
+ debug: registry.npmmirror.com/debug/3.2.7
resolve: 1.22.1
dev: true
@@ -1408,7 +1404,7 @@
eslint:
optional: true
dependencies:
- debug: 3.2.7
+ debug: registry.npmmirror.com/debug/3.2.7
eslint: 8.23.0
dev: true
@@ -2781,7 +2777,7 @@
peerDependencies:
eslint: '>=6.0.0'
dependencies:
- debug: 4.3.4
+ debug: registry.npmmirror.com/debug/4.3.4
eslint: 8.23.0
eslint-scope: 7.1.1
eslint-visitor-keys: 3.3.0
@@ -2915,6 +2911,12 @@
dev: true
optional: true
+ registry.npmmirror.com/@socket.io/component-emitter/3.1.0:
+ resolution: {integrity: sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz}
+ name: '@socket.io/component-emitter'
+ version: 3.1.0
+ dev: false
+
registry.npmmirror.com/@types/qs/6.9.7:
resolution: {integrity: sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@types/qs/-/qs-6.9.7.tgz}
name: '@types/qs'
@@ -3126,6 +3128,14 @@
which: registry.npmmirror.com/which/2.0.2
dev: true
+ registry.npmmirror.com/debug/3.2.7:
+ resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/debug/-/debug-3.2.7.tgz}
+ name: debug
+ version: 3.2.7
+ dependencies:
+ ms: registry.npmmirror.com/ms/2.1.2
+ dev: true
+
registry.npmmirror.com/debug/4.3.4:
resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/debug/-/debug-4.3.4.tgz}
name: debug
@@ -3138,7 +3148,6 @@
optional: true
dependencies:
ms: registry.npmmirror.com/ms/2.1.2
- dev: true
registry.npmmirror.com/delayed-stream/1.0.0:
resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/delayed-stream/-/delayed-stream-1.0.0.tgz}
@@ -3165,6 +3174,29 @@
version: 9.2.2
dev: true
+ registry.npmmirror.com/engine.io-client/6.2.2:
+ resolution: {integrity: sha512-8ZQmx0LQGRTYkHuogVZuGSpDqYZtCM/nv8zQ68VZ+JkOpazJ7ICdsSpaO6iXwvaU30oFg5QJOJWj8zWqhbKjkQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/engine.io-client/-/engine.io-client-6.2.2.tgz}
+ name: engine.io-client
+ version: 6.2.2
+ dependencies:
+ '@socket.io/component-emitter': registry.npmmirror.com/@socket.io/component-emitter/3.1.0
+ debug: registry.npmmirror.com/debug/4.3.4
+ engine.io-parser: registry.npmmirror.com/engine.io-parser/5.0.4
+ ws: registry.npmmirror.com/ws/8.2.3
+ xmlhttprequest-ssl: registry.npmmirror.com/xmlhttprequest-ssl/2.0.0
+ transitivePeerDependencies:
+ - bufferutil
+ - supports-color
+ - utf-8-validate
+ dev: false
+
+ registry.npmmirror.com/engine.io-parser/5.0.4:
+ resolution: {integrity: sha512-+nVFp+5z1E3HcToEnO7ZIj3g+3k9389DvWtvJZz0T6/eOCPIyyxehFcedoYrZQrp0LgQbD9pPXhpMBKMd5QURg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/engine.io-parser/-/engine.io-parser-5.0.4.tgz}
+ name: engine.io-parser
+ version: 5.0.4
+ engines: {node: '>=10.0.0'}
+ dev: false
+
registry.npmmirror.com/esbuild-android-64/0.14.54:
resolution: {integrity: sha512-Tz2++Aqqz0rJ7kYBfz+iqyE3QMycD4vk7LBRyWaAVFgFtQ/O8EJOnVmTOiDWYZ/uYzB4kvP+bqejYdVKzE5lAQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/esbuild-android-64/-/esbuild-android-64-0.14.54.tgz}
name: esbuild-android-64
@@ -3663,7 +3695,6 @@
resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/ms/-/ms-2.1.2.tgz}
name: ms
version: 2.1.2
- dev: true
registry.npmmirror.com/normalize-path/3.0.0:
resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/normalize-path/-/normalize-path-3.0.0.tgz}
@@ -3838,6 +3869,34 @@
is-fullwidth-code-point: registry.npmmirror.com/is-fullwidth-code-point/4.0.0
dev: true
+ registry.npmmirror.com/socket.io-client/4.5.2:
+ resolution: {integrity: sha512-naqYfFu7CLDiQ1B7AlLhRXKX3gdeaIMfgigwavDzgJoIUYulc1qHH5+2XflTsXTPY7BlPH5rppJyUjhjrKQKLg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/socket.io-client/-/socket.io-client-4.5.2.tgz}
+ name: socket.io-client
+ version: 4.5.2
+ engines: {node: '>=10.0.0'}
+ dependencies:
+ '@socket.io/component-emitter': registry.npmmirror.com/@socket.io/component-emitter/3.1.0
+ debug: registry.npmmirror.com/debug/4.3.4
+ engine.io-client: registry.npmmirror.com/engine.io-client/6.2.2
+ socket.io-parser: registry.npmmirror.com/socket.io-parser/4.2.1
+ transitivePeerDependencies:
+ - bufferutil
+ - supports-color
+ - utf-8-validate
+ dev: false
+
+ registry.npmmirror.com/socket.io-parser/4.2.1:
+ resolution: {integrity: sha512-V4GrkLy+HeF1F/en3SpUaM+7XxYXpuMUWLGde1kSSh5nQMN4hLrbPIkD+otwh6q9R6NOQBN4AMaOZ2zVjui82g==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/socket.io-parser/-/socket.io-parser-4.2.1.tgz}
+ name: socket.io-parser
+ version: 4.2.1
+ engines: {node: '>=10.0.0'}
+ dependencies:
+ '@socket.io/component-emitter': registry.npmmirror.com/@socket.io/component-emitter/3.1.0
+ debug: registry.npmmirror.com/debug/4.3.4
+ transitivePeerDependencies:
+ - supports-color
+ dev: false
+
registry.npmmirror.com/string-argv/0.3.1:
resolution: {integrity: sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/string-argv/-/string-argv-0.3.1.tgz}
name: string-argv
@@ -3952,6 +4011,28 @@
strip-ansi: registry.npmmirror.com/strip-ansi/6.0.1
dev: true
+ registry.npmmirror.com/ws/8.2.3:
+ resolution: {integrity: sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/ws/-/ws-8.2.3.tgz}
+ name: ws
+ version: 8.2.3
+ engines: {node: '>=10.0.0'}
+ peerDependencies:
+ bufferutil: ^4.0.1
+ utf-8-validate: ^5.0.2
+ peerDependenciesMeta:
+ bufferutil:
+ optional: true
+ utf-8-validate:
+ optional: true
+ dev: false
+
+ registry.npmmirror.com/xmlhttprequest-ssl/2.0.0:
+ resolution: {integrity: sha512-QKxVRxiRACQcVuQEYFsI1hhkrMlrXHPegbbd1yn9UHOmRxY+si12nQYzri3vbzt8VdTTRviqcKxcyllFas5z2A==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.0.0.tgz}
+ name: xmlhttprequest-ssl
+ version: 2.0.0
+ engines: {node: '>=0.4.0'}
+ dev: false
+
registry.npmmirror.com/yaml/2.1.1:
resolution: {integrity: sha512-o96x3OPo8GjWeSLF+wOAbrPfhFOGY0W00GNaxCDv+9hkcDJEnev1yh8S7pgHF0ik6zc8sQLuL8hjHjJULZp8bw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/yaml/-/yaml-2.1.1.tgz}
name: yaml
diff --git a/studio/components/log/index.tsx b/studio/components/log/index.tsx
index 57ee3bb..6e353cb 100644
--- a/studio/components/log/index.tsx
+++ b/studio/components/log/index.tsx
@@ -16,17 +16,24 @@
*/
import { NTabs, NTabPane, NLog } from 'naive-ui'
-import { defineComponent, ref } from 'vue'
+import { defineComponent, PropType } from 'vue'
+
+const props = {
+ value: {
+ type: String as PropType<string>,
+ default: ''
+ }
+}
export const Log = defineComponent({
name: 'log',
- setup() {
- const logRef = ref('')
+ props,
+ setup(props) {
return () => {
return (
<NTabs type='card' closable size='small'>
<NTabPane name='运行日志'>
- <NLog log={logRef.value} />
+ <NLog log={props.value} />
</NTabPane>
</NTabs>
)
diff --git a/studio/components/studio-content/index.tsx b/studio/components/studio-content/index.tsx
index 9533bfa..829a8e6 100644
--- a/studio/components/studio-content/index.tsx
+++ b/studio/components/studio-content/index.tsx
@@ -15,7 +15,7 @@
* limitations under the License.
*/
-import { defineComponent } from 'vue'
+import { defineComponent, ref } from 'vue'
import { NLayoutContent } from 'naive-ui'
import { Toolbar } from '../toolbar'
import { Tabs } from '../tab'
@@ -24,12 +24,18 @@
export const StudioContent = defineComponent({
name: 'studio-content',
setup() {
+ const logIdRef = ref()
+
+ const showLog = (id: number) => {
+ logIdRef.value = id
+ }
+
return () => (
<NLayoutContent class={styles['studio-content']}>
<div class={styles['editor']}>
- <Toolbar />
+ <Toolbar onShowLog={showLog} />
<div class={styles['tab']}>
- <Tabs />
+ <Tabs runId={logIdRef.value} />
</div>
</div>
</NLayoutContent>
diff --git a/studio/components/tab/index.tsx b/studio/components/tab/index.tsx
index 1be8e02..18aca24 100644
--- a/studio/components/tab/index.tsx
+++ b/studio/components/tab/index.tsx
@@ -15,16 +15,27 @@
* limitations under the License.
*/
-import { defineComponent, watch } from 'vue'
+import { defineComponent, watch, PropType, reactive } from 'vue'
import { NTabPane, NTabs } from 'naive-ui'
import { MonacoEditor } from '../monaco'
import utils from '@/utils'
import { useFileStore } from '@/store/file'
import { Log } from '../log'
+import { createLogSocket } from '@/service/modules/log'
+import type { Socket } from 'socket.io-client'
+
+const props = {
+ runId: {
+ type: Number as PropType<number>,
+ default: 0
+ }
+}
export const Tabs = defineComponent({
name: 'tabs',
- setup() {
+ props,
+ setup(props) {
+ const socketRef = reactive<{ [key: string]: Socket }>({})
const fileStore = useFileStore()
const updateContent = (value: string) => {
@@ -33,27 +44,30 @@
const handleClose = (fileName: string) => {
fileStore.closeFile(fileName)
+ socketRef[fileName].close()
}
const handleChange = (value: string) => {
updateContent(value)
}
- const createTabPane = () => {
- return fileStore.getOpenFiles.map((file) => {
- const language = utils.getLanguageByName(file.name)
- return (
- <NTabPane name={file.name} key={file.name} tab={file.name}>
- <MonacoEditor v-model:value={file.content} options={{ language }} />
- <Log />
- </NTabPane>
- )
- })
+ const getLogContent = (id: number) => {
+ const file = fileStore.getOpenFiles.filter(
+ (file) => file.name === fileStore.getCurrentFile
+ )[0]
+
+ if (!socketRef[file.name]) {
+ socketRef[file.name] = createLogSocket(id)
+ }
+
+ const socket = socketRef[file.name]
+ console.log(file.log)
+ socket.on('log', (data) => (file.log += data))
}
watch(
- () => fileStore.getCurrentFile,
- () => createTabPane()
+ () => props.runId,
+ () => getLogContent(props.runId)
)
return () => (
@@ -66,7 +80,18 @@
onClose={handleClose}
on-update:value={handleChange}
>
- {createTabPane()}
+ {fileStore.getOpenFiles.map((file) => {
+ const language = utils.getLanguageByName(file.name)
+ return (
+ <NTabPane name={file.name} key={file.name} tab={file.name}>
+ <MonacoEditor
+ v-model:value={file.content}
+ options={{ language }}
+ />
+ <Log v-model:value={file.log} />
+ </NTabPane>
+ )
+ })}
</NTabs>
)
}
diff --git a/studio/components/toolbar/index.tsx b/studio/components/toolbar/index.tsx
index 7e62c44..9f9ec01 100644
--- a/studio/components/toolbar/index.tsx
+++ b/studio/components/toolbar/index.tsx
@@ -29,7 +29,8 @@
export const Toolbar = defineComponent({
name: 'toolbar',
- setup() {
+ emits: ['showLog'],
+ setup(props, ctx) {
const fileStore = useFileStore()
const handleSave = () => {
@@ -44,7 +45,8 @@
(file) => file.name === fileStore.getCurrentFile
)[0]
- runFile(file.id)
+ // runFile(file.id)
+ ctx.emit('showLog', file.id)
}
const openFile = () => {
@@ -61,28 +63,28 @@
return () => (
<div class={styles.toolbar}>
<div class={styles.operate}>
- <NButton text style={{ fontSize: '24px' }} onClick={openFile}>
+ <NButton text style={{ fontSize: '18px' }} onClick={openFile}>
<NIcon>
<FileAddOutlined />
</NIcon>
</NButton>
</div>
<div class={styles.operate}>
- <NButton text style={{ fontSize: '24px' }} onClick={handleSave}>
+ <NButton text style={{ fontSize: '18px' }} onClick={handleSave}>
<NIcon>
<SaveOutlined />
</NIcon>
</NButton>
</div>
<div class={styles.operate}>
- <NButton text style={{ fontSize: '24px' }} onClick={handleRun}>
+ <NButton text style={{ fontSize: '18px' }} onClick={handleRun}>
<NIcon>
<PlayCircleOutlined />
</NIcon>
</NButton>
</div>
<div class={styles.operate}>
- <NButton text style={{ fontSize: '24px' }}>
+ <NButton text style={{ fontSize: '18px' }}>
<NIcon>
<FullscreenOutlined />
</NIcon>
diff --git a/studio/service/modules/log/index.ts b/studio/service/modules/log/index.ts
new file mode 100644
index 0000000..cb902e6
--- /dev/null
+++ b/studio/service/modules/log/index.ts
@@ -0,0 +1,24 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { io, Socket } from 'socket.io-client'
+
+export const createLogSocket = (id: number): Socket => {
+ return io('', {
+ path: '/studio/ws'
+ })
+}
diff --git a/studio/store/file/index.ts b/studio/store/file/index.ts
index 5b8232e..834aaf2 100644
--- a/studio/store/file/index.ts
+++ b/studio/store/file/index.ts
@@ -41,6 +41,7 @@
this.files.push(file)
this.fileNames.push(file.name)
}
+ file.log = ''
this.currentFile = file.name
},
closeFile(fileName: string): void {
diff --git a/studio/store/file/types.ts b/studio/store/file/types.ts
index 57d7ae1..0ea4043 100644
--- a/studio/store/file/types.ts
+++ b/studio/store/file/types.ts
@@ -21,6 +21,7 @@
content: string
oldContent?: string
saved: boolean
+ log?: string
}
interface IFileState {
diff --git a/vite.config.ts b/vite.config.ts
index 84e6ed8..429ce10 100644
--- a/vite.config.ts
+++ b/vite.config.ts
@@ -50,6 +50,11 @@
target: loadEnv('development', './').VITE_APP_DEV_WEB_URL,
changeOrigin: true,
rewrite: (path) => path.replace(/^\/studio\/api/, '')
+ },
+ '/studio/ws': {
+ target: loadEnv('development', './').VITE_APP_DEV_WEB_URL,
+ ws: true,
+ rewrite: (path) => path.replace(/^\/studio\/ws/, '/socket.io/')
}
}
},