From ebbc4625252fb4b76c5cabb77d5bfe8be4b5517a Mon Sep 17 00:00:00 2001 From: Dsaquel Date: Fri, 20 Dec 2024 23:00:30 +0100 Subject: [PATCH 01/17] feat: init console :construction: --- src/output/Console.vue | 20 +++++ src/output/ConsoleLine.vue | 157 +++++++++++++++++++++++++++++++++++++ src/output/JsonNode.vue | 55 +++++++++++++ src/output/JsonTree.vue | 29 +++++++ src/output/Preview.vue | 41 +++++++--- src/output/PreviewProxy.ts | 2 + src/types.ts | 9 +++ src/utils.ts | 13 +++ 8 files changed, 314 insertions(+), 12 deletions(-) create mode 100644 src/output/Console.vue create mode 100644 src/output/ConsoleLine.vue create mode 100644 src/output/JsonNode.vue create mode 100644 src/output/JsonTree.vue diff --git a/src/output/Console.vue b/src/output/Console.vue new file mode 100644 index 00000000..1ac4605a --- /dev/null +++ b/src/output/Console.vue @@ -0,0 +1,20 @@ + + + + + diff --git a/src/output/ConsoleLine.vue b/src/output/ConsoleLine.vue new file mode 100644 index 00000000..c6da9c18 --- /dev/null +++ b/src/output/ConsoleLine.vue @@ -0,0 +1,157 @@ + + + + + diff --git a/src/output/JsonNode.vue b/src/output/JsonNode.vue new file mode 100644 index 00000000..ff1b8aa0 --- /dev/null +++ b/src/output/JsonNode.vue @@ -0,0 +1,55 @@ + + + + + + diff --git a/src/output/JsonTree.vue b/src/output/JsonTree.vue new file mode 100644 index 00000000..6cb9229c --- /dev/null +++ b/src/output/JsonTree.vue @@ -0,0 +1,29 @@ + + + + diff --git a/src/output/Preview.vue b/src/output/Preview.vue index 19b0e93c..070958bb 100644 --- a/src/output/Preview.vue +++ b/src/output/Preview.vue @@ -1,4 +1,5 @@ diff --git a/src/output/JsonNode.vue b/src/output/JsonNode.vue index ff1b8aa0..558148f3 100644 --- a/src/output/JsonNode.vue +++ b/src/output/JsonNode.vue @@ -1,55 +1,87 @@ +.tree__title { + font-weight: 500; +} +.block { + display: block; +} + diff --git a/src/output/JsonTree.vue b/src/output/JsonTree.vue index 6cb9229c..acc572a2 100644 --- a/src/output/JsonTree.vue +++ b/src/output/JsonTree.vue @@ -1,19 +1,22 @@ - + + diff --git a/src/output/Preview.vue b/src/output/Preview.vue index 070958bb..642a59d1 100644 --- a/src/output/Preview.vue +++ b/src/output/Preview.vue @@ -303,14 +303,16 @@ defineExpose({ reload, container: containerRef }) class="iframe-container" :class="{ [theme]: previewTheme }" /> - + diff --git a/src/types.ts b/src/types.ts index 0820d3eb..564ef7bd 100644 --- a/src/types.ts +++ b/src/types.ts @@ -8,8 +8,18 @@ export interface EditorProps { readonly?: boolean mode?: EditorMode } -export type ConsoleLevel = 'clear' | 'log' | 'info' | 'dir' | 'warn' | 'error' | 'table' | 'group' | 'unclonable' | 'assert' -export interface CommandData{ +export type ConsoleLevel = + | 'clear' + | 'log' + | 'info' + | 'dir' + | 'warn' + | 'error' + | 'table' + | 'group' + | 'unclonable' + | 'assert' +export interface CommandData { action: 'console' | 'cmd_error' | 'cmd_ok' | 'error' | 'unhandledrejection' args: string[] level: ConsoleLevel diff --git a/src/utils.ts b/src/utils.ts index 2db3bc5c..2e673f12 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -33,14 +33,19 @@ export function atou(base64: string): string { } export function parse(value: any = false) { - value = value ?? false - if (typeof value === 'object') { - return Object.entries(value) as [string, any][] - } - return false + value = value ?? false + if (typeof value === 'object') { + return Object.entries(value) as [string, any][] + } + return false } export function word(total: number, singular: string, plural: string) { - const choose = total > 1 ? plural : singular - return `${total} ${choose}` + const choose = total > 1 ? plural : singular + return `${total} ${choose}` +} + +export function isObject(value: any) { + const type = typeof value + return value != null && (type == 'object' || type == 'function') } diff --git a/test/main.ts b/test/main.ts index 85cce24f..8e4c3f3f 100644 --- a/test/main.ts +++ b/test/main.ts @@ -59,7 +59,7 @@ const App = { previewTheme: previewTheme.value, editor: MonacoEditor, // layout: 'vertical', - ssr: true, + ssr: false, sfcOptions: { script: { // inlineTemplate: false From 859e216781b57229f003f88bab19515a2f27991f Mon Sep 17 00:00:00 2001 From: Dsaquel Date: Sun, 22 Dec 2024 17:02:18 +0100 Subject: [PATCH 03/17] chore: wip --- src/output/ConsoleLine.vue | 1 - src/output/JsonNode.vue | 13 +++++-------- src/output/JsonTree.vue | 12 ++++-------- 3 files changed, 9 insertions(+), 17 deletions(-) diff --git a/src/output/ConsoleLine.vue b/src/output/ConsoleLine.vue index 210c5bc8..103d9b56 100644 --- a/src/output/ConsoleLine.vue +++ b/src/output/ConsoleLine.vue @@ -58,7 +58,6 @@ const level = ref(1) v-for="arg in log.args" :data="arg" :margin-offset="0" - :increment="0" /> diff --git a/src/output/JsonNode.vue b/src/output/JsonNode.vue index 558148f3..81776c1c 100644 --- a/src/output/JsonNode.vue +++ b/src/output/JsonNode.vue @@ -1,6 +1,6 @@ diff --git a/src/output/ConsoleLine.vue b/src/output/ConsoleLine.vue deleted file mode 100644 index 103d9b56..00000000 --- a/src/output/ConsoleLine.vue +++ /dev/null @@ -1,175 +0,0 @@ - - - - - diff --git a/src/output/JsonNode.vue b/src/output/JsonNode.vue deleted file mode 100644 index 81776c1c..00000000 --- a/src/output/JsonNode.vue +++ /dev/null @@ -1,84 +0,0 @@ - - - - - diff --git a/src/output/JsonTree.vue b/src/output/JsonTree.vue deleted file mode 100644 index d9ee0624..00000000 --- a/src/output/JsonTree.vue +++ /dev/null @@ -1,49 +0,0 @@ - - - - - diff --git a/src/output/Preview.vue b/src/output/Preview.vue index 642a59d1..bf5038cf 100644 --- a/src/output/Preview.vue +++ b/src/output/Preview.vue @@ -11,11 +11,11 @@ import { watch, watchEffect, } from 'vue' +import LunaConsole from 'luna-console' import srcdoc from './srcdoc.html?raw' import { PreviewProxy } from './PreviewProxy' import { compileModulesForPreview } from './moduleCompiler' -import { CommandData, injectKeyProps } from '../../src/types' -import Console from './Console.vue' +import { injectKeyProps } from '../../src/types' const props = defineProps<{ show: boolean; ssr: boolean }>() @@ -23,16 +23,21 @@ const { store, clearConsole, theme, previewTheme, previewOptions } = inject(injectKeyProps)! const containerRef = useTemplateRef('container') +const consoleContainerRef = useTemplateRef('console-container') const runtimeError = ref() const runtimeWarning = ref() -const logs = ref([]) let sandbox: HTMLIFrameElement +let lunaConsole: LunaConsole let proxy: PreviewProxy let stopUpdateWatcher: WatchStopHandle | undefined // create sandbox on mount -onMounted(createSandbox) +onMounted(() => { + createSandbox() + if (!consoleContainerRef.value) return + lunaConsole = new LunaConsole(consoleContainerRef.value, { theme: 'dark' }) +}) // reset sandbox when import map changes watch( @@ -142,6 +147,7 @@ function createSandbox() { } else { runtimeError.value = log.args[0] } + lunaConsole.error(...log.args) } else if (log.level === 'warn') { if (log.args[0].toString().includes('[Vue warn]')) { runtimeWarning.value = log.args @@ -149,26 +155,22 @@ function createSandbox() { .replace(/\[Vue warn\]:/, '') .trim() } + lunaConsole.warn(...log.args) } else { - push_logs(log) + lunaConsole.log(...log.args) } }, on_console_group: (action: any) => { - // group_logs(action.label, false); + lunaConsole.group(action.label) }, on_console_group_end: () => { - // ungroup_logs(); + lunaConsole.groupEnd() }, on_console_group_collapsed: (action: any) => { - // group_logs(action.label, true); + lunaConsole.groupCollapsed(action.label) }, }) - function push_logs(log: CommandData) { - //current_log_group.push(last_console_event = log); - logs.value.push(log) - } - sandbox.addEventListener('load', () => { proxy.handle_links() stopUpdateWatcher = watchEffect(updatePreview) @@ -312,7 +314,7 @@ defineExpose({ reload, container: containerRef }) /> From bbf1943b38fd5efcff2006803c7ae9f6f40b2004 Mon Sep 17 00:00:00 2001 From: Dsaquel Date: Sat, 12 Apr 2025 15:09:17 +0200 Subject: [PATCH 05/17] improve console --- pnpm-lock.yaml | 73 ++++++++++++++++++++++-------------------- src/Repl.vue | 6 ++-- src/output/Preview.vue | 11 +++++-- src/output/Sandbox.vue | 67 +++++++++++++++++++++++++++++++++----- src/output/srcdoc.html | 31 ++++-------------- 5 files changed, 117 insertions(+), 71 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 27edfa91..973cb12e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -7,19 +7,6 @@ settings: importers: .: - dependencies: - luna-console: - specifier: ^1.3.5 - version: 1.3.5(luna-data-grid@1.3.0)(luna-dom-viewer@1.4.0)(luna-object-viewer@0.3.1) - luna-data-grid: - specifier: ^1.3.0 - version: 1.3.0 - luna-dom-viewer: - specifier: ^1.4.0 - version: 1.4.0 - luna-object-viewer: - specifier: ^0.3.1 - version: 0.3.1 devDependencies: '@babel/standalone': specifier: ^7.26.9 @@ -90,6 +77,18 @@ importers: lint-staged: specifier: ^15.4.3 version: 15.4.3 + luna-console: + specifier: ^1.3.5 + version: 1.3.5(luna-data-grid@1.4.1)(luna-dom-viewer@1.8.2)(luna-object-viewer@0.3.1) + luna-data-grid: + specifier: ^1.3.0 + version: 1.4.1 + luna-dom-viewer: + specifier: ^1.4.0 + version: 1.8.2 + luna-object-viewer: + specifier: ^0.3.1 + version: 0.3.1 monaco-editor-core: specifier: ^0.52.2 version: 0.52.2 @@ -1684,11 +1683,11 @@ packages: resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} engines: {node: '>= 0.8.0'} - licia@1.46.0: - resolution: {integrity: sha512-Zms2AjJB+KdqUKFF87J5J/w9DwXnGN/lKlbjpRgvaPf0BIQ0mOZ/2lX4E79zwNafHGMUq5RtN54FN6Af5G92cA==} + licia@1.48.0: + resolution: {integrity: sha512-bBWiT5CSdEtwuAHiYTJ74yItCjIFdHi4xiFk6BRDfKa+sdCpkUHp69YKb5udNOJlHDzFjNjcMgNZ/+wQIHrB8A==} - lilconfig@3.1.2: - resolution: {integrity: sha512-eop+wDAvpItUys0FWkHIKeC9ybYrTGbU41U5K7+bttZZeohvnY7M9dZ5kB21GNWiFT2q1OoPTvncPCgSOVO5ow==} + lilconfig@3.1.3: + resolution: {integrity: sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==} engines: {node: '>=14'} lines-and-columns@1.2.4: @@ -1738,17 +1737,21 @@ packages: luna-dom-viewer: ^1.4.0 luna-object-viewer: ^0.3.1 - luna-data-grid@1.3.0: - resolution: {integrity: sha512-lB6ym/F+iS1yQ2sBZL10yWS+IhivmfE9sFuPZO0WeUveBQkDUkEbfPnm8fMiVxl7qUP6khevRlBaR6qfn9veXQ==} + luna-data-grid@1.4.1: + resolution: {integrity: sha512-Blo7PP+86LBaiCie5hNeXxQgpodMQGD2ReczFvn2NXZhV6FVKLQC3TL2avSqCsFmIXon09w1zzJVhdh+fVhpCQ==} - luna-dom-viewer@1.4.0: - resolution: {integrity: sha512-T7nbFh0z/NmEMhyffp5BycG79eCAsD/8VGyCSzlMeGMjSMfQocPzeGk8miAedfPzGzmkrMseRfWpq+XEbI5Cng==} + luna-dom-viewer@1.8.2: + resolution: {integrity: sha512-37yiSYLBeu2TyHp1iQMVrYsAkH4X5Hkn0UYIaTlvTTEc6uSdu5aBI67zHnuXV2FVmOoa0kJhFK/GsUKsFibaCQ==} luna-object-viewer@0.3.1: resolution: {integrity: sha512-byynxixA8aAzSg9LymFDzPPrhKCPBOiELnOGxuztAXmes7W7OFqGkiLSyV8ECDvRimF1WewVmyOdxyhsLVquFg==} - magic-string@0.30.11: - resolution: {integrity: sha512-+Wri9p0QHMy+545hKww7YAu5NyzF8iomPL/RQazugQ9+Ez4Ic3mERMd8ZTX5rfK944j+560ZJi8iAwgak1Ac7A==} + magic-string@0.30.17: + resolution: {integrity: sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==} + + math-intrinsics@1.1.0: + resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} + engines: {node: '>= 0.4'} mdast-util-to-hast@13.2.0: resolution: {integrity: sha512-QGYKEuUsYT9ykKBCMOEDLsU5JRObWQusAolFMeko/tYPufNkRffBAQjIE+99jbA87xv6FgmjLtwjh9wBWajwAA==} @@ -4254,9 +4257,9 @@ snapshots: prelude-ls: 1.2.1 type-check: 0.4.0 - licia@1.46.0: {} + licia@1.48.0: {} - lilconfig@3.1.2: {} + lilconfig@3.1.3: {} lines-and-columns@1.2.4: {} @@ -4315,26 +4318,26 @@ snapshots: dependencies: yallist: 4.0.0 - luna-console@1.3.5(luna-data-grid@1.3.0)(luna-dom-viewer@1.4.0)(luna-object-viewer@0.3.1): + luna-console@1.3.5(luna-data-grid@1.4.1)(luna-dom-viewer@1.8.2)(luna-object-viewer@0.3.1): dependencies: - licia: 1.46.0 - luna-data-grid: 1.3.0 - luna-dom-viewer: 1.4.0 + licia: 1.48.0 + luna-data-grid: 1.4.1 + luna-dom-viewer: 1.8.2 luna-object-viewer: 0.3.1 - luna-data-grid@1.3.0: + luna-data-grid@1.4.1: dependencies: - licia: 1.46.0 + licia: 1.48.0 - luna-dom-viewer@1.4.0: + luna-dom-viewer@1.8.2: dependencies: - licia: 1.46.0 + licia: 1.48.0 luna-object-viewer@0.3.1: dependencies: - licia: 1.46.0 + licia: 1.48.0 - magic-string@0.30.11: + magic-string@0.30.17: dependencies: '@jridgewell/sourcemap-codec': 1.5.0 diff --git a/src/Repl.vue b/src/Repl.vue index b6b8bee1..2aa68276 100644 --- a/src/Repl.vue +++ b/src/Repl.vue @@ -25,6 +25,7 @@ export interface Props { showCompileOutput?: boolean showImportMap?: boolean showTsConfig?: boolean + showConsole?: boolean clearConsole?: boolean layout?: 'horizontal' | 'vertical' layoutReverse?: boolean @@ -132,8 +133,9 @@ defineExpose({ reload }) margin: 0; overflow: hidden; font-size: 13px; - font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, - Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif; + font-family: + -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, + Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif; background-color: var(--bg-soft); } diff --git a/src/output/Preview.vue b/src/output/Preview.vue index 20c6f37d..c9fc19e1 100644 --- a/src/output/Preview.vue +++ b/src/output/Preview.vue @@ -5,8 +5,14 @@ import Sandbox from './Sandbox.vue' const props = defineProps<{ show: boolean; ssr: boolean }>() -const { store, clearConsole, theme, previewTheme, previewOptions } = - inject(injectKeyProps)! +const { + store, + clearConsole, + showConsole, + theme, + previewTheme, + previewOptions, +} = inject(injectKeyProps)! const sandboxTheme = computed(() => previewTheme.value ? theme.value : undefined, @@ -29,6 +35,7 @@ defineExpose({ :theme="sandboxTheme" :preview-options="previewOptions" :ssr="props.ssr" + :show-console="showConsole" :clear-console="clearConsole" /> diff --git a/src/output/Sandbox.vue b/src/output/Sandbox.vue index eba9c688..e6add4e0 100644 --- a/src/output/Sandbox.vue +++ b/src/output/Sandbox.vue @@ -11,17 +11,21 @@ import { watch, watchEffect, } from 'vue' +import LunaConsole from 'luna-console' import srcdoc from './srcdoc.html?raw' import { PreviewProxy } from './PreviewProxy' +import SplitPane from '../SplitPane.vue' import { compileModulesForPreview } from './moduleCompiler' -import type { Store } from '../store' import { injectKeyProps } from '../types' +import type { Store } from '../store' + export interface SandboxProps { store: Store show?: boolean ssr?: boolean clearConsole?: boolean + showConsole?: boolean theme?: 'dark' | 'light' previewOptions?: { headHTML?: string @@ -42,6 +46,7 @@ const props = withDefaults(defineProps(), { show: true, ssr: false, theme: 'light', + showConsole: false, clearConsole: true, previewOptions: () => ({}), autoStoreInit: true, @@ -54,15 +59,26 @@ if (keyProps === undefined && props.autoStoreInit) { } const containerRef = useTemplateRef('container') +const consoleContainerRef = useTemplateRef('console-container') const runtimeError = ref() const runtimeWarning = ref() let sandbox: HTMLIFrameElement +let lunaConsole: LunaConsole let proxy: PreviewProxy let stopUpdateWatcher: WatchStopHandle | undefined // create sandbox on mount -onMounted(createSandbox) +onMounted(() => { + createSandbox() + if (!consoleContainerRef.value) return + if (props.showConsole) { + lunaConsole = new LunaConsole(consoleContainerRef.value, { + theme: keyProps?.theme.value || 'light', + }) + watch(() => store.value.activeFile.code, clearLunaConsole) + } +}) // reset sandbox when import map changes watch( @@ -157,15 +173,13 @@ function createSandbox() { runtimeError.value = 'Uncaught (in promise): ' + error.message }, on_console: (log: any) => { - if (log.duplicate) { - return - } if (log.level === 'error') { if (log.args[0] instanceof Error) { runtimeError.value = log.args[0].message } else { runtimeError.value = log.args[0] } + lunaConsole.error(...log.args) } else if (log.level === 'warn') { if (log.args[0].toString().includes('[Vue warn]')) { runtimeWarning.value = log.args @@ -173,16 +187,19 @@ function createSandbox() { .replace(/\[Vue warn\]:/, '') .trim() } + lunaConsole.warn(...log.args) + } else { + lunaConsole.log(...log.args) } }, on_console_group: (action: any) => { - // group_logs(action.label, false); + lunaConsole.group(action.label) }, on_console_group_end: () => { - // ungroup_logs(); + lunaConsole.groupEnd() }, on_console_group_collapsed: (action: any) => { - // group_logs(action.label, true); + lunaConsole.groupCollapsed(action.label) }, }) @@ -301,18 +318,33 @@ async function updatePreview() { } } +function clearLunaConsole() { + lunaConsole?.clear(true) +} + /** * Reload the preview iframe */ function reload() { sandbox.contentWindow?.location.reload() + clearLunaConsole() } defineExpose({ reload, container: containerRef })