Skip to content

Commit

Permalink
feat: add loading state, swc gui
Browse files Browse the repository at this point in the history
  • Loading branch information
sxzz committed May 15, 2024
1 parent 1218363 commit a7e6ceb
Show file tree
Hide file tree
Showing 9 changed files with 169 additions and 50 deletions.
29 changes: 19 additions & 10 deletions app.vue
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,28 @@ const language = computed(() => {
</script>

<template>
<main flex="~ col" lg:h-screen>
<NavBar mb-1 />
<Suspense>
<main flex="~ col" lg:h-screen>
<NavBar mb-1 />

<div min-h-0 flex flex-1 flex-col gap2 lg:flex-row>
<SideBar v-show="showSideBar" overflow-auto lg:w-75 lg:flex-none />
<div min-h-0 flex flex-1 flex-col gap2 lg:flex-row>
<SideBar v-show="showSideBar" overflow-auto lg:w-75 lg:flex-none />

<div min-h-95vh min-w-0 flex flex-col gap2 p2 lg:flex-1 lg:flex-row>
<div v-show="showLeftLayout" min-w-0 flex-1>
<CodeEditor v-model="code" :language="language" h-full w-full />
<div min-h-95vh min-w-0 flex flex-col gap2 p2 lg:flex-1 lg:flex-row>
<div v-show="showLeftLayout" min-w-0 flex-1>
<CodeEditor v-model="code" :language="language" h-full w-full />
</div>

<AstViewer v-show="showRightLayout" min-w-0 flex-1 />
</div>
</div>
</main>

<AstViewer v-show="showRightLayout" min-w-0 flex-1 />
<template #fallback>
<div h-screen flex items-center justify-center gap1 text-3xl font-bold>
<div i-ri:loader-4-fill animate-spin />
Loading...
</div>
</div>
</main>
</template>
</Suspense>
</template>
13 changes: 12 additions & 1 deletion composables/language/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,18 @@ export const currentParser = computed(

export const currentParserGui = computed(
() =>
currentParser.value.gui && defineAsyncComponent(currentParser.value.gui),
currentParser.value.gui &&
defineAsyncComponent({
loader: currentParser.value.gui,
// @unocss-include
loadingComponent: () =>
h('div', { class: 'flex justify-center items-center gap1' }, [
h('div', { class: 'i-ri:loader-4-fill animate-spin' }),
'Loading...',
]),
suspensible: false,
delay: 200,
}),
)

export const overrideVersion = ref<string>()
Expand Down
35 changes: 32 additions & 3 deletions composables/language/javascript/BabelGui.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,36 @@
<script setup lang="ts">
import { useOption, usePlugin } from './babel'
import type { ParserOptions } from '@babel/parser'
<script lang="ts">
import type { ParserOptions, ParserPlugin } from '@babel/parser'
const useOption = makeUseOption<ParserOptions>()
function usePlugin(name: ParserPlugin, deps: Ref<boolean | undefined>[] = []) {
const value = useOptions(
(opt: ParserOptions) => !!opt.plugins?.includes?.(name),
(value, opt) => {
if (!Array.isArray(opt.plugins)) opt.plugins = []
if (value) {
deps.forEach((dep) => !dep.value && (dep.value = true))
opt.plugins.push(name)
} else {
opt.plugins = del(opt.plugins, [name])
}
},
)
watch(
() => deps.map((dep) => dep.value),
(deps) => {
if (value.value && deps.some((dep) => !dep)) {
value.value = false
}
},
)
return value
}
</script>

<script setup lang="ts">
// options
const allowImportExportEverywhere = useOption('allowImportExportEverywhere')
const allowAwaitOutsideFunction = useOption('allowAwaitOutsideFunction')
Expand Down
7 changes: 5 additions & 2 deletions composables/language/javascript/OxcGui.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
<script setup lang="ts">
import { useOption } from './oxc'
<script lang="ts">
import type { ParserOptions } from '@oxc-parser/wasm'
const useOption = makeUseOption<ParserOptions>()
</script>

<script setup lang="ts">
const sourceType = useOption('sourceType', 'script', true)
const sourceFilename = useOption('sourceFilename', '', true)
</script>
Expand Down
97 changes: 97 additions & 0 deletions composables/language/javascript/SwcGui.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
<script lang="ts">
import type { ParserConfig } from '@swc/wasm-web'
const useOption = makeUseOption<ParserConfig>()
</script>

<script setup lang="ts">
const language = useOption('syntax', 'ecmascript', true)
const jsx = useOption('jsx')
const tsx = useOption('tsx')
const decorators = useOption('decorators')
const decoratorsBeforeExport = useOption('decoratorsBeforeExport')
const functionBind = useOption('functionBind')
const importAssertions = useOption('importAssertions')
const dynamicImport = useOption('dynamicImport')
const exportDefaultFrom = useOption('exportDefaultFrom')
watch(language, (language) => {
if (language === 'ecmascript') {
jsx.value = tsx.value
tsx.value = dynamicImport.value = false
} else {
tsx.value = jsx.value
jsx.value =
decoratorsBeforeExport.value =
functionBind.value =
importAssertions.value =
exportDefaultFrom.value =
false
}
})
</script>

<template>
<div flex="~ col gap4" text-sm font-mono>
<label>
<span>Language</span>
<select v-model="language" p1>
<option value="ecmascript">JavaScript</option>
<option value="typescript">TypeScript</option>
</select>
</label>

<label>
<input
v-if="language === 'ecmascript'"
v-model="jsx"
type="checkbox"
switch
/>
<input v-else v-model="tsx" type="checkbox" switch />
<span>{{ language === 'ecmascript' ? 'JSX' : 'TSX' }}</span>
</label>

<label>
<input v-model="decorators" type="checkbox" switch />
<span>decorators</span>
</label>

<template v-if="language === 'ecmascript'">
<label ml6>
<input v-model="decoratorsBeforeExport" type="checkbox" switch />
<span>beforeExport</span>
</label>

<label>
<input v-model="functionBind" type="checkbox" switch />
<span>functionBind</span>
</label>

<label>
<input v-model="importAssertions" type="checkbox" switch />
<span>importAssertions</span>
</label>

<label>
<input v-model="exportDefaultFrom" type="checkbox" switch />
<span>exportDefaultFrom</span>
</label>
</template>

<template v-else>
<label>
<input v-model="dynamicImport" type="checkbox" switch />
<span>dynamicImport</span>
</label>
</template>
</div>
</template>

<style scoped>
label {
--at-apply: 'flex gap-2 items-center';
}
label span {
--at-apply: 'op85';
}
</style>
31 changes: 0 additions & 31 deletions composables/language/javascript/babel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,34 +36,3 @@ export const babel: Parser<typeof Babel, Babel.ParserOptions> = {
getAstLocation: getAstLocationBabel,
gui: () => import('./BabelGui.vue'),
}

export const useOption = makeUseOption<Babel.ParserOptions>()
export function usePlugin(
name: Babel.ParserPlugin,
deps: Ref<boolean | undefined>[] = [],
) {
const value = useOptions(
(opt: Babel.ParserOptions) => !!opt.plugins?.includes?.(name),
(value, opt) => {
if (!Array.isArray(opt.plugins)) opt.plugins = []

if (value) {
deps.forEach((dep) => !dep.value && (dep.value = true))
opt.plugins.push(name)
} else {
opt.plugins = del(opt.plugins, [name])
}
},
)

watch(
() => deps.map((dep) => dep.value),
(deps) => {
if (value.value && deps.some((dep) => !dep)) {
value.value = false
}
},
)

return value
}
2 changes: 0 additions & 2 deletions composables/language/javascript/oxc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,5 +34,3 @@ export const oxc: Parser<typeof Oxc, Partial<Oxc.ParserOptions>> = {
getAstLocation: getAstLocationBabel,
gui: () => import('./OxcGui.vue'),
}

export const useOption = makeUseOption<Oxc.ParserOptions>()
1 change: 1 addition & 0 deletions composables/language/javascript/swc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,4 +61,5 @@ export const swc: Parser<typeof Swc, Swc.ParseOptions> = {
return options?.syntax === 'typescript' ? 'typescript' : 'javascript'
},
getAstLocation: getAstLocation('swc'),
gui: () => import('./SwcGui.vue'),
}
4 changes: 3 additions & 1 deletion composables/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,10 @@ export function useOptions<O extends object, T>(
})
}

type KeysOfUnion<T> = T extends T ? keyof T : never

export function makeUseOption<O extends object>() {
return <K extends keyof O>(
return <K extends KeysOfUnion<O>>(
key: K,
defaultValue: O[K] = false as any,
keep?: boolean,
Expand Down

0 comments on commit a7e6ceb

Please sign in to comment.