From a629383b3244325f4caeae7437fe31a92daa2b47 Mon Sep 17 00:00:00 2001 From: OrbisK Date: Mon, 13 Oct 2025 13:27:39 +0200 Subject: [PATCH] feat: add `store.customData` to (de)serialize custom data --- src/Repl.vue | 5 +++-- src/import-map.ts | 2 +- src/index.ts | 1 + src/output/Output.vue | 4 +++- src/output/Sandbox.vue | 2 +- src/output/srcdoc.html | 5 +++-- src/sourcemap.ts | 3 +-- src/store.ts | 9 +++++++++ src/transform.ts | 12 ++++++++++-- 9 files changed, 32 insertions(+), 11 deletions(-) diff --git a/src/Repl.vue b/src/Repl.vue index a290c968..afffd463 100644 --- a/src/Repl.vue +++ b/src/Repl.vue @@ -133,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/import-map.ts b/src/import-map.ts index 328cb40b..b390fff5 100644 --- a/src/import-map.ts +++ b/src/import-map.ts @@ -4,7 +4,7 @@ export function getVersions(version: string): number[] { return version.split('.').map((v) => parseInt(v, 10)) } -export function isVaporSupported(version: string): boolean{ +export function isVaporSupported(version: string): boolean { const [major, minor] = getVersions(version) // vapor mode is supported in v3.6+ return major > 3 || (major === 3 && minor >= 6) diff --git a/src/index.ts b/src/index.ts index b055c6e6..1917ecae 100644 --- a/src/index.ts +++ b/src/index.ts @@ -2,4 +2,5 @@ export { default as Repl, type Props as ReplProps } from './Repl.vue' export { default as Preview } from './output/Preview.vue' export { default as Sandbox, type SandboxProps } from './output/Sandbox.vue' export type { OutputModes } from './types' +export { utoa, atou } from './utils' export * from './core' diff --git a/src/output/Output.vue b/src/output/Output.vue index 13d6feb1..06b19cee 100644 --- a/src/output/Output.vue +++ b/src/output/Output.vue @@ -41,7 +41,9 @@ watchEffect(() => { }) const showSourceMap = computed(() => { - return props.showOpenSourceMap && (mode.value === 'js' || mode.value === 'ssr') + return ( + props.showOpenSourceMap && (mode.value === 'js' || mode.value === 'ssr') + ) }) function openSourceMap() { diff --git a/src/output/Sandbox.vue b/src/output/Sandbox.vue index c62f480c..728fda4d 100644 --- a/src/output/Sandbox.vue +++ b/src/output/Sandbox.vue @@ -214,7 +214,7 @@ async function updatePreview() { } const vaporSupported = isVaporSupported( - store.value.vueVersion || store.value.compiler?.version + store.value.vueVersion || store.value.compiler?.version, ) try { diff --git a/src/output/srcdoc.html b/src/output/srcdoc.html index 75fa51b3..57f137ca 100644 --- a/src/output/srcdoc.html +++ b/src/output/srcdoc.html @@ -6,8 +6,9 @@ color-scheme: dark; } body { - 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; } diff --git a/src/sourcemap.ts b/src/sourcemap.ts index 3ecdf477..79e09127 100644 --- a/src/sourcemap.ts +++ b/src/sourcemap.ts @@ -39,8 +39,7 @@ export function getSourceMap( // same above templateMap as Omit as TraceEncodedSourceMap, ) - const offset = - (trimAnalyzedBindings(scriptCode).match(/\r?\n/g)?.length ?? 0) + const offset = trimAnalyzedBindings(scriptCode).match(/\r?\n/g)?.length ?? 0 eachMapping(tracer, (m) => { if (m.source == null) return addMapping(gen, { diff --git a/src/store.ts b/src/store.ts index 3af17d4e..4a8adc64 100644 --- a/src/store.ts +++ b/src/store.ts @@ -48,6 +48,8 @@ export function useStore( typescriptVersion = ref('latest'), dependencyVersion = ref(Object.create(null)), reloadLanguageTools = ref(), + + customData = ref({}), }: Partial = {}, serializedState?: string, ): ReplStore { @@ -273,6 +275,9 @@ export function useStore( if (typescriptVersion.value !== 'latest' || files._tsVersion) { files._tsVersion = typescriptVersion.value } + if (customData.value && Object.keys(customData.value).length) { + files.__metadata = JSON.stringify(customData.value) + } return '#' + utoa(JSON.stringify(files)) } const deserialize: ReplStore['deserialize'] = ( @@ -294,6 +299,8 @@ export function useStore( vueVersion.value = saved[filename] } else if (filename === '_tsVersion') { typescriptVersion.value = saved[filename] + } else if (filename === '__metadata') { + customData.value = JSON.parse(saved[filename]) } else { setFile(files.value, filename, saved[filename]) } @@ -372,6 +379,7 @@ export function useStore( compiler, loading, vueVersion, + customData, locale, typescriptVersion, @@ -438,6 +446,7 @@ export type StoreState = ToRefs<{ compiler: typeof defaultCompiler /* only apply for compiler-sfc */ vueVersion: string | null + customData: Record // volar-related locale: string | undefined diff --git a/src/transform.ts b/src/transform.ts index d1ec2b19..9d383202 100644 --- a/src/transform.ts +++ b/src/transform.ts @@ -137,7 +137,15 @@ export async function compileFile( let clientScript: string let bindings: BindingMetadata | undefined try { - const res = await doCompileScript(store, descriptor, id, false, isTS, isJSX, isCE) + const res = await doCompileScript( + store, + descriptor, + id, + false, + isTS, + isJSX, + isCE, + ) clientScript = res.code bindings = res.bindings clientScriptMap = res.map @@ -159,7 +167,7 @@ export async function compileFile( true, isTS, isJSX, - isCE + isCE, ) ssrScript = ssrScriptResult.code ssrCode += ssrScript