Skip to content

Commit 150946f

Browse files
author
Dsaquel
committed
chore: deplace LunaConsole
1 parent 83ba683 commit 150946f

File tree

8 files changed

+108
-101
lines changed

8 files changed

+108
-101
lines changed

src/Repl.vue

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@
22
import SplitPane from './SplitPane.vue'
33
import Output from './output/Output.vue'
44
import { type Store, useStore } from './store'
5-
import { computed, provide, toRefs, useTemplateRef } from 'vue'
5+
import { computed, provide, toRefs, useTemplateRef, watchEffect } from 'vue'
66
import {
7+
type ConsoleComponentType,
78
type EditorComponentType,
89
injectKeyPreviewRef,
910
injectKeyProps,
@@ -16,6 +17,7 @@ export interface Props {
1617
theme?: 'dark' | 'light'
1718
previewTheme?: boolean
1819
editor: EditorComponentType
20+
console?: ConsoleComponentType
1921
store?: Store
2022
autoResize?: boolean
2123
showCompileOutput?: boolean
@@ -57,6 +59,7 @@ const props = withDefaults(defineProps<Props>(), {
5759
showCompileOutput: true,
5860
showImportMap: true,
5961
showTsConfig: true,
62+
showConsole: false,
6063
clearConsole: true,
6164
layoutReverse: false,
6265
ssr: false,
@@ -69,6 +72,15 @@ const props = withDefaults(defineProps<Props>(), {
6972
if (!props.editor) {
7073
throw new Error('The "editor" prop is now required.')
7174
}
75+
watchEffect(() => {
76+
if (!!props.showConsole && !props.console)
77+
throw new Error(
78+
'If you want to enable a console "console" prop is required.',
79+
)
80+
})
81+
const consoleWrapper = computed<ConsoleComponentType>(
82+
() => props.console ?? (() => ({})),
83+
)
7284
7385
const outputRef = useTemplateRef('output')
7486
@@ -79,6 +91,7 @@ const outputSlotName = computed(() => (props.layoutReverse ? 'left' : 'right'))
7991
8092
provide(injectKeyProps, {
8193
...toRefs(props),
94+
console: consoleWrapper,
8295
autoSave,
8396
})
8497
provide(
@@ -106,6 +119,7 @@ defineExpose({ reload })
106119
<Output
107120
ref="output"
108121
:editor-component="editor"
122+
:console-component="consoleWrapper"
109123
:show-compile-output="props.showCompileOutput"
110124
:ssr="!!props.ssr"
111125
/>

src/output/LunaConsole.vue

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
<script setup lang="ts">
2+
import { inject, onMounted, ref, useTemplateRef, watch } from 'vue'
3+
import LunaConsole from 'luna-console'
4+
import { type LogPayload, injectKeyProps } from '../types'
5+
import 'luna-object-viewer/luna-object-viewer.css'
6+
import 'luna-data-grid/luna-data-grid.css'
7+
import 'luna-dom-viewer/luna-dom-viewer.css'
8+
import 'luna-console/luna-console.css'
9+
10+
const { store, theme } = inject(injectKeyProps)!
11+
const lunaRef = useTemplateRef('luna-ref')
12+
const lunaConsole = ref<LunaConsole>()
13+
14+
onMounted(() => {
15+
if (!lunaRef.value) return
16+
lunaConsole.value = new LunaConsole(lunaRef.value, {
17+
theme: theme.value || 'light',
18+
})
19+
store.value.executeLog = ({ logLevel, data = [] }: LogPayload) => {
20+
;(lunaConsole.value?.[logLevel] as any)?.(...data)
21+
}
22+
})
23+
24+
function clearLunaConsole() {
25+
lunaConsole.value?.clear(true)
26+
}
27+
28+
watch(() => store.value.activeFile.code, clearLunaConsole)
29+
</script>
30+
31+
<template>
32+
<div class="console-container">
33+
<div ref="luna-ref" />
34+
<button class="clear-btn" @click="clearLunaConsole">clear</button>
35+
</div>
36+
</template>
37+
38+
<style scoped>
39+
.console-container {
40+
height: 100%;
41+
width: 100%;
42+
}
43+
.luna-console-theme-dark {
44+
background-color: var(--bg) !important;
45+
}
46+
.clear-btn {
47+
position: absolute;
48+
font-size: 18px;
49+
font-family: var(--font-code);
50+
color: #999;
51+
top: 10px;
52+
right: 10px;
53+
z-index: 99;
54+
padding: 8px 10px 6px;
55+
background-color: var(--bg);
56+
border-radius: 4px;
57+
border: 1px solid var(--border);
58+
&:hover {
59+
color: var(--color-branding);
60+
}
61+
}
62+
</style>

src/output/Output.vue

Lines changed: 7 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -1,67 +1,23 @@
11
<script setup lang="ts">
22
import Preview from './Preview.vue'
33
import SplitPane from '../SplitPane.vue'
4+
import { computed, inject, useTemplateRef } from 'vue'
45
import {
5-
computed,
6-
inject,
7-
onMounted,
8-
ref,
9-
useTemplateRef,
10-
watch,
11-
type WatchHandle,
12-
} from 'vue'
13-
import LunaConsole from 'luna-console'
14-
import {
6+
type ConsoleComponentType,
157
type EditorComponentType,
16-
type LogPayload,
178
type OutputModes,
189
injectKeyProps,
1910
} from '../types'
2011
2112
const props = defineProps<{
2213
editorComponent: EditorComponentType
14+
consoleComponent: ConsoleComponentType
2315
showCompileOutput?: boolean
2416
ssr: boolean
2517
}>()
2618
27-
const { store, showConsole, theme } = inject(injectKeyProps)!
19+
const { store, showConsole } = inject(injectKeyProps)!
2820
const previewRef = useTemplateRef('preview')
29-
const consoleContainerRef = useTemplateRef('console-container')
30-
const lunaConsole = ref<LunaConsole>()
31-
let lunaWatcher: WatchHandle | undefined = undefined
32-
33-
onMounted(createConsole)
34-
35-
watch(
36-
showConsole,
37-
(val) => {
38-
if (val) {
39-
createConsole()
40-
} else {
41-
lunaConsole.value = undefined
42-
lunaWatcher?.stop()
43-
}
44-
},
45-
{ flush: 'post' },
46-
)
47-
48-
function createConsole() {
49-
if (!consoleContainerRef.value || lunaConsole.value) return
50-
lunaConsole.value = new LunaConsole(consoleContainerRef.value, {
51-
theme: theme.value || 'light',
52-
})
53-
if (!lunaWatcher) {
54-
const consoleStyles = [
55-
import('luna-object-viewer/luna-object-viewer.css'),
56-
import('luna-data-grid/luna-data-grid.css'),
57-
import('luna-dom-viewer/luna-dom-viewer.css'),
58-
import('luna-console/luna-console.css'),
59-
]
60-
Promise.all(consoleStyles)
61-
lunaWatcher = watch(() => store.value.activeFile.code, clearLunaConsole)
62-
}
63-
lunaWatcher.resume()
64-
}
6521
6622
const modes = computed(() =>
6723
props.showCompileOutput
@@ -81,17 +37,9 @@ const mode = computed<OutputModes>({
8137
},
8238
})
8339
84-
function onLog({ logLevel, data = [] }: LogPayload) {
85-
;(lunaConsole.value?.[logLevel] as any)?.(...data)
86-
}
87-
88-
function clearLunaConsole() {
89-
lunaConsole.value?.clear(true)
90-
}
91-
9240
function reload() {
9341
previewRef.value?.reload()
94-
clearLunaConsole()
42+
//clearLunaConsole()
9543
}
9644
9745
defineExpose({ reload, previewRef })
@@ -112,16 +60,10 @@ defineExpose({ reload, previewRef })
11260
<div class="output-container">
11361
<SplitPane v-if="showConsole" layout="vertical">
11462
<template #left>
115-
<Preview
116-
ref="preview"
117-
:show="mode === 'preview'"
118-
:ssr="ssr"
119-
@log="onLog"
120-
/>
63+
<Preview ref="preview" :show="mode === 'preview'" :ssr="ssr" />
12164
</template>
12265
<template #right>
123-
<div ref="console-container" />
124-
<button class="clear-btn" @click="clearLunaConsole">clear</button>
66+
<props.consoleComponent />
12567
</template>
12668
</SplitPane>
12769
<Preview v-else ref="preview" :show="mode === 'preview'" :ssr="ssr" />
@@ -166,23 +108,4 @@ button.active {
166108
color: var(--color-branding-dark);
167109
border-bottom: 3px solid var(--color-branding-dark);
168110
}
169-
.luna-console-theme-dark {
170-
background-color: var(--bg) !important;
171-
}
172-
.clear-btn {
173-
position: absolute;
174-
font-size: 18px;
175-
font-family: var(--font-code);
176-
color: #999;
177-
top: 10px;
178-
right: 10px;
179-
z-index: 99;
180-
padding: 8px 10px 6px;
181-
background-color: var(--bg);
182-
border-radius: 4px;
183-
border: 1px solid var(--border);
184-
&:hover {
185-
color: var(--color-branding);
186-
}
187-
}
188111
</style>

src/output/Preview.vue

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
11
<script setup lang="ts">
22
import { computed, inject, useTemplateRef } from 'vue'
3-
import { injectKeyProps, SandboxEmits } from '../../src/types'
3+
import { injectKeyProps } from '../../src/types'
44
import Sandbox from './Sandbox.vue'
55
66
const props = defineProps<{
77
show: boolean
88
ssr: boolean
99
}>()
10-
const emit = defineEmits<SandboxEmits>()
1110
1211
const { store, clearConsole, theme, previewTheme, previewOptions } =
1312
inject(injectKeyProps)!
@@ -34,6 +33,6 @@ defineExpose({
3433
:preview-options="previewOptions"
3534
:ssr="props.ssr"
3635
:clear-console="clearConsole"
37-
@log="(p) => emit('log', p)"
36+
@log="store.executeLog"
3837
/>
3938
</template>

src/output/Sandbox.vue

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -167,18 +167,16 @@ function createSandbox() {
167167
} else if (!maybeMsg.includes('%c Cannot clone the message')) {
168168
runtimeError.value = maybeMsg
169169
}
170-
doLog('warn', log.args)
171-
} else if (log.level === 'warn') {
172-
if (maybeMsg.toString().includes('[Vue warn]')) {
173-
runtimeWarning.value = log.args
174-
.join('')
175-
.replace(/\[Vue warn\]:/, '')
176-
.trim()
177-
}
178-
doLog('warn', log.args)
179-
} else {
180-
doLog(log.level || 'log', log.args)
170+
} else if (
171+
log.level === 'warn' &&
172+
maybeMsg.toString().includes('[Vue warn]')
173+
) {
174+
runtimeWarning.value = log.args
175+
.join('')
176+
.replace(/\[Vue warn\]:/, '')
177+
.trim()
181178
}
179+
doLog(log.level || 'log', log.args)
182180
},
183181
on_console_group: (action: any) => {
184182
doLog('group', action.label)

src/output/srcdoc.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@
156156
;['clear', 'log', 'info', 'dir', 'warn', 'error', 'table'].forEach(
157157
(level) => {
158158
const original = console[level]
159-
console[level] = async (...args) => {
159+
console[level] = (...args) => {
160160
const msg = args[0]
161161
if (typeof msg === 'string') {
162162
if (

src/store.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import type {
1616
SFCScriptCompileOptions,
1717
SFCTemplateCompileOptions,
1818
} from 'vue/compiler-sfc'
19-
import type { OutputModes } from './types'
19+
import type { LogPayload, OutputModes } from './types'
2020
import type { editor } from 'monaco-editor-core'
2121
import { type ImportMap, mergeImportMap, useVueImportMap } from './import-map'
2222

@@ -48,6 +48,7 @@ export function useStore(
4848
typescriptVersion = ref('latest'),
4949
dependencyVersion = ref(Object.create(null)),
5050
reloadLanguageTools = ref(),
51+
executeLog = ref(),
5152
}: Partial<StoreState> = {},
5253
serializedState?: string,
5354
): ReplStore {
@@ -389,6 +390,7 @@ export function useStore(
389390
deserialize,
390391
getFiles,
391392
setFiles,
393+
executeLog,
392394
})
393395
return store
394396
}
@@ -440,6 +442,11 @@ export type StoreState = ToRefs<{
440442
/** \{ dependencyName: version \} */
441443
dependencyVersion: Record<string, string>
442444
reloadLanguageTools?: (() => void) | undefined
445+
/**
446+
* If you enabled "showConsole" and have a custom "console" then you must provide this function.
447+
* @param payload - payload of a console static method output
448+
*/
449+
executeLog?: (payload: LogPayload) => void
443450
}>
444451

445452
export interface ReplStore extends UnwrapRef<StoreState> {
@@ -463,6 +470,7 @@ export interface ReplStore extends UnwrapRef<StoreState> {
463470
deserialize(serializedState: string, checkBuiltinImportMap?: boolean): void
464471
getFiles(): Record<string, string>
465472
setFiles(newFiles: Record<string, string>, mainFile?: string): Promise<void>
473+
executeLog?(payload: LogPayload): void
466474
}
467475

468476
export type Store = Pick<
@@ -487,6 +495,7 @@ export type Store = Pick<
487495
| 'renameFile'
488496
| 'getImportMap'
489497
| 'getTsConfig'
498+
| 'executeLog'
490499
>
491500

492501
export class File {

src/types.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ export interface SandboxEmits {
3939
}
4040
export type EditorComponentType = Component<EditorProps>
4141

42+
export type ConsoleComponentType = Component
43+
4244
export type OutputModes = 'preview' | EditorMode
4345

4446
export const injectKeyProps: InjectionKey<

0 commit comments

Comments
 (0)