From 393c418758cf0f57c96da54b6bba573b39ac724f Mon Sep 17 00:00:00 2001 From: ackzell Date: Wed, 24 Sep 2025 18:29:54 +0200 Subject: [PATCH 01/18] #15: Starting to integrate luna-console Modifying the vue-repl based on https://github.com/vuejs/repl/pull/333 --- packages/vue-repl/package.json | 10 +- packages/vue-repl/src/Repl.vue | 20 +++ packages/vue-repl/src/output/Output.vue | 16 +- packages/vue-repl/src/output/Preview.vue | 1 + packages/vue-repl/src/output/Sandbox.vue | 52 +++--- packages/vue-repl/src/output/srcdoc.html | 210 ++++++----------------- packages/vue-repl/src/store.ts | 16 +- packages/vue-repl/src/types.ts | 33 ++++ packages/vue-repl/test/main.ts | 4 +- packages/vue-repl/vite.config.ts | 7 +- pnpm-lock.yaml | 49 ++++++ src/components/YvRepl.vue | 5 + 12 files changed, 235 insertions(+), 188 deletions(-) diff --git a/packages/vue-repl/package.json b/packages/vue-repl/package.json index ee24e9e..6932129 100644 --- a/packages/vue-repl/package.json +++ b/packages/vue-repl/package.json @@ -26,6 +26,11 @@ "import": "./dist/codemirror-editor.js", "require": null }, + "./luna-console": { + "types": "./dist/luna-console.d.ts", + "import": "./dist/luna-console.js", + "require": null + }, "./core": { "types": "./dist/core.d.ts", "import": "./dist/core.js", @@ -117,6 +122,9 @@ "volar-service-typescript": "0.0.65", "vscode-uri": "^3.1.0", "vue": "^3.5.18", - "vue-tsc": "3.0.7-alpha.1" + "vue-tsc": "3.0.7-alpha.1", + "luna-console": "^1.3.5", + "luna-data-grid": "^1.3.0", + "luna-object-viewer": "^0.3.1" } } diff --git a/packages/vue-repl/src/Repl.vue b/packages/vue-repl/src/Repl.vue index a290c96..a82b2d0 100644 --- a/packages/vue-repl/src/Repl.vue +++ b/packages/vue-repl/src/Repl.vue @@ -4,6 +4,9 @@ import Output from './output/Output.vue' import { type Store, useStore } from './store' import { computed, provide, toRefs, useTemplateRef } from 'vue' import { + type ConsoleComponentType, + + type EditorComponentType, injectKeyPreviewRef, injectKeyProps, @@ -15,6 +18,9 @@ export interface Props { theme?: 'dark' | 'light' previewTheme?: boolean editor: EditorComponentType + console?: ConsoleComponentType + + store?: Store autoResize?: boolean showCompileOutput?: boolean @@ -22,6 +28,9 @@ export interface Props { showImportMap?: boolean showSsrOutput?: boolean showTsConfig?: boolean + showConsole?: boolean + + clearConsole?: boolean layout?: 'horizontal' | 'vertical' layoutReverse?: boolean @@ -59,6 +68,9 @@ const props = withDefaults(defineProps(), { showImportMap: true, showSsrOutput: false, showTsConfig: true, + showConsole: false, + + clearConsole: true, layoutReverse: false, ssr: false, @@ -72,6 +84,10 @@ if (!props.editor) { throw new Error('The "editor" prop is now required.') } +const consoleWrapper = computed( + () => props.console ?? (() => ({})), +) + const outputRef = useTemplateRef('output') props.store.init() @@ -81,6 +97,9 @@ const outputSlotName = computed(() => (props.layoutReverse ? 'left' : 'right')) provide(injectKeyProps, { ...toRefs(props), + console: consoleWrapper, + + autoSave, }) provide( @@ -108,6 +127,7 @@ defineExpose({ reload }) import Preview from './Preview.vue' +import SplitPane from '../SplitPane.vue' import SsrOutput from './SsrOutput.vue' import { computed, inject, useTemplateRef, watchEffect } from 'vue' import { + type ConsoleComponentType, type EditorComponentType, type OutputModes, injectKeyProps, @@ -10,13 +12,14 @@ import { const props = defineProps<{ editorComponent: EditorComponentType + consoleComponent: ConsoleComponentType showCompileOutput?: boolean showOpenSourceMap?: boolean showSsrOutput?: boolean ssr: boolean }>() -const { store } = inject(injectKeyProps)! +const { store, showConsole } = inject(injectKeyProps)! const previewRef = useTemplateRef('preview') const modes = computed(() => { const outputModes: OutputModes[] = ['preview'] @@ -51,6 +54,9 @@ function openSourceMap() { function reload() { previewRef.value?.reload() + store.value.clearConsole?.() + + } defineExpose({ reload, previewRef }) @@ -69,6 +75,14 @@ defineExpose({ reload, previewRef })
+ + + + diff --git a/packages/vue-repl/src/output/Sandbox.vue b/packages/vue-repl/src/output/Sandbox.vue index c62f480..8c969f0 100644 --- a/packages/vue-repl/src/output/Sandbox.vue +++ b/packages/vue-repl/src/output/Sandbox.vue @@ -15,7 +15,7 @@ import srcdoc from './srcdoc.html?raw' import { PreviewProxy } from './PreviewProxy' import { compileModulesForPreview } from './moduleCompiler' import type { Store } from '../store' -import { injectKeyProps } from '../types' +import { type LogLevel, type SandboxEmits, injectKeyProps } from '../types' import { getVersions, isVaporSupported } from '../import-map' export interface SandboxProps { @@ -47,6 +47,10 @@ const props = withDefaults(defineProps(), { previewOptions: () => ({}), autoStoreInit: true, }) + +const emit = defineEmits() + + const { store, theme, clearConsole, previewOptions } = toRefs(props) const keyProps = inject(injectKeyProps) @@ -132,6 +136,9 @@ function createSandbox() { sandbox.srcdoc = sandboxSrc containerRef.value?.appendChild(sandbox) + const doLog = (logLevel: LogLevel, data?: any) => + emit('log', { logLevel, data }) + proxy = new PreviewProxy(sandbox, { on_fetch_progress: (progress: any) => { // pending_imports = progress; @@ -157,33 +164,33 @@ function createSandbox() { } runtimeError.value = 'Uncaught (in promise): ' + error.message }, - on_console: (log: any) => { - if (log.duplicate) { - return - } + on_console: (log: any) => { + const maybeMsg = log.args[0] if (log.level === 'error') { - if (log.args[0] instanceof Error) { - runtimeError.value = log.args[0].message - } else { - runtimeError.value = log.args[0] - } - } else if (log.level === 'warn') { - if (log.args[0].toString().includes('[Vue warn]')) { - runtimeWarning.value = log.args - .join('') - .replace(/\[Vue warn\]:/, '') - .trim() + if (maybeMsg instanceof Error) { + runtimeError.value = maybeMsg.message + } else if (!maybeMsg?.startsWith('[vue-repl]')) { + runtimeError.value = maybeMsg } + } else if ( + log.level === 'warn' && + maybeMsg.toString().includes('[Vue warn]') + ) { + runtimeWarning.value = log.args + .join('') + .replace(/\[Vue warn\]:/, '') + .trim() } + doLog(log.level || 'log', log.args) }, on_console_group: (action: any) => { - // group_logs(action.label, false); + doLog('group', action.label) }, on_console_group_end: () => { - // ungroup_logs(); + doLog('groupEnd') }, on_console_group_collapsed: (action: any) => { - // group_logs(action.label, true); + doLog('groupCollapsed', action.label) }, }) @@ -348,12 +355,7 @@ defineExpose({ reload, container: containerRef })